import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'shared/settings_persistence.dart';

class RememberedAudioTrack {
  final int streamIndex;
  final String? language;
  final String? codec;
  final int? channels;
  final String? displayTitle;
  final DateTime updatedAt;

  const RememberedAudioTrack({
    required this.streamIndex,
    this.language,
    this.codec,
    this.channels,
    this.displayTitle,
    required this.updatedAt,
  });

  Map<String, dynamic> toJson() => {
    'streamIndex': streamIndex,
    if (language != null) 'language': language,
    if (codec != null) 'codec': codec,
    if (channels != null) 'channels': channels,
    if (displayTitle != null) 'displayTitle': displayTitle,
    'updatedAt': updatedAt.toIso8601String(),
  };

  factory RememberedAudioTrack.fromJson(Map<String, dynamic> json) {
    return RememberedAudioTrack(
      streamIndex: json['streamIndex'] as int,
      language: json['language'] as String?,
      codec: json['codec'] as String?,
      channels: json['channels'] as int?,
      displayTitle: json['displayTitle'] as String?,
      updatedAt:
          DateTime.tryParse(json['updatedAt'] as String? ?? '') ??
          DateTime.now(),
    );
  }
}

class AudioSettingsState {
  final bool rememberAudioTrack;
  final String preferredAudioLanguage;
  final bool volumeBoost;

  const AudioSettingsState({
    this.rememberAudioTrack = false,
    this.preferredAudioLanguage = '',
    this.volumeBoost = false,
  });

  AudioSettingsState copyWith({
    bool? rememberAudioTrack,
    String? preferredAudioLanguage,
    bool? volumeBoost,
  }) => AudioSettingsState(
    rememberAudioTrack: rememberAudioTrack ?? this.rememberAudioTrack,
    preferredAudioLanguage:
        preferredAudioLanguage ?? this.preferredAudioLanguage,
    volumeBoost: volumeBoost ?? this.volumeBoost,
  );
}

class AudioSettingsNotifier extends AsyncNotifier<AudioSettingsState>
    with SettingsPersistence {
  static const _keyRememberTrack = 'smplayer.audio_remember_track';
  static const _keyPreferredLang = 'smplayer.audio_preferred_language';
  static const _keyVolumeBoost = 'smplayer.audio_volume_boost';
  static const _keyLastAudioTracks = 'smplayer.audio_last_tracks';
  static const _maxRememberedTracks = 200;

  @override
  Future<AudioSettingsState> build() async {
    final prefs = await getPrefs();
    return AudioSettingsState(
      rememberAudioTrack: prefs.getBool(_keyRememberTrack) ?? false,
      preferredAudioLanguage: prefs.getString(_keyPreferredLang) ?? '',
      volumeBoost: prefs.getBool(_keyVolumeBoost) ?? false,
    );
  }

  Future<void> setRememberAudioTrack(bool value) async {
    final current = state.value ?? const AudioSettingsState();
    state = AsyncValue.data(current.copyWith(rememberAudioTrack: value));
    await persistField(_keyRememberTrack, value);
  }

  Future<void> setPreferredAudioLanguage(String language) async {
    final current = state.value ?? const AudioSettingsState();
    state = AsyncValue.data(current.copyWith(preferredAudioLanguage: language));
    await persistField(_keyPreferredLang, language);
  }

  Future<void> setVolumeBoost(bool value) async {
    final current = state.value ?? const AudioSettingsState();
    state = AsyncValue.data(current.copyWith(volumeBoost: value));
    await persistField(_keyVolumeBoost, value);
  }

  Future<void> saveLastAudioTrack(String key, RememberedAudioTrack track) =>
      putRemembered(
        _keyLastAudioTracks,
        key,
        track.toJson(),
        _maxRememberedTracks,
      );

  Future<RememberedAudioTrack?> getLastAudioTrack(String key) async {
    final entry = await readRemembered(_keyLastAudioTracks, key);
    return entry == null ? null : RememberedAudioTrack.fromJson(entry);
  }
}

final audioSettingsProvider =
    AsyncNotifierProvider<AudioSettingsNotifier, AudioSettingsState>(
      AudioSettingsNotifier.new,
    );
