import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:get/get.dart';
import 'package:encrypt_shared_preferences/provider.dart';

const Map<String, Locale> supportedLocales = {
  'en_US': Locale('en', 'US'),
  'de_DE': Locale('de', 'DE'),
  'fr_FR': Locale('fr', 'FR'),
  'nl_NL': Locale('nl', 'NL'),
};

class MyTranslations extends Translations {
  static final MyTranslations instance = MyTranslations._internal();
  MyTranslations._internal();

  static final Map<String, Map<String, String>> _translations = {};

  static Future<void> loadTranslations() async {
    for (final localeKey in supportedLocales.keys) {
      try {
        final String jsonString = await rootBundle.loadString(
          'assets/i18n/$localeKey.json',
        );
        final Map<String, dynamic> jsonMap = json.decode(jsonString);
        _translations[localeKey] = jsonMap.map(
          (key, value) => MapEntry(key, value.toString()),
        );
      } catch (e) {
        debugPrint('Konnte Übersetzung für $localeKey nicht laden: $e');
      }
    }
  }

  @override
  Map<String, Map<String, String>> get keys => _translations;
}

class LocalizationController extends GetxController {
  final EncryptedSharedPreferencesAsync storage =
      EncryptedSharedPreferencesAsync.getInstance();
  Rx<Locale> currentLocale = supportedLocales['en_US']!.obs;

  @override
  void onInit() {
    super.onInit();
    loadLocale();
  }

  Future<void> loadLocale() async {
    String? savedLocaleKey = await storage.getString(
      'locale',
      defaultValue: 'en_US',
    );

    final Locale locale =
        supportedLocales[savedLocaleKey ?? 'en_US'] ??
        supportedLocales['en_US']!;

    currentLocale.value = locale;
    Get.locale = locale;
  }

  Future<void> changeLocale(Locale newLocale) async {
    final String localeKey = supportedLocales.entries
        .firstWhere(
          (entry) => entry.value == newLocale,
          orElse: () => supportedLocales.entries.first,
        )
        .key;

    currentLocale.value = newLocale;
    Get.updateLocale(newLocale);
    await storage.setString('locale', localeKey);
  }
}
