

part of 'player_page.dart';

extension _PlayerPageBottomBar on _PlayerPageState {
  Widget _buildBottomBar(PlaybackSession session) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        if (!_pip.isPip) _buildLogoRow(session),
        DebouncedSeekBar(
          player: session.engine,
          onDragChanged: (t) => _seekPreview.value = t,
        ),
        SizedBox(
          height: _pip.isPip ? 32 : 52,
          child: ValueListenableBuilder<int>(
            valueListenable: _barVersion,
            builder: (context, _, _) {
              if (_pip.isPip) return _buildPipBottomRow(session);
              return _buildFullBottomRow(session);
            },
          ),
        ),
      ],
    );
  }

  Widget _buildLogoRow(PlaybackSession session) {
    final logoUrl = session.context.logoUrl;
    if (logoUrl == null) return const SizedBox.shrink();
    final imageHeaders = ref.watch(embyImageHeadersProvider).value;
    return Padding(
      padding: const EdgeInsets.only(left: 16, bottom: 8),
      child: Align(
        alignment: Alignment.centerLeft,
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 200, maxHeight: 48),
          child: CachedNetworkImage(
            imageUrl: logoUrl,
            httpHeaders: imageHeaders,
            fit: BoxFit.contain,
            alignment: Alignment.bottomLeft,
            memCacheWidth: 600,
            fadeInDuration: const Duration(milliseconds: 200),
            placeholder: (_, _) => const SizedBox.shrink(),
            errorWidget: (_, _, _) => const SizedBox.shrink(),
          ),
        ),
      ),
    );
  }


  List<Widget> _transportControls(
    PlaybackSession session, {
    double? iconSize,
    bool compact = false,
  }) {
    final pl = _playlist;
    final hasPrev = pl?.hasPrev ?? false;
    final hasNext = pl?.hasNext ?? false;
    final btnConstraints = compact
        ? const BoxConstraints(minWidth: 36, minHeight: 36)
        : null;
    final btnPadding = compact ? EdgeInsets.zero : null;
    return [
      IconButton(
        onPressed: hasPrev ? () => unawaited(pl!.prev()) : null,
        icon: Icon(
          Icons.skip_previous,
          color: hasPrev ? Colors.white : Colors.white38,
          size: iconSize,
        ),
        tooltip: '上一集',
        constraints: btnConstraints,
        padding: btnPadding,
      ),
      PlayerPlayPauseButton(
        player: session.engine,
        iconSize: compact ? 24.0 : null,
        constraints: btnConstraints,
      ),
      IconButton(
        onPressed: hasNext ? () => unawaited(pl!.next()) : null,
        icon: Icon(
          Icons.skip_next,
          color: hasNext ? Colors.white : Colors.white38,
          size: iconSize,
        ),
        tooltip: '下一集',
        constraints: btnConstraints,
        padding: btnPadding,
      ),
    ];
  }

  Widget _buildPipBottomRow(PlaybackSession session) {
    return Row(
      children: [
        const Spacer(),
        PlayerPositionIndicator(
          player: session.engine,
          seekPreview: _seekPreview,
        ),
        const SizedBox(width: 4),
        IconButton(
          onPressed: () => unawaited(_togglePip()),
          icon: const Icon(Icons.open_in_full, color: Colors.white, size: 20),
          tooltip: '退出画中画 (P)',
          constraints: const BoxConstraints(minWidth: 32, minHeight: 32),
          padding: EdgeInsets.zero,
          visualDensity: VisualDensity.compact,
        ),
        const SizedBox(width: 8),
      ],
    );
  }

  Widget _buildPipCenterControls(PlaybackSession session) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {},
      child: DecoratedBox(
        decoration: BoxDecoration(
          color: Colors.black.withValues(alpha: 0.35),
          borderRadius: BorderRadius.circular(40),
        ),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: _transportControls(session, iconSize: 26, compact: true),
          ),
        ),
      ),
    );
  }

  Widget _buildFullBottomRow(PlaybackSession session) {
    final allMediaSources = session.context.allMediaSources;
    final embySubtitles = session.context.embySubtitles;
    final hasPicker = session.context.seriesId != null;

    final compactRow = Row(
      children: [
        ..._transportControls(session, iconSize: 24, compact: true),
        Expanded(
          child: FittedBox(
            fit: BoxFit.scaleDown,
            alignment: Alignment.centerLeft,
            child: PlayerPositionIndicator(
              player: session.engine,
              seekPreview: _seekPreview,
            ),
          ),
        ),
        _compactMoreButton(session),
        IconButton(
          tooltip: _fullscreen.isFullscreen ? '退出全屏' : '全屏',
          constraints: const BoxConstraints(minWidth: 40, minHeight: 40),
          padding: EdgeInsets.zero,
          onPressed: () => unawaited(_toggleFullscreen()),
          icon: Icon(
            _fullscreen.isFullscreen ? Icons.fullscreen_exit : Icons.fullscreen,
            color: Colors.white,
            size: 28,
          ),
        ),
      ],
    );

    final row = Row(
      children: [
        ..._transportControls(session),
        if (!Platform.isAndroid)
          PlayerVolumeButton(
            player: session.engine,
            volumeBoost: ref.watch(
              audioSettingsProvider.select(
                (s) => s.value?.volumeBoost ?? false,
              ),
            ),
          ),
        PlayerPositionIndicator(
          player: session.engine,
          seekPreview: _seekPreview,
        ),
        const Spacer(),
        if (allMediaSources.length > 1 || _crossServerCards.isNotEmpty)
          ValueListenableBuilder<bool>(
            valueListenable: _versionBarOpen,
            builder: (context, open, _) => PanelToggleAffordance(
              isOpen: open,
              onTap: _toggleVersionBar,
              tooltip: '切换版本',
              child: const Icon(
                Icons.switch_video,
                color: Colors.white,
                size: 26,
              ),
            ),
          ),
        CompositedTransformTarget(
          link: _panelLinks[PlayerPanelCategory.subtitle]!,
          child: SubtitleTracksButton(
            player: session.engine,
            embySubtitles: embySubtitles,
            isPanelOpen: _drawer.category == PlayerPanelCategory.subtitle,
            onTogglePanel: () => _togglePanel(PlayerPanelCategory.subtitle),
          ),
        ),
        CompositedTransformTarget(
          link: _panelLinks[PlayerPanelCategory.audio]!,
          child: AudioTracksButton(
            player: session.engine,
            isPanelOpen: _drawer.category == PlayerPanelCategory.audio,
            onTogglePanel: () => _togglePanel(PlayerPanelCategory.audio),
          ),
        ),
        CompositedTransformTarget(
          link: _panelLinks[PlayerPanelCategory.speed]!,
          child: SpeedButton(
            currentRate: _playbackRate,
            isPanelOpen: _drawer.category == PlayerPanelCategory.speed,
            onTogglePanel: () => _togglePanel(PlayerPanelCategory.speed),
          ),
        ),
        CompositedTransformTarget(
          link: _panelLinks[PlayerPanelCategory.fit]!,
          child: FitButton(
            currentFit: _videoFit.value,
            isPanelOpen: _drawer.category == PlayerPanelCategory.fit,
            onTogglePanel: () => _togglePanel(PlayerPanelCategory.fit),
          ),
        ),
        if (hasPicker) _panelIcon(PlayerPanelCategory.episode),
        _panelIcon(PlayerPanelCategory.danmaku),
        if (_isDesktopWindow)
          IconButton(
            onPressed: () => unawaited(_togglePip()),
            icon: const Icon(
              Icons.picture_in_picture,
              color: Colors.white,
              size: 24,
            ),
            tooltip: '画中画 (P)',
          ),
        IconButton(
          tooltip: _fullscreen.isFullscreen ? '退出全屏' : '全屏',
          onPressed: () => unawaited(_toggleFullscreen()),
          icon: Icon(
            _fullscreen.isFullscreen
                ? Icons.fullscreen_exit
                : Icons.fullscreen,
            color: Colors.white,
            size: 28,
          ),
        ),
      ],
    );

    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth < Breakpoints.compact) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 4),
            child: compactRow,
          );
        }
        return SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: ConstrainedBox(
            constraints: BoxConstraints(minWidth: constraints.maxWidth),
            child: IntrinsicWidth(child: row),
          ),
        );
      },
    );
  }

  Widget _compactMoreButton(PlaybackSession session) {
    final hasVersion =
        session.context.allMediaSources.length > 1 ||
        _crossServerCards.isNotEmpty;
    final hasPicker = session.context.seriesId != null;
    final items = <_CompactMoreItem>[
      if (hasVersion)
        _CompactMoreItem(
          icon: Icons.switch_video,
          label: '切换版本',
          onTap: _toggleVersionBar,
        ),
      _CompactMoreItem.panel(
        PlayerPanelCategory.subtitle,
        (c) => _showCompactPanelSheet(session, c),
      ),
      _CompactMoreItem.panel(
        PlayerPanelCategory.audio,
        (c) => _showCompactPanelSheet(session, c),
      ),
      _CompactMoreItem.panel(
        PlayerPanelCategory.speed,
        (c) => _showCompactPanelSheet(session, c),
      ),
      _CompactMoreItem.panel(
        PlayerPanelCategory.fit,
        (c) => _showCompactPanelSheet(session, c),
      ),
      if (hasPicker)
        _CompactMoreItem.panel(
          PlayerPanelCategory.episode,
          (c) => _showCompactPanelSheet(session, c),
        ),
      _CompactMoreItem.panel(
        PlayerPanelCategory.danmaku,
        (c) => _showCompactPanelSheet(session, c),
      ),
    ];

    return IconButton(
      tooltip: '更多',
      constraints: const BoxConstraints(minWidth: 40, minHeight: 40),
      padding: EdgeInsets.zero,
      icon: const Icon(Icons.more_horiz, color: Colors.white, size: 26),
      onPressed: () => _showCompactMoreSheet(items),
    );
  }

  Future<void> _showCompactPanelSheet(
    PlaybackSession session,
    PlayerPanelCategory category,
  ) async {
    _versionBarOpen.value = false;
    _drawer.close();
    await showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (_) {
        if (category == PlayerPanelCategory.episode) {
          WidgetsBinding.instance.addPostFrameCallback(
            (_) => _episodeBodyKey.currentState?.ensureLoaded(),
          );
        }
        return SafeArea(
          top: false,
          child: Container(
            margin: const EdgeInsets.fromLTRB(12, 0, 12, 12),
            constraints: BoxConstraints(
              maxHeight: MediaQuery.sizeOf(context).height * 0.72,
            ),
            child: PlayerPanelShell(
              icon: panelCategoryIcon(category),
              title: panelCategoryLabel(category),
              width: double.infinity,
              onClose: () => Navigator.of(context).pop(),
              child: _panelBody(session, category),
            ),
          ),
        );
      },
    );
  }

  Future<void> _showCompactMoreSheet(List<_CompactMoreItem> items) async {
    await showModalBottomSheet<void>(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (sheetContext) => SafeArea(
        top: false,
        child: Container(
          margin: const EdgeInsets.fromLTRB(12, 0, 12, 12),
          decoration: BoxDecoration(
            color: kPanelBg,
            borderRadius: BorderRadius.circular(18),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Padding(
                padding: const EdgeInsets.fromLTRB(16, 14, 16, 8),
                child: Row(
                  children: [
                    const Text(
                      '更多控制',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    const Spacer(),
                    IconButton(
                      onPressed: () => Navigator.of(sheetContext).pop(),
                      icon: const Icon(
                        Icons.close,
                        color: Colors.white70,
                        size: 20,
                      ),
                    ),
                  ],
                ),
              ),
              panelDivider(),
              ConstrainedBox(
                constraints: BoxConstraints(
                  maxHeight: MediaQuery.sizeOf(context).height * 0.56,
                ),
                child: ListView.separated(
                  shrinkWrap: true,
                  padding: const EdgeInsets.symmetric(vertical: 8),
                  itemCount: items.length,
                  separatorBuilder: (_, _) =>
                      panelDivider(),
                  itemBuilder: (context, i) {
                    final item = items[i];
                    return ListTile(
                      leading: Icon(item.icon, color: Colors.white70),
                      title: Text(
                        item.label,
                        style: const TextStyle(color: Colors.white),
                      ),
                      trailing: const Icon(
                        Icons.chevron_right_rounded,
                        color: Colors.white38,
                      ),
                      onTap: () {
                        Navigator.of(sheetContext).pop();
                        item.onTap();
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _CompactMoreItem {
  final IconData icon;
  final String label;
  final VoidCallback onTap;

  const _CompactMoreItem({
    required this.icon,
    required this.label,
    required this.onTap,
  });

  factory _CompactMoreItem.panel(
    PlayerPanelCategory category,
    ValueChanged<PlayerPanelCategory> onToggle,
  ) {
    return _CompactMoreItem(
      icon: panelCategoryIcon(category),
      label: panelCategoryLabel(category),
      onTap: () => onToggle(category),
    );
  }
}
