import 'dart:convert';

import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

import 'package:together_mobile/database/box_type.dart';
import 'package:together_mobile/models/init_get_it.dart';
import 'package:together_mobile/models/user_model.dart';
import 'package:together_mobile/utils/app_dir.dart';

void initDatabase() async {
  List<int> encryptionKeyUint8List = await getEncryptKey();

  await Hive.initFlutter(await getBoxDir());

  Box<ChatSetting> chatSettingBox =
      await Hive.openBox<ChatSetting>('chat_setting');

  final openedChats = chatSettingBox.values.where((element) => element.isOpen);

  for (var chatBox in openedChats) {
    Hive.openBox<MessageT>(
      'message_${chatBox.contactId}',
      encryptionCipher: HiveAesCipher(encryptionKeyUint8List),
      compactionStrategy: (entries, deletedEntries) => entries > 200,
    );
  }
}

void registerAdapter() {
  Hive.registerAdapter(ChatSettingAdapter());
  Hive.registerAdapter(MessageTAdapter());
}

Future<List<int>> getEncryptKey() async {
  final id = getIt.get<UserAccount>().id;
  const secureStorage = FlutterSecureStorage();
  final encryptionKeyString = await secureStorage.read(key: 'encryptKey:$id');
  if (encryptionKeyString == null) {
    final key = Hive.generateSecureKey();
    await secureStorage.write(
      key: 'encryptKey:$id',
      value: base64Encode(key),
    );
  }
  // String? key = await secureStorage.read(key: 'encryptKey:$id');
  final encryptionKeyUint8List = base64Url.decode(encryptionKeyString!);

  return encryptionKeyUint8List;
}

Future<void> openNewMessageBox(String contactId, int type) async {
  final encryptionKeyUint8List = await getEncryptKey();

  var chatSettingBox = Hive.box<ChatSetting>('chat_setting');
  chatSettingBox.add(
      ChatSetting(contactId, type, false, false, false, DateTime.now(), 0));

  await Hive.openBox<MessageT>(
    'message_$contactId',
    encryptionCipher: HiveAesCipher(encryptionKeyUint8List),
    compactionStrategy: (entries, deletedEntries) => entries > 200,
  );
}