// Dart imports:
import 'dart:async';

// Flutter imports:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hive_ce/hive.dart';

import 'package:injectable/injectable.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/components/notifiers/app_settings.dart';
import 'package:remever/components/notifiers/home_screen_data.dart';
import 'package:remever/helpers/hive_creator.dart';
import 'package:remever/i18n/strings.g.dart';
import 'package:remever/interfaces/warmup_service.dart';
import 'package:remever/models/adapters/app_locale_adapter.dart';
import 'package:remever/models/adapters/theme_mode_adapter.dart';

import '../inject.dart';
import 'core/enc_keys_service.dart';
import 'core/lang_service.dart';
import 'core/theme_service.dart';

///
/// Сервис прогрева приложения
///
@Singleton()
class WarmupService {
  WarmupService(this._themeService, this._langService, this._encKeysService);

  /// Сервисы
  final ThemeService _themeService;
  final LangService _langService;
  final EncKeysService _encKeysService;

  /// [Completer] для прогрева приложения
  final Completer<bool> _firstStartCompleter = Completer<bool>();
  Completer<bool> get firstStartCompleter => _firstStartCompleter;

  @PostConstruct(preResolve: true)
  Future<void> common() async {
    await _registerHiveAdapters();
    await _openHiveBoxes();
    await _registerNotifiers();
  }

  ///
  /// Инициализация для запуска приложения
  ///
  Future<void> firstStart() async {
    await _setStoragesValue();
  }

  ///
  /// Проставнока изначальных значений хранилищ
  ///
  Future<void> _setStoragesValue() async {
    final List<IWarmupService> services = <IWarmupService>[
      _themeService,
      _langService,
    ];

    for (final IWarmupService service in services) {
      await service.init();
    }
  }

  ///
  /// Регистрация [Hive] адаптеров
  ///
  Future<void> _registerHiveAdapters() async {
    Hive.registerAdapter<ThemeMode>(ThemeModeAdapter());
    Hive.registerAdapter<AppLocale>(AppLocaleAdapter());
  }

  ///
  /// Открытие [Hive] хранилищ
  ///
  Future<void> _openHiveBoxes() async {
    final Map<String, HiveCreator<dynamic>> storageNames =
        <String, HiveCreator<dynamic>>{
          Storage.storageAuth: HiveCreator<String>(),
          Storage.hiveThemeMode: HiveCreator<ThemeMode>(),
          Storage.hiveLang: HiveCreator<AppLocale>(),
        };

    for (MapEntry<String, HiveCreator<dynamic>> storage
        in storageNames.entries) {
      final String name = storage.key;
      final Uint8List key = await _encKeysService.getKey(name);

      await storage.value.open(name, HiveAesCipher(key));
    }
  }

  ///
  /// Регистрация нотификаторов
  ///
  Future<void> _registerNotifiers() async {
    getIt.registerLazySingleton<AppSettingsNotifier>(
      () => AppSettingsNotifier(debugMode: kDebugMode),
    );

    getIt.registerLazySingleton<CollectionData>(() => CollectionData());
  }
}
