import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:on_field_work/helpers/services/json_decoder.dart';
import 'package:on_field_work/helpers/services/localizations/language.dart';
import 'package:on_field_work/helpers/services/localizations/translator.dart';
import 'package:on_field_work/helpers/services/navigation_services.dart';
import 'package:on_field_work/helpers/theme/admin_theme.dart';
import 'package:on_field_work/helpers/theme/app_notifier.dart';
import 'package:on_field_work/helpers/theme/app_theme.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

typedef ThemeChangeCallback = void Function(
    ThemeCustomizer oldVal, ThemeCustomizer newVal);

class ThemeCustomizer {
  ThemeCustomizer();

  static final List<ThemeChangeCallback> _notifier = [];

  Language currentLanguage = Language.languages.first;

  ThemeMode theme = ThemeMode.light;
  ThemeMode leftBarTheme = ThemeMode.light;
  ThemeMode rightBarTheme = ThemeMode.light;
  ThemeMode topBarTheme = ThemeMode.light;
  ColorThemeType colorTheme = ColorThemeType.red;
  bool rightBarOpen = false;
  bool leftBarCondensed = false;

  static ThemeCustomizer instance = ThemeCustomizer();
  static ThemeCustomizer oldInstance = ThemeCustomizer();

  static Future<void> init() async {
    await initLanguage();
    await _loadColorTheme();
     _notify(); 
  }

  static initLanguage() async {
    await changeLanguage(ThemeCustomizer.instance.currentLanguage);
  }

  String toJSON() {
    return jsonEncode({'theme': theme.name, 'colorTheme': colorTheme.name});
  }

  static ThemeCustomizer fromJSON(String? json) {
    instance = ThemeCustomizer();
    if (json != null && json.trim().isNotEmpty) {
      JSONDecoder decoder = JSONDecoder(json);
      instance.theme =
          decoder.getEnum('theme', ThemeMode.values, ThemeMode.light);
      instance.colorTheme = decoder.getEnum(
          'colorTheme', ColorThemeType.values, ColorThemeType.red);
    }
    return instance;
  }

  static void addListener(ThemeChangeCallback callback) {
    _notifier.add(callback);
  }

  static void removeListener(ThemeChangeCallback callback) {
    _notifier.remove(callback);
  }

  static void _notify() {
    AdminTheme.setTheme();
    AppStyle.changeMyTheme();
    if (NavigationService.globalContext != null) {
      Provider.of<AppNotifier>(NavigationService.globalContext!, listen: false)
          .updateTheme(instance);
    }
    for (var value in _notifier) {
      value(oldInstance, instance);
    }
  }

  /// Public method to trigger theme updates externally
  static void applyThemeChange() {
    _notify();
  }

  static void notify() {
    for (var value in _notifier) {
      value(oldInstance, instance);
    }
  }

  static void setTheme(ThemeMode theme) {
    oldInstance = instance.clone();
    instance.theme = theme;
    instance.leftBarTheme = theme;
    instance.rightBarTheme = theme;
    instance.topBarTheme = theme;
    _notify();
  }

  static Future<void> changeLanguage(Language language) async {
    oldInstance = instance.clone();
    ThemeCustomizer.instance.currentLanguage = language;
    await Translator.changeLanguage(language);
  }

  static void openRightBar(bool opened) {
    instance.rightBarOpen = opened;
    _notify();
  }

  static void toggleLeftBarCondensed() {
    instance.leftBarCondensed = !instance.leftBarCondensed;
    _notify();
  }

  ThemeCustomizer clone() {
    var tc = ThemeCustomizer();
    tc.theme = theme;
    tc.rightBarTheme = rightBarTheme;
    tc.leftBarTheme = leftBarTheme;
    tc.topBarTheme = topBarTheme;
    tc.rightBarOpen = rightBarOpen;
    tc.leftBarCondensed = leftBarCondensed;
    tc.colorTheme = colorTheme;
    tc.currentLanguage = currentLanguage.clone();
    return tc;
  }

  @override
  String toString() {
    return 'ThemeCustomizer{theme: $theme, colorTheme: $colorTheme}';
  }

  // ---------------------------------------------------------------------------
  // 🟢 Color Theme Persistence
  // ---------------------------------------------------------------------------

  static const _colorThemeKey = 'color_theme_type';

  /// Save selected color theme
  static Future<void> saveColorTheme(ColorThemeType type) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_colorThemeKey, type.name);
    instance.colorTheme = type;
    _notify();
  }

  /// Load saved color theme (called at startup)
  static Future<void> _loadColorTheme() async {
    final prefs = await SharedPreferences.getInstance();
    final savedType = prefs.getString(_colorThemeKey);
    if (savedType != null) {
      instance.colorTheme = ColorThemeType.values.firstWhere(
        (e) => e.name == savedType,
        orElse: () => ColorThemeType.red,
      );
    }
  }

  /// Change color theme & persist
  static Future<void> changeColorTheme(ColorThemeType type) async {
    oldInstance = instance.clone();
    instance.colorTheme = type;
    await saveColorTheme(type);
  }
}
