import 'package:color_blindness/color_blindness.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../utils/theme_mode_extensions.dart';

class SettingsService extends ChangeNotifier {
  late final SharedPreferences _prefs;
  var _initialized = false;

  SettingsService();

  var _lowBandwidthMode = false;

  bool get lowBandwidthMode => _lowBandwidthMode;

  set lowBandwidthMode(bool value) {
    _lowBandwidthMode = value;
    _prefs.setBool(_lowBandwidthModeKey, _lowBandwidthMode);
    notifyListeners();
  }

  var _themeMode = ThemeMode.system;

  ThemeMode get themeMode => _themeMode;

  set themeMode(ThemeMode mode) {
    _themeMode = mode;
    _prefs.setString(_themeModeKey, _themeMode.name);
    notifyListeners();
  }

  ColorBlindnessType _colorBlindnessType = ColorBlindnessType.none;

  ColorBlindnessType get colorBlindnessType => _colorBlindnessType;

  set colorBlindnessType(ColorBlindnessType type) {
    _colorBlindnessType = type;
    _prefs.setString(_colorBlindnessTestingModeKey, type.name);
    notifyListeners();
  }

  Level _logLevel = Level.SEVERE;

  Level get logLevel => _logLevel;

  set logLevel(Level level) {
    _logLevel = level;
    _prefs.setString(_logLevelKey, level.name);
    notifyListeners();
  }

  Future<void> initialize() async {
    if (_initialized) {
      return;
    }
    _prefs = await SharedPreferences.getInstance();
    _lowBandwidthMode = _prefs.getBool(_lowBandwidthModeKey) ?? false;
    _themeMode = ThemeModeExtensions.parse(_prefs.getString(_themeModeKey));
    _colorBlindnessType = _colorBlindnessTypeFromPrefs(_prefs);
    _logLevel = _levelFromPrefs(_prefs);
    _initialized = true;
  }
}

const _lowBandwidthModeKey = 'LowBandwidthMode';
const _themeModeKey = 'ThemeMode';
const _colorBlindnessTestingModeKey = 'ColorBlindnessTestingMode';
const _logLevelKey = 'LogLevel';

ColorBlindnessType _colorBlindnessTypeFromPrefs(SharedPreferences prefs) {
  final cbString = prefs.getString(_colorBlindnessTestingModeKey);
  if (cbString?.isEmpty ?? true) {
    return ColorBlindnessType.none;
  }
  return ColorBlindnessType.values.firstWhere(
    (c) => c.name == cbString,
    orElse: () => ColorBlindnessType.none,
  );
}

Level _levelFromPrefs(SharedPreferences prefs) {
  final levelString = prefs.getString(_logLevelKey);
  return switch (levelString) {
    'ALL' => Level.ALL,
    'FINEST' => Level.FINEST,
    'FINER' => Level.FINER,
    'FINE' => Level.FINE,
    'CONFIG' => Level.CONFIG,
    'INFO' => Level.INFO,
    'WARNING' => Level.WARNING,
    'SEVERE' => Level.SEVERE,
    'SHOUT' => Level.SHOUT,
    'OFF' => Level.OFF,
    _ => Level.OFF,
  };
}
