import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/errors/error_handler.dart';
import '../../../../core/network/dio_client.dart';
import '../../data/datasources/settings_datasource.dart';
import '../../data/datasources/settings_remote_datasource.dart';
import '../../data/repositories/settings_repository_impl.dart';
import '../../domain/entities/app_settings.dart';
import '../../domain/repositories/settings_repository.dart';

// ---------------------------------------------------------------------------
// Dependency providers
// ---------------------------------------------------------------------------

final _sharedPreferencesProvider = FutureProvider<SharedPreferences>((ref) {
  return SharedPreferences.getInstance();
});

final settingsDatasourceProvider = Provider<SettingsDatasource?>((ref) {
  final prefsAsync = ref.watch(_sharedPreferencesProvider);
  return prefsAsync.whenOrNull(
    data: (prefs) => SettingsDatasource(prefs),
  );
});

final settingsRepositoryProvider = Provider<SettingsRepository?>((ref) {
  final datasource = ref.watch(settingsDatasourceProvider);
  if (datasource == null) return null;
  return SettingsRepositoryImpl(datasource);
});

final settingsRemoteDatasourceProvider =
    Provider<SettingsRemoteDatasource>((ref) {
  final dio = ref.watch(dioClientProvider);
  return SettingsRemoteDatasource(dio);
});

// ---------------------------------------------------------------------------
// Account profile state
// ---------------------------------------------------------------------------

class AccountProfile {
  final String displayName;
  final String email;
  final bool isLoading;
  final String? error;

  const AccountProfile({
    this.displayName = '',
    this.email = '',
    this.isLoading = false,
    this.error,
  });

  AccountProfile copyWith({
    String? displayName,
    String? email,
    bool? isLoading,
    String? error,
  }) {
    return AccountProfile(
      displayName: displayName ?? this.displayName,
      email: email ?? this.email,
      isLoading: isLoading ?? this.isLoading,
      error: error,
    );
  }
}

// ---------------------------------------------------------------------------
// Settings state notifier
// ---------------------------------------------------------------------------

class SettingsNotifier extends StateNotifier<AppSettings> {
  final SettingsRepository? _repository;

  SettingsNotifier(this._repository) : super(const AppSettings()) {
    _loadSettings();
  }

  Future<void> _loadSettings() async {
    if (_repository == null) return;
    try {
      final settings = await _repository.loadSettings();
      state = settings;
    } catch (_) {
      // Use defaults on error
    }
  }

  Future<void> setThemeMode(ThemeMode mode) async {
    state = state.copyWith(themeMode: mode);
    await _repository?.saveSettings(state);
  }

  Future<void> setNotificationsEnabled(bool enabled) async {
    state = state.copyWith(notificationsEnabled: enabled);
    await _repository?.saveSettings(state);
  }

  Future<void> setSoundEnabled(bool enabled) async {
    state = state.copyWith(soundEnabled: enabled);
    await _repository?.saveSettings(state);
  }

  Future<void> setHapticFeedback(bool enabled) async {
    state = state.copyWith(hapticFeedback: enabled);
    await _repository?.saveSettings(state);
  }

  Future<void> setTenant(String? id, String? name) async {
    state = state.copyWith(selectedTenantId: id, selectedTenantName: name);
    await _repository?.saveSettings(state);
  }

  Future<void> setLanguage(String language) async {
    state = state.copyWith(language: language);
    await _repository?.saveSettings(state);
  }

  Future<void> setBiometricEnabled(bool enabled) async {
    state = state.copyWith(biometricEnabled: enabled);
    await _repository?.saveSettings(state);
  }

  Future<void> setTtsVoice(String voice) async {
    state = state.copyWith(ttsVoice: voice);
    await _repository?.saveSettings(state);
  }

  Future<void> setTtsStyle(String style) async {
    state = state.copyWith(ttsStyle: style);
    await _repository?.saveSettings(state);
  }

  Future<void> setEngineType(String type) async {
    state = state.copyWith(engineType: type);
    await _repository?.saveSettings(state);
  }

  Future<void> resetToDefaults() async {
    await _repository?.resetSettings();
    state = const AppSettings();
  }
}

// ---------------------------------------------------------------------------
// Account profile notifier
// ---------------------------------------------------------------------------

class AccountProfileNotifier extends StateNotifier<AccountProfile> {
  final SettingsRemoteDatasource _remote;

  AccountProfileNotifier(this._remote) : super(const AccountProfile());

  Future<void> loadProfile() async {
    state = state.copyWith(isLoading: true, error: null);
    try {
      final data = await _remote.getAccount();
      state = state.copyWith(
        displayName: data['displayName'] as String? ?? '',
        email: data['email'] as String? ?? '',
        isLoading: false,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false, error: ErrorHandler.friendlyMessage(e));
    }
  }

  Future<bool> updateDisplayName(String name) async {
    state = state.copyWith(isLoading: true, error: null);
    try {
      final data = await _remote.updateAccount(name);
      state = state.copyWith(
        displayName: data['displayName'] as String? ?? name,
        isLoading: false,
      );
      return true;
    } catch (e) {
      state = state.copyWith(isLoading: false, error: ErrorHandler.friendlyMessage(e));
      return false;
    }
  }

  Future<({bool success, String? message})> changePassword({
    required String currentPassword,
    required String newPassword,
  }) async {
    try {
      final data = await _remote.changePassword(
        currentPassword: currentPassword,
        newPassword: newPassword,
      );
      final success = data['success'] as bool? ?? false;
      final message = data['message'] as String?;
      return (success: success, message: message);
    } catch (e) {
      return (success: false, message: ErrorHandler.friendlyMessage(e));
    }
  }
}

// ---------------------------------------------------------------------------
// Main providers
// ---------------------------------------------------------------------------

final settingsProvider =
    StateNotifierProvider<SettingsNotifier, AppSettings>((ref) {
  final repository = ref.watch(settingsRepositoryProvider);
  return SettingsNotifier(repository);
});

final accountProfileProvider =
    StateNotifierProvider<AccountProfileNotifier, AccountProfile>((ref) {
  final remote = ref.watch(settingsRemoteDatasourceProvider);
  return AccountProfileNotifier(remote);
});

final themeModeProvider = Provider<ThemeMode>((ref) {
  return ref.watch(settingsProvider).themeMode;
});

final notificationsEnabledProvider = Provider<bool>((ref) {
  return ref.watch(settingsProvider).notificationsEnabled;
});

/// Returns null when language is '' (auto/system), letting Flutter pick the device locale.
final localeProvider = Provider<Locale?>((ref) {
  final lang = ref.watch(settingsProvider).language;
  return switch (lang) {
    'zh_TW' => const Locale('zh', 'TW'),
    'zh'    => const Locale('zh'),
    'en'    => const Locale('en'),
    _       => null, // '' or anything else → follow device locale
  };
});
