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

import '../../core/contracts/library.dart';

const Color _defaultSeasonAccentColor = Color(0xFF4F8DFF);
const double _inlineSeasonHorizontalPadding = 14;
const double _inlineSeasonVerticalPadding = 6;
const double _inlineSeasonGap = 8;
const double _inlineWidthSafetyMargin = 2;
const TextStyle _inlineSeasonTextStyle = TextStyle(fontSize: 13);

class SeasonSelector extends StatelessWidget {
  final List<EmbyRawSeason> seasons;
  final String selectedId;
  final ValueChanged<String> onSelect;
  final Color accentColor;
  final Color? backgroundColor;

  const SeasonSelector({
    super.key,
    required this.seasons,
    required this.selectedId,
    required this.onSelect,
    this.accentColor = _defaultSeasonAccentColor,
    this.backgroundColor,
  });

  EmbyRawSeason _resolveSelectedSeason() {
    for (final season in seasons) {
      if (season.Id == selectedId) return season;
    }
    return seasons.first;
  }

  TextStyle _inlineTextStyle(bool selected) {
    return _inlineSeasonTextStyle.copyWith(
      fontWeight: selected ? FontWeight.w600 : FontWeight.normal,
      color: selected ? Colors.white : Colors.white.withValues(alpha: 0.7),
    );
  }

  double _calculateInlineWidth(BuildContext context) {
    final textDirection = Directionality.of(context);
    final textScaler = MediaQuery.textScalerOf(context);
    var requiredWidth = 0.0;

    for (var index = 0; index < seasons.length; index++) {
      final season = seasons[index];
      final textPainter = TextPainter(
        text: TextSpan(
          text: season.Name,
          style: _inlineTextStyle(season.Id == selectedId),
        ),
        maxLines: 1,
        textDirection: textDirection,
        textScaler: textScaler,
      )..layout();
      requiredWidth += textPainter.width + (_inlineSeasonHorizontalPadding * 2);
      if (index > 0) requiredWidth += _inlineSeasonGap;
    }

    return requiredWidth + _inlineWidthSafetyMargin;
  }

  @override
  Widget build(BuildContext context) {
    if (seasons.isEmpty) return const SizedBox.shrink();

    final selectedSeason = _resolveSelectedSeason();

    return LayoutBuilder(
      builder: (context, constraints) {
        final inlineWidth = _calculateInlineWidth(context);
        final hasEnoughInlineSpace =
            !constraints.hasBoundedWidth || inlineWidth <= constraints.maxWidth;

        final selector = hasEnoughInlineSpace
            ? _buildInlineOptions()
            : _buildDropdownSelect(context, selectedSeason);

        return Align(
          alignment: Alignment.centerLeft,
          widthFactor: 1,
          child: selector,
        );
      },
    );
  }

  Widget _buildInlineOptions() {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        for (var index = 0; index < seasons.length; index++) ...[
          if (index > 0) const SizedBox(width: _inlineSeasonGap),
          _buildInlineOption(seasons[index]),
        ],
      ],
    );
  }

  Widget _buildInlineOption(EmbyRawSeason season) {
    final selected = season.Id == selectedId;

    return Material(
      color: Colors.transparent,
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: selected ? null : () => onSelect(season.Id),
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 150),
          padding: const EdgeInsets.symmetric(
            horizontal: _inlineSeasonHorizontalPadding,
            vertical: _inlineSeasonVerticalPadding,
          ),
          decoration: BoxDecoration(
            color: selected
                ? accentColor.withValues(alpha: 0.28)
                : backgroundColor ?? Colors.white.withValues(alpha: 0.08),
            borderRadius: BorderRadius.circular(20),
          ),
          child: Text(season.Name, style: _inlineTextStyle(selected)),
        ),
      ),
    );
  }

  Widget _buildDropdownSelect(
    BuildContext context,
    EmbyRawSeason selectedSeason,
  ) {
    final controlWidth = _calculateControlWidth(context, selectedSeason);
    final menuWidth = _calculateMenuWidth(context, controlWidth);

    return SizedBox(
      width: controlWidth,
      child: FSelect<String>.rich(
        control: FSelectControl<String>.lifted(
          value: selectedId,
          onChange: (seasonId) {
            if (seasonId != null && seasonId != selectedId) {
              onSelect(seasonId);
            }
          },
        ),
        format: _seasonNameForId,
        contentConstraints: FPortalConstraints(
          minWidth: menuWidth,
          maxWidth: menuWidth,
          maxHeight: 360,
        ),
        children: [
          for (final season in seasons)
            FSelectItem<String>.item(
              title: Text(season.Name),
              subtitle: season.ChildCount == null
                  ? null
                  : Text('${season.ChildCount} 集'),
              value: season.Id,
            ),
        ],
      ),
    );
  }

  double _calculateControlWidth(
    BuildContext context,
    EmbyRawSeason selectedSeason,
  ) {
    final selectedTextWidth = _measureTextWidth(
      context,
      selectedSeason.Name,
      _inlineSeasonTextStyle.copyWith(fontWeight: FontWeight.w600),
    );


    return (selectedTextWidth + 64).clamp(104.0, 200.0).toDouble();
  }

  double _calculateMenuWidth(BuildContext context, double controlWidth) {
    var widestContent = 0.0;
    for (final season in seasons) {
      final seasonNameWidth = _measureTextWidth(
        context,
        season.Name,
        const TextStyle(fontSize: 14),
      );
      final episodeCountWidth = season.ChildCount == null
          ? 0.0
          : _measureTextWidth(
              context,
              '${season.ChildCount} 集',
              const TextStyle(fontSize: 12),
            );
      widestContent = widestContent.clamp(
        seasonNameWidth > episodeCountWidth
            ? seasonNameWidth
            : episodeCountWidth,
        double.infinity,
      );
    }

    final screenWidth = MediaQuery.sizeOf(context).width;
    final maximumSafeWidth = (screenWidth - 32).clamp(
      controlWidth,
      double.infinity,
    );


    return (widestContent + 72)
        .clamp(controlWidth, maximumSafeWidth)
        .toDouble();
  }

  double _measureTextWidth(BuildContext context, String text, TextStyle style) {
    final textPainter = TextPainter(
      text: TextSpan(text: text, style: style),
      maxLines: 1,
      textDirection: Directionality.of(context),
      textScaler: MediaQuery.textScalerOf(context),
    )..layout();
    return textPainter.width;
  }

  String _seasonNameForId(String seasonId) {
    for (final season in seasons) {
      if (season.Id == seasonId) return season.Name;
    }
    return _resolveSelectedSeason().Name;
  }
}
