import 'dart:convert';

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:injectable/injectable.dart';
import 'package:moonwell_launcher/features/launcher/domain/entities/launcher_session.dart';
import 'package:moonwell_launcher/features/preferences/domain/repositories/preferences_repository.dart';
import 'package:shared_preferences/shared_preferences.dart';

const _outputDirKey = 'output_dir';
const _launcherSessionKey = 'launcher_session';

@LazySingleton(as: PreferencesRepository, env: ['flutter'])
class LocalPreferencesRepository implements PreferencesRepository {
  final SharedPreferences _preferences;
  final FlutterSecureStorage _secureStorage;

  const LocalPreferencesRepository({
    required SharedPreferences preferences,
    required FlutterSecureStorage secureStorage,
  }) : _preferences = preferences,
       _secureStorage = secureStorage;

  @override
  Future<Uri?> getOutputDir() {
    final rawPath = _preferences.getString(_outputDirKey);

    if (rawPath == null) {
      return Future.value(null);
    }

    return Future.value(Uri.parse(rawPath));
  }

  @override
  Future<void> setOutputDir(Uri uri) {
    return _preferences.setString(_outputDirKey, uri.toString());
  }

  @override
  Future<LauncherSession?> getLauncherSession() async {
    await _maybeClearLegacyLauncherSession();

    final rawSession = await _secureStorage.read(key: _launcherSessionKey);
    if (rawSession == null || rawSession.isEmpty) {
      return null;
    }

    try {
      final decoded = jsonDecode(rawSession);
      if (decoded is! Map) {
        return null;
      }

      final json = decoded.map((key, value) => MapEntry(key.toString(), value));
      return LauncherSession.fromJson(json);
    } catch (_) {
      return null;
    }
  }

  @override
  Future<void> setLauncherSession(LauncherSession session) async {
    await _secureStorage.write(
      key: _launcherSessionKey,
      value: jsonEncode(session.toJson()),
    );
    await _maybeClearLegacyLauncherSession();
  }

  @override
  Future<void> clearLauncherSession() async {
    await _secureStorage.delete(key: _launcherSessionKey);
    await _maybeClearLegacyLauncherSession();
  }

  Future<void> _maybeClearLegacyLauncherSession() async {
    if (_preferences.containsKey(_launcherSessionKey)) {
      await _preferences.remove(_launcherSessionKey);
    }
  }
}
