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

import '../../../core/contracts/library.dart';
import '../../../shared/constants/breakpoints.dart';
import '../../../shared/widgets/frosted_panel.dart';
import '../../../shared/widgets/hover_scrollable_row.dart';

class MediaInfoSection extends StatelessWidget {
  final EmbyRawItem item;
  final int selectedSourceIndex;
  final EmbyRawMediaSource? selectedSource;
  final bool embedded;

  const MediaInfoSection({
    super.key,
    required this.item,
    this.selectedSourceIndex = 0,
    this.selectedSource,
    this.embedded = false,
  });

  static bool hasVisibleContent({
    required EmbyRawItem item,
    int selectedSourceIndex = 0,
    EmbyRawMediaSource? selectedSource,
  }) {
    if (item.Type == 'Series') return false;

    final EmbyRawMediaSource source;
    if (selectedSource != null) {
      source = selectedSource;
    } else {
      final sources = mediaSourcesOfItem(item);
      if (sources.isEmpty) return false;
      source = sources[selectedSourceIndex.clamp(0, sources.length - 1)];
    }
    final streams = source.MediaStreams ?? [];
    if (streams.isEmpty) return false;

    return streams.any(
      (stream) =>
          stream.Type == 'Video' ||
          stream.Type == 'Audio' ||
          stream.Type == 'Subtitle',
    );
  }

  @override
  Widget build(BuildContext context) {
    if (!hasVisibleContent(
      item: item,
      selectedSourceIndex: selectedSourceIndex,
      selectedSource: selectedSource,
    )) {
      return const SizedBox.shrink();
    }

    final EmbyRawMediaSource source;
    if (selectedSource != null) {
      source = selectedSource!;
    } else {
      final sources = mediaSourcesOfItem(item);
      if (sources.isEmpty) return const SizedBox.shrink();
      source = sources[selectedSourceIndex.clamp(0, sources.length - 1)];
    }
    final streams = source.MediaStreams ?? [];
    if (streams.isEmpty) return const SizedBox.shrink();

    final hPad = embedded
        ? 0.0
        : (MediaQuery.sizeOf(context).width < Breakpoints.detail ? 16.0 : 32.0);

    final defaultAudioIdx = source.DefaultAudioStreamIndex;
    final cards = <Widget>[];

    for (final s in streams.where((s) => s.Type == 'Video')) {
      cards.add(_StreamCard(stream: s, kind: _Kind.video));
    }
    for (final s in streams.where((s) => s.Type == 'Audio')) {
      final isDefault =
          (s.Index != null && s.Index == defaultAudioIdx) ||
          (s.IsDefault ?? false);
      cards.add(
        _StreamCard(stream: s, kind: _Kind.audio, isDefault: isDefault),
      );
    }
    for (final s in streams.where((s) => s.Type == 'Subtitle')) {
      cards.add(
        _StreamCard(
          stream: s,
          kind: _Kind.subtitle,
          isDefault: s.IsDefault ?? false,
        ),
      );
    }

    if (cards.isEmpty) return const SizedBox.shrink();

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const FDivider(style: .delta(color: Color(0x1AFFFFFF), padding: .value(EdgeInsets.symmetric(vertical: 24)))),
        Padding(
          padding: EdgeInsets.fromLTRB(hPad, 0, hPad, 16),
          child: Text(
            '媒体信息',
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.w600,
              color: Colors.white.withValues(alpha: 0.9),
            ),
          ),
        ),
        SizedBox(
          height: 280,
          child: HoverScrollableRow(
            builder: (_, controller) => ListView.builder(
              controller: controller,
              scrollDirection: Axis.horizontal,
              padding: EdgeInsets.symmetric(horizontal: hPad),
              itemCount: cards.length,
              itemBuilder: (_, i) => Padding(
                padding: EdgeInsets.only(right: i < cards.length - 1 ? 12 : 0),
                child: cards[i],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

enum _Kind { video, audio, subtitle }

class _StreamCard extends StatelessWidget {
  final EmbyRawMediaStream stream;
  final _Kind kind;
  final bool isDefault;

  const _StreamCard({
    required this.stream,
    required this.kind,
    this.isDefault = false,
  });

  List<(String label, String value)> _fields() {
    final ex = stream.extra;
    final rows = <(String, String)>[];

    switch (kind) {
      case _Kind.video:
        _add(rows, '编码', stream.Codec);
        final w = ex['Width'] as int?;
        final h = ex['Height'] as int?;
        if (w != null && h != null) rows.add(('分辨率', '${w}x$h'));
        final fr =
            (ex['RealFrameRate'] as num?) ?? (ex['AverageFrameRate'] as num?);
        if (fr != null) rows.add(('帧率', fr.toDouble().toStringAsFixed(1)));
        final br = ex['BitRate'] as int?;
        if (br != null) rows.add(('比特率', '${(br / 1000).round()}kbps'));
        _add(rows, '动态范围', ex['VideoRange'] as String?);
        _add(rows, '配置', ex['Profile'] as String?);
      case _Kind.audio:
        _add(rows, '标题', stream.Title);
        _add(rows, '内嵌标题', stream.DisplayTitle);
        _add(rows, '语言', stream.Language);
        _add(rows, '布局', ex['ChannelLayout'] as String?);
        if (stream.Channels != null) rows.add(('声道', '${stream.Channels}'));
        _add(rows, '编码', stream.Codec);
        final br = ex['BitRate'] as int?;
        if (br != null) rows.add(('比特率', '${(br / 1000).round()}kbps'));
        final sr = ex['SampleRate'] as int?;
        if (sr != null) rows.add(('采样率', '${sr}Hz'));
        rows.add(('外部', (stream.IsExternal ?? false) ? '是' : '否'));
        rows.add(('默认', (stream.IsDefault ?? false) ? '是' : '否'));
      case _Kind.subtitle:
        _add(rows, '标题', stream.Title);
        _add(rows, '内嵌标题', stream.DisplayTitle);
        _add(rows, '语言', stream.Language);
        _add(rows, '格式', stream.Codec);
        rows.add(('外部', (stream.IsExternal ?? false) ? '是' : '否'));
        if (stream.IsForced ?? false) rows.add(('强制', '是'));
        rows.add(('默认', (stream.IsDefault ?? false) ? '是' : '否'));
    }
    return rows;
  }

  static void _add(List<(String, String)> rows, String label, String? value) {
    if (value != null && value.isNotEmpty) rows.add((label, value));
  }

  @override
  Widget build(BuildContext context) {
    final fields = _fields();

    final (IconData icon, String name) = switch (kind) {
      _Kind.video => (Icons.videocam_outlined, '视频'),
      _Kind.audio => (Icons.music_note_outlined, '音频'),
      _Kind.subtitle => (Icons.subtitles_outlined, '字幕'),
    };

    return SizedBox(
      width: 260,
      height: 280,
      child: FrostedPanel(
        radius: 12,
        padding: const EdgeInsets.all(16),
        blurSigma: 15,
        border: Border.all(color: Colors.white.withValues(alpha: 0.08)),
        color: Colors.black26,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(icon, size: 16, color: Colors.white),
                const SizedBox(width: 6),
                Text(
                  name,
                  style: const TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    color: Colors.white,
                  ),
                ),
                if (isDefault) ...[
                  const SizedBox(width: 6),
                  Icon(
                    Icons.check,
                    size: 14,
                    color: Colors.white.withValues(alpha: 0.7),
                  ),
                ],
              ],
            ),
            const SizedBox(height: 12),
            Expanded(
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    for (final (label, value) in fields)
                      Padding(
                        padding: const EdgeInsets.only(bottom: 5),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            SizedBox(
                              width: 60,
                              child: Text(
                                label,
                                style: TextStyle(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w400,
                                  color: Colors.white.withValues(alpha: 0.55),
                                ),
                              ),
                            ),
                            Expanded(
                              child: Text(
                                value,
                                style: TextStyle(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w400,
                                  color: Colors.white.withValues(alpha: 0.85),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
