import 'dart:async';
import 'dart:io' show Platform;

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

import 'package:forui/forui.dart';

import '../../../../core/contracts/playback.dart';
import '../../../../core/infra/player_engine/player_engine.dart';
import '../../../../providers/subtitle_settings_provider.dart';
import '../player_drawer_panel.dart';
import '../player_panel_shell.dart';
import 'panel_selection_list.dart';
import 'panel_setting_rows.dart';
import 'selection_panel_entry.dart';

const _activeColor = Color(0xFF2196F3);

String? _translateLanguage(String? code) {
  if (code == null || code.isEmpty) return null;
  return kLanguageNames[code.toLowerCase()];
}

enum _SubtitlePanelView { subtitles, style }

class SubtitlePanelBody extends StatefulWidget {
  final SubtitleStyleSettings subtitleSettings;
  final ValueChanged<SubtitleStyleSettings> onSubtitleSettingsChanged;


  final List<EmbySubtitleTrack> subtitles;


  final ValueListenable<int?> activeSubtitleStreamIndex;


  final ValueListenable<bool> subtitleLoading;


  final void Function(int? streamIndex)? onSubtitleSelected;

  const SubtitlePanelBody({
    super.key,
    required this.subtitleSettings,
    required this.onSubtitleSettingsChanged,
    required this.subtitles,
    required this.activeSubtitleStreamIndex,
    required this.subtitleLoading,
    this.onSubtitleSelected,
  });

  @override
  State<SubtitlePanelBody> createState() => _SubtitlePanelBodyState();
}

class _SubtitlePanelBodyState extends State<SubtitlePanelBody> {
  _SubtitlePanelView _selectedView = _SubtitlePanelView.subtitles;


  int? _activeStreamIndex;
  bool _isSubtitleLoading = false;

  @override
  void initState() {
    super.initState();
    widget.activeSubtitleStreamIndex.addListener(_onActiveIndexChanged);
    widget.subtitleLoading.addListener(_onLoadingChanged);
    _activeStreamIndex = widget.activeSubtitleStreamIndex.value;
    _isSubtitleLoading = widget.subtitleLoading.value;
  }

  @override
  void didUpdateWidget(covariant SubtitlePanelBody oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.activeSubtitleStreamIndex !=
        widget.activeSubtitleStreamIndex) {
      oldWidget.activeSubtitleStreamIndex.removeListener(_onActiveIndexChanged);
      widget.activeSubtitleStreamIndex.addListener(_onActiveIndexChanged);
      _activeStreamIndex = widget.activeSubtitleStreamIndex.value;
    }
    if (oldWidget.subtitleLoading != widget.subtitleLoading) {
      oldWidget.subtitleLoading.removeListener(_onLoadingChanged);
      widget.subtitleLoading.addListener(_onLoadingChanged);
      _isSubtitleLoading = widget.subtitleLoading.value;
    }
  }

  @override
  void dispose() {
    widget.activeSubtitleStreamIndex.removeListener(_onActiveIndexChanged);
    widget.subtitleLoading.removeListener(_onLoadingChanged);
    super.dispose();
  }

  void _onActiveIndexChanged() {
    if (!mounted) return;
    setState(() => _activeStreamIndex = widget.activeSubtitleStreamIndex.value);
  }

  void _onLoadingChanged() {
    if (!mounted) return;
    setState(() => _isSubtitleLoading = widget.subtitleLoading.value);
  }


  void _selectSubtitle(int? streamIndex) {
    if (!mounted) return;
    setState(() => _activeStreamIndex = streamIndex);
    widget.onSubtitleSelected?.call(streamIndex);
  }

  @override
  Widget build(BuildContext context) {
    if (Platform.isAndroid) return _buildAndroidBody();
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(width: 150, child: _leftMenu()),
        const FDivider(
          axis: Axis.vertical,
          style: .delta(color: kPanelDivider, padding: .value(EdgeInsets.zero)),
        ),
        Expanded(child: _content()),
      ],
    );
  }

  Widget _buildAndroidBody() {
    if (_selectedView == _SubtitlePanelView.style) {
      return PlayerDrawerPanel(
        title: '字幕样式',
        onBack: () =>
            setState(() => _selectedView = _SubtitlePanelView.subtitles),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: _subtitleStyleRows(),
        ),
      );
    }
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        _androidStyleEntry(),
        panelDivider(),
        Flexible(child: _subtitleList()),
      ],
    );
  }


  Widget _androidStyleEntry() {
    return InkWell(
      onTap: () => setState(() => _selectedView = _SubtitlePanelView.style),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Row(
          children: [
            const Icon(
              Icons.closed_caption_outlined,
              color: Colors.white54,
              size: 16,
            ),
            const SizedBox(width: 10),
            const Expanded(
              child: Text(
                '字幕样式',
                style: TextStyle(color: Colors.white, fontSize: 13),
              ),
            ),
            Text(
              _subtitleStyleLabel(),
              style: const TextStyle(color: Colors.white38, fontSize: 11),
            ),
            const SizedBox(width: 4),
            const Icon(Icons.chevron_right, color: Colors.white24, size: 16),
          ],
        ),
      ),
    );
  }

  Widget _content() {
    switch (_selectedView) {
      case _SubtitlePanelView.subtitles:
        return _subtitleList();
      case _SubtitlePanelView.style:
        return _subtitleSettings();
    }
  }

  Widget _leftMenu() {
    return SingleChildScrollView(
      padding: const EdgeInsets.symmetric(vertical: 8),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          _menuItem(
            view: _SubtitlePanelView.subtitles,
            label: '字幕',
            subtitle: _activeSubtitleLabel(),
            icon: Icons.subtitles_outlined,
          ),
          _menuItem(
            view: _SubtitlePanelView.style,
            label: '字幕样式',
            subtitle: _subtitleStyleLabel(),
            icon: Icons.closed_caption_outlined,
          ),
        ],
      ),
    );
  }

  Widget _menuItem({
    required _SubtitlePanelView view,
    required String label,
    required String subtitle,
    required IconData icon,
  }) {
    final selected = _selectedView == view;
    return GestureDetector(
      onTap: () => setState(() => _selectedView = view),
      behavior: HitTestBehavior.opaque,
      child: Container(
        margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
        decoration: selected
            ? BoxDecoration(
                color: Colors.white.withOpacity(0.08),
                borderRadius: BorderRadius.circular(6),
              )
            : null,
        child: Row(
          children: [
            Icon(
              icon,
              size: 16,
              color: selected ? _activeColor : Colors.white54,
            ),
            const SizedBox(width: 8),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    label,
                    style: TextStyle(
                      color: selected ? _activeColor : Colors.white,
                      fontSize: 13,
                      fontWeight: selected
                          ? FontWeight.w600
                          : FontWeight.normal,
                    ),
                  ),
                  Text(
                    subtitle,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      color: selected
                          ? _activeColor.withOpacity(0.7)
                          : Colors.white38,
                      fontSize: 11,
                    ),
                  ),
                ],
              ),
            ),
            Icon(
              Icons.chevron_right,
              size: 16,
              color: selected ? _activeColor : Colors.white24,
            ),
          ],
        ),
      ),
    );
  }

  Widget _subtitleList() {
    final embedded = widget.subtitles
        .where((track) => !track.isExternal)
        .toList(growable: false);
    final external = widget.subtitles
        .where((track) => track.isExternal)
        .toList(growable: false);

    const disableValue = -1;
    final entries = <SelectionPanelEntry<int>>[
      SelectionPanelEntry.item(
        value: disableValue,
        label: '禁用',
        isActive: _activeStreamIndex == null,
      ),
      if (embedded.isNotEmpty) const SelectionPanelEntry.divider(),
      for (final track in embedded)
        SelectionPanelEntry.item(
          value: track.index,
          label: track.title ?? track.language ?? '字幕 ${track.index}',
          subtitle: _translateLanguage(track.language),
          isActive: _activeStreamIndex == track.index,
          isLoading: _isSubtitleLoading && _activeStreamIndex == track.index,
        ),
      if (external.isNotEmpty) const SelectionPanelEntry.divider(),
      for (final track in external)
        SelectionPanelEntry.item(
          value: track.index,
          label: track.title ?? track.language ?? '外挂字幕 ${track.index}',
          subtitle: _translateLanguage(track.language),
          badge: '外挂',
          isActive: _activeStreamIndex == track.index,
          isLoading: _isSubtitleLoading && _activeStreamIndex == track.index,
        ),
    ];
    return PanelSelectionList<int>(
      entries: entries,
      onSelected: (value) =>
          _selectSubtitle(value == disableValue ? null : value),
    );
  }

  Widget _subtitleSettings() {
    return SingleChildScrollView(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const PanelGroupHeader(title: '主字幕样式'),
          ..._subtitleStyleRows(),
          const SizedBox(height: 8),
        ],
      ),
    );
  }


  List<Widget> _subtitleStyleRows() {
    final settings = widget.subtitleSettings;
    return [
      PanelSliderRow(
        label: '位置',
        value: settings.position.toDouble(),
        min: 0,
        max: 150,
        step: 5,
        display: settings.position.toString(),
        onChanged: (v) => widget.onSubtitleSettingsChanged(
          settings.copyWith(position: v.round()),
        ),
      ),
      PanelSliderRow(
        label: '大小',
        value: settings.fontSize,
        min: 10,
        max: 120,
        step: 2,
        display: settings.fontSize.round().toString(),
        onChanged: (v) =>
            widget.onSubtitleSettingsChanged(settings.copyWith(fontSize: v)),
      ),
      PanelSliderRow(
        label: '延迟',
        value: settings.delay,
        min: -10.0,
        max: 10.0,
        step: 0.5,
        display:
            '${settings.delay >= 0 ? '+' : ''}${settings.delay.toStringAsFixed(1)}s',
        onChanged: (v) =>
            widget.onSubtitleSettingsChanged(settings.copyWith(delay: v)),
      ),
      PanelSliderRow(
        label: '背景',
        value: settings.bgOpacity,
        min: 0.0,
        max: 1.0,
        step: 0.1,
        display: '${(settings.bgOpacity * 100).round()}%',
        onChanged: (v) =>
            widget.onSubtitleSettingsChanged(settings.copyWith(bgOpacity: v)),
      ),
    ];
  }

  String _activeSubtitleLabel() {
    final index = _activeStreamIndex;
    if (index == null) return '禁用';
    final track = widget.subtitles
        .where((subtitle) => subtitle.index == index)
        .firstOrNull;
    if (track == null) return '字幕';
    return track.title ?? track.language ?? '字幕 ${track.index}';
  }

  String _subtitleStyleLabel() {
    final settings = widget.subtitleSettings;
    return '${settings.fontSize.round()} / ${settings.delay >= 0 ? '+' : ''}${settings.delay.toStringAsFixed(1)}s';
  }
}

class AudioPanelBody extends StatefulWidget {
  final PlayerEngine player;
  final void Function(AudioTrack track)? onAudioTrackSelected;

  const AudioPanelBody({
    super.key,
    required this.player,
    this.onAudioTrackSelected,
  });

  @override
  State<AudioPanelBody> createState() => _AudioPanelBodyState();
}

class _AudioPanelBodyState extends State<AudioPanelBody> {
  AudioTrack _activeAudio = const AudioTrack.auto();
  List<AudioTrack> _audioTracks = const [];
  StreamSubscription<PlayerTrack>? _trackSub;
  StreamSubscription<PlayerTracks>? _tracksSub;

  @override
  void initState() {
    super.initState();
    _syncFromPlayer(widget.player);
    _subscribePlayer(widget.player);
  }

  @override
  void didUpdateWidget(covariant AudioPanelBody oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.player != widget.player) {
      _cancelSubscriptions();
      _syncFromPlayer(widget.player);
      _subscribePlayer(widget.player);
    }
  }

  @override
  void dispose() {
    _cancelSubscriptions();
    super.dispose();
  }

  void _syncFromPlayer(PlayerEngine player) {
    _activeAudio = player.state.track.audio;
    _audioTracks = player.state.tracks.embeddedAudio;
  }

  void _subscribePlayer(PlayerEngine player) {
    _trackSub = player.stream.track.listen((track) {
      if (!mounted) return;
      setState(() => _activeAudio = track.audio);
    });
    _tracksSub = player.stream.tracks.listen((tracks) {
      if (!mounted) return;
      setState(() => _audioTracks = tracks.embeddedAudio);
    });
  }

  void _cancelSubscriptions() {
    unawaited(_trackSub?.cancel());
    unawaited(_tracksSub?.cancel());
    _trackSub = null;
    _tracksSub = null;
  }

  Future<void> _selectAudio(AudioTrack track) async {
    if (!mounted) return;
    setState(() => _activeAudio = track);
    await WidgetsBinding.instance.endOfFrame;
    if (!mounted) return;
    try {
      await widget.player.setAudioTrack(track);
      widget.onAudioTrackSelected?.call(track);
    } catch (_) {
      if (mounted) {
        setState(() => _activeAudio = widget.player.state.track.audio);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return _audioList();
  }

  Widget _audioList() {
    final entries = <SelectionPanelEntry<AudioTrack>>[
      for (final t in _audioTracks)
        SelectionPanelEntry.item(
          value: t,
          label: t.title ?? t.language ?? '音频 ${t.id}',
          subtitle: _translateLanguage(t.language) ?? t.language,
          isActive: _activeAudio.id == t.id,
        ),
      if (_audioTracks.isNotEmpty) const SelectionPanelEntry.divider(),
      SelectionPanelEntry.item(
        value: const AudioTrack.no(),
        label: '关闭音频',
        isActive: _activeAudio.id == 'no',
      ),
    ];
    return PanelSelectionList<AudioTrack>(
      entries: entries,
      onSelected: (track) => unawaited(_selectAudio(track)),
    );
  }
}
