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

import '../../../models/participant_model.dart';
import '../../../models/score_model.dart';
import '../../../models/member_model.dart';
import '../../../models/club_model.dart';
import '../../../models/tie_breaker_option.dart';
import '../../../utils/tie_breaker_util.dart';
import '../../../theme/badges.dart';

class ScoresTab extends StatefulWidget {
  final String eventId;
  final List<Participant> participants;
  final List<Score> scores;
  final List<Member> members;
  final List<Member> clubMembers; // for gender icon lookup
  final Club? club;

  final bool includeHandicap;
  final ValueChanged<bool> onIncludeHandicapChanged;

  final bool groupByParticipant;
  final ValueChanged<bool> onGroupByParticipantChanged;

  final Future<void> Function(Participant participant, List<Score> scores) onOpenBatchEdit;
  final Future<void> Function(Score score) onEditScore;
  final void Function(Score score) onDeleteScore;

  const ScoresTab({
    super.key,
    required this.eventId,
    required this.participants,
    required this.scores,
    required this.members,
    required this.clubMembers,
    required this.club,
    required this.includeHandicap,
    required this.onIncludeHandicapChanged,
    required this.groupByParticipant,
    required this.onGroupByParticipantChanged,
    required this.onOpenBatchEdit,
    required this.onEditScore,
    required this.onDeleteScore,
  });

  @override
  State<ScoresTab> createState() => _ScoresTabState();
}

class _ScoresTabState extends State<ScoresTab> {
  @override
  Widget build(BuildContext context) {
    if (widget.scores.isEmpty) {
      return const Center(child: Text('등록된 점수가 없습니다.'));
    }

    // 동점자 처리 옵션
    List<TieBreakerOption>? tieBreakerOptions;
    if (widget.club != null &&
        widget.club!.tieBreakerOptions != null &&
        widget.club!.tieBreakerOptions!.isNotEmpty) {
      tieBreakerOptions = widget.club!.tieBreakerOptions;
    }

    // 정렬/순위 계산
    final sortedScores = TieBreakerUtil.sortScoresByOptions(
      widget.scores,
      tieBreakerOptions,
      widget.members,
      widget.includeHandicap,
    );

    final ranks = TieBreakerUtil.computeScoreRanks(
      sortedScores,
      includeHandicap: widget.includeHandicap,
      options: tieBreakerOptions,
      members: widget.members,
    );

    // 평균/최고/최저
    final totalScoreSum = sortedScores.fold<int>(
      0,
      (sum, s) => sum + (widget.includeHandicap ? s.totalScore + (s.handicap ?? 0) : s.totalScore),
    );
    final averageScore = sortedScores.isNotEmpty ? totalScoreSum / sortedScores.length : 0.0;
    final int? maxScore = sortedScores.isNotEmpty
        ? sortedScores
            .map((s) => widget.includeHandicap ? s.totalScore + (s.handicap ?? 0) : s.totalScore)
            .reduce((a, b) => a > b ? a : b)
        : null;
    final int? minScore = sortedScores.isNotEmpty
        ? sortedScores
            .map((s) => widget.includeHandicap ? s.totalScore + (s.handicap ?? 0) : s.totalScore)
            .reduce((a, b) => a < b ? a : b)
        : null;

    return Column(
      children: [
        // Summary cards
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
          child: Row(
            children: [
              Expanded(
                child: _summaryCard(
                  color: Colors.blue.shade50,
                  icon: const Icon(Icons.analytics, color: Colors.blue),
                  title: '평균',
                  value: averageScore.toStringAsFixed(1),
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _summaryCard(
                  color: Colors.green.shade50,
                  icon: const Icon(Icons.trending_up, color: Colors.green),
                  title: '최고',
                  value: maxScore?.toString() ?? '-',
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _summaryCard(
                  color: Colors.red.shade50,
                  icon: const Icon(Icons.trending_down, color: Colors.red),
                  title: '최저',
                  value: minScore?.toString() ?? '-',
                ),
              ),
            ],
          ),
        ),
        Container(
          padding: const EdgeInsets.all(8),
          margin: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            color: Colors.blue.shade50,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: Colors.blue.shade200),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.score, color: Colors.blue),
              const SizedBox(width: 8),
              Text('평균 점수: ${averageScore.toStringAsFixed(1)}',
                  style: const TextStyle(fontWeight: FontWeight.bold)),
            ],
          ),
        ),
        if (tieBreakerOptions != null && tieBreakerOptions.isNotEmpty)
          Container(
            padding: const EdgeInsets.all(8),
            margin: const EdgeInsets.symmetric(horizontal: 8),
            decoration: BoxDecoration(
              color: Colors.green.shade50,
              borderRadius: BorderRadius.circular(8),
              border: Border.all(color: Colors.green.shade200),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('동점자 처리 우선순위:', style: TextStyle(fontWeight: FontWeight.bold)),
                const SizedBox(height: 4),
                Wrap(
                  spacing: 8,
                  children: tieBreakerOptions.map((o) => Chip(
                        label: Text(_tieBreakerLabel(o)),
                        backgroundColor: Colors.green.shade100,
                      )).toList(),
                ),
              ],
            ),
          ),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
          child: Row(
            children: [
              ToggleButtons(
                isSelected: [widget.groupByParticipant, !widget.groupByParticipant],
                onPressed: (i) => widget.onGroupByParticipantChanged(i == 0),
                constraints: const BoxConstraints(minHeight: 32, minWidth: 100),
                borderRadius: BorderRadius.circular(8),
                children: const [
                  Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: Text('참가자별')),
                  Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: Text('점수별')),
                ],
              ),
              const Spacer(),
              Row(
                children: [
                  const Text('핸디캡 포함'),
                  Switch(
                    value: widget.includeHandicap,
                    onChanged: widget.onIncludeHandicapChanged,
                  ),
                ],
              )
            ],
          ),
        ),
        Expanded(
          child: widget.groupByParticipant
              ? _buildGroupedList(sortedScores)
              : ListView.builder(
                  itemCount: sortedScores.length,
                  itemBuilder: (context, index) {
                    final score = sortedScores[index];
                    final rank = ranks[score.id] ?? (index + 1);
                    var participant = widget.participants.firstWhere(
                      (p) => p.id == (score.participantId ?? ''),
                      orElse: () => Participant(
                        id: '',
                        eventId: '',
                        memberId: score.memberId,
                        name: '알 수 없음',
                      ),
                    );
                    if (participant.id.isEmpty) {
                      final byMember = widget.participants.where((p) => p.memberId == score.memberId);
                      if (byMember.isNotEmpty) participant = byMember.first;
                    }
                    return _buildScoreListItem(context, score, rank, participant);
                  },
                ),
        ),
      ],
    );
  }

  Widget _summaryCard({required Color color, required Icon icon, required String title, required String value}) {
    return Card(
      color: color,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 10),
        child: Row(
          children: [
            icon,
            const SizedBox(width: 8),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(title, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 12, color: Colors.black54)),
                  Text(value, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  String _tieBreakerLabel(TieBreakerOption option) {
    switch (option) {
      case TieBreakerOption.lowerHandicap:
        return '핸디캡 낮은 순';
      case TieBreakerOption.lowerScoreGap:
        return '점수 격차 작은 순';
      case TieBreakerOption.olderAge:
        return '연장자 우선';
      case TieBreakerOption.none:
        return '없음';
    }
  }

  Widget _buildGroupedList(List<Score> sortedScores) {
    final summaries = widget.participants.map((p) {
      final pScores = sortedScores.where((s) => ((s.participantId != null && s.participantId!.isNotEmpty && s.participantId == p.id) || ((s.participantId == null || s.participantId!.isEmpty) && s.memberId == p.memberId))).toList();
      if (pScores.isEmpty) return null;
      pScores.sort((a, b) => (a.gameNumber ?? 0).compareTo(b.gameNumber ?? 0));
      final totals = pScores.map((s) => s.totalScore).toList();
      final totalsH = pScores.map((s) => s.totalScore + (s.handicap ?? 0)).toList();
      final total = totals.fold<int>(0, (a, b) => a + b);
      final totalH = totalsH.fold<int>(0, (a, b) => a + b);
      final avg = totals.isNotEmpty ? (total / totals.length) : 0.0;
      final avgH = totalsH.isNotEmpty ? (totalH / totalsH.length) : 0.0;
      final high = totals.isNotEmpty ? totals.reduce((a, b) => a > b ? a : b) : 0;
      final highH = totalsH.isNotEmpty ? totalsH.reduce((a, b) => a > b ? a : b) : 0;
      final low = totals.isNotEmpty ? totals.reduce((a, b) => a < b ? a : b) : 0;
      final lowH = totalsH.isNotEmpty ? totalsH.reduce((a, b) => a < b ? a : b) : 0;
      final handicapSum = pScores.fold<int>(0, (a, s) => a + (s.handicap ?? 0));
      return {
        'p': p,
        'scores': pScores,
        'total': total,
        'totalH': totalH,
        'avg': avg,
        'avgH': avgH,
        'high': high,
        'highH': highH,
        'low': low,
        'lowH': lowH,
        'handicapSum': handicapSum,
      };
    }).whereType<Map<String, dynamic>>().toList();

    final ranked = TieBreakerUtil.rankParticipantSummaries(
      summaries,
      includeHandicap: widget.includeHandicap,
    );

    return ListView(
      children: ranked.map((data) {
        final rank = data['rank'] as int;
        final p = data['p'] as Participant;
        final pScores = data['scores'] as List<Score>;
        final total = data['total'] as int;
        final totalH = data['totalH'] as int;
        final avg = data['avg'] as double;
        final avgH = data['avgH'] as double;
        final high = data['high'] as int;
        final highH = data['highH'] as int;
        final low = data['low'] as int;
        final lowH = data['lowH'] as int;
        final handicapSum = data['handicapSum'] as int;
        final displayTotal = widget.includeHandicap ? totalH : total;
        final displayAvg = widget.includeHandicap ? avgH : avg;
        final subtitle = widget.includeHandicap
            ? '게임 ${pScores.length} · 최저 $lowH · 최고 $highH'
            : '게임 ${pScores.length} · 최저 $low · 최고 $high';

        Icon? genderIcon;
        try {
          final m = widget.clubMembers.firstWhere((cm) => cm.id == p.memberId);
          final g = m.gender?.toLowerCase();
          if (g == 'male' || g == 'm' || g == '남' || g == '남성') {
            genderIcon = const Icon(Icons.male, size: 16, color: Colors.blue);
          } else if (g == 'female' || g == 'f' || g == '여' || g == '여성') {
            genderIcon = const Icon(Icons.female, size: 16, color: Colors.pink);
          }
        } catch (_) {}

        return ExpansionTile(
          leading: CircleAvatar(
            backgroundColor: _getRankColor(rank),
            child: Text('$rank', style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
          ),
          title: Row(
            children: [
              Expanded(
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    Flexible(
                      fit: FlexFit.loose,
                      child: Text(
                        p.name ?? '알 수 없음',
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
                      ),
                    ),
                    const SizedBox(width: 8),
                    Flexible(
                      child: FittedBox(
                        fit: BoxFit.scaleDown,
                        alignment: Alignment.centerLeft,
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            // Small guest badge next to name (grouped)
                            if ((p.memberType ?? '').toLowerCase() == 'guest')
                              Padding(
                                padding: const EdgeInsets.only(right: 6),
                                child: BadgeStyles.guestSmall(size: 16),
                              ),
                            if (genderIcon != null)
                              Icon(genderIcon.icon, size: 20, color: genderIcon.color),
                            if (handicapSum != 0) ...[
                              const SizedBox(width: 8),
                              Container(
                                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
                                decoration: BoxDecoration(
                                  color: Colors.indigo.shade100,
                                  borderRadius: BorderRadius.circular(14),
                                ),
                                child: Text('+$handicapSum', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w700)),
                              ),
                            ],
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 8),
              Row(
                children: [
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
                    decoration: BoxDecoration(
                      color: displayAvg >= 200 ? Colors.red.shade400 : Colors.blue.shade100,
                      borderRadius: BorderRadius.circular(14),
                    ),
                    child: Text(
                      displayAvg.toStringAsFixed(1),
                      style: TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w700,
                        color: displayAvg >= 200 ? Colors.white : Colors.black87,
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
          subtitle: Row(
            children: [
              Expanded(
                child: Text(subtitle, style: const TextStyle(fontSize: 13), overflow: TextOverflow.ellipsis, maxLines: 1),
              ),
              const SizedBox(width: 8),
              FittedBox(
                fit: BoxFit.scaleDown,
                child: Container(
                  padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
                  decoration: BoxDecoration(color: Colors.blue.shade100, borderRadius: BorderRadius.circular(14)),
                  child: Text('$displayTotal', style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.black87)),
                ),
              ),
            ],
          ),
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 4, 16, 0),
              child: Align(
                alignment: Alignment.centerRight,
                child: OutlinedButton.icon(
                  icon: const Icon(Icons.edit, size: 18),
                  label: const Text('전체 수정'),
                  onPressed: () => widget.onOpenBatchEdit(p, pScores),
                  style: OutlinedButton.styleFrom(
                    visualDensity: VisualDensity.compact,
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
                  ),
                ),
              ),
            ),
            ...pScores.map((s) {
              final scoreText = widget.includeHandicap
                  ? '${s.totalScore + (s.handicap ?? 0)} (${s.totalScore}+${s.handicap ?? 0})'
                  : '${s.totalScore}';
              final int displayVal = widget.includeHandicap ? (s.totalScore + (s.handicap ?? 0)) : s.totalScore;
              final gameNo = s.gameNumber?.toString() ?? '';
              return Dismissible(
                key: ValueKey('score_${s.id}_${s.gameNumber ?? ''}'),
                direction: DismissDirection.endToStart,
                background: Container(
                  alignment: Alignment.centerRight,
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  color: Colors.red.shade400,
                  child: const Icon(Icons.delete, color: Colors.white),
                ),
                onDismissed: (_) => widget.onDeleteScore(s),
                child: ListTile(
                  dense: true,
                  contentPadding: const EdgeInsets.symmetric(horizontal: 50),
                  leading: CircleAvatar(
                    radius: 18,
                    child: Text(gameNo.isEmpty ? '-' : gameNo, style: const TextStyle(fontSize: 15)),
                  ),
                  title: Row(
                    children: [
                      Expanded(
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            if (displayVal >= 200)
                              Container(
                                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
                                decoration: BoxDecoration(color: Colors.red.shade400, borderRadius: BorderRadius.circular(12)),
                                child: Text(
                                  scoreText,
                                  maxLines: 1,
                                  overflow: TextOverflow.ellipsis,
                                  style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.white),
                                ),
                              )
                            else
                              Text(
                                scoreText,
                                maxLines: 1,
                                overflow: TextOverflow.ellipsis,
                                style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w700, color: Colors.black87),
                              ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 8),
                      Text(DateFormat('yyyy-MM-dd').format(s.date), style: const TextStyle(color: Colors.black54, fontSize: 12)),
                    ],
                  ),
                  onTap: () => widget.onEditScore(s),
                ),
              );
            }),
          ],
        );
      }).toList(),
    );
  }

  Widget _buildScoreListItem(BuildContext context, Score score, int rank, Participant participant) {
    return Dismissible(
      key: Key('score_${score.id}'),
      direction: DismissDirection.endToStart,
      background: Container(
        alignment: Alignment.centerRight,
        padding: const EdgeInsets.symmetric(horizontal: 16),
        color: Colors.red,
        child: const Icon(Icons.delete, color: Colors.white),
      ),
      confirmDismiss: (direction) async {
        // confirm handled by parent via onDeleteScore as needed; keep swipe immediate
        return true;
      },
      onDismissed: (_) => widget.onDeleteScore(score),
      child: Card(
        margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
        child: ListTile(
          leading: CircleAvatar(
            backgroundColor: _getRankColor(rank),
            child: Text(
              rank.toString(),
              key: Key('rank_${rank}_text'),
              style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
            ),
          ),
          title: Row(
            children: [
              Expanded(
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Flexible(
                      child: Text(
                        participant.name ?? '알 수 없음',
                        style: const TextStyle(fontWeight: FontWeight.bold),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                    const SizedBox(width: 6),
                    // Small guest badge next to name
                    if ((participant.memberType ?? '').toLowerCase() == 'guest')
                      Padding(
                        padding: const EdgeInsets.only(right: 2),
                        child: BadgeStyles.guestSmall(size: 16),
                      ),
                    Builder(
                      builder: (ctx) {
                        Member? m;
                        try {
                          m = widget.clubMembers.firstWhere((cm) => cm.id == (participant.memberId.isNotEmpty ? participant.memberId : score.memberId));
                        } catch (_) {}
                        final gender = m?.gender?.toLowerCase();
                        IconData? icon;
                        Color color = Colors.grey;
                        if (gender == 'male' || gender == 'm' || gender == '남' || gender == '남성') {
                          icon = Icons.male;
                          color = Colors.blue;
                        } else if (gender == 'female' || gender == 'f' || gender == '여' || gender == '여성') {
                          icon = Icons.female;
                          color = Colors.pink;
                        }
                        if (icon == null) return const SizedBox.shrink();
                        return Icon(icon, size: 16, color: color);
                      },
                    ),
                    if ((score.handicap ?? 0) != 0) ...[
                      const SizedBox(width: 4),
                      Container(
                        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                        decoration: BoxDecoration(color: Colors.indigo.shade100, borderRadius: BorderRadius.circular(12)),
                        child: Text(
                          '+${score.handicap}',
                          style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w600),
                        ),
                      ),
                    ],
                  ],
                ),
              ),
              const SizedBox(width: 6),
              Flexible(
                child: Align(
                  alignment: Alignment.centerRight,
                  child: Builder(
                    builder: (ctx) {
                      final displayedTotal = widget.includeHandicap ? (score.totalScore + (score.handicap ?? 0)) : score.totalScore;
                      final bool isHigh = displayedTotal >= 200;
                      final bg = isHigh ? Colors.red.shade400 : Colors.blue.shade100;
                      final fg = isHigh ? Colors.white : Colors.black87;
                      return Container(
                        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                        decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(12)),
                        child: Text('$displayedTotal', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14, color: fg)),
                      );
                    },
                  ),
                ),
              ),
            ],
          ),
          subtitle: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(height: 4),
              Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text('날짜: ${DateFormat('yyyy-MM-dd').format(score.date)}'),
                ],
              ),
              const SizedBox(height: 4),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  children: score.frames.asMap().entries.map((entry) {
                    return Container(
                      width: 30,
                      height: 30,
                      margin: const EdgeInsets.only(right: 4),
                      decoration: BoxDecoration(color: _getScoreColor(entry.value), borderRadius: BorderRadius.circular(4)),
                      child: Center(
                        child: Text(
                          _getFrameDisplay(entry.key, entry.value, score.frames),
                          style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
            ],
          ),
          onTap: () => widget.onEditScore(score),
        ),
      ),
    );
  }

  // helpers (duplicated from original for isolation)
  Color _getRankColor(int rank) {
    switch (rank) {
      case 1:
        return Colors.amber.shade700;
      case 2:
        return Colors.blueGrey.shade400;
      case 3:
        return Colors.brown.shade400;
      default:
        return Colors.blue.shade700;
    }
  }

  Color _getScoreColor(int score) {
    if (score == 10) return Colors.green;
    if (score == 0) return Colors.red;
    return Colors.blue;
  }

  String _getFrameDisplay(int frameIndex, int score, List<int> frames) {
    if (score == 10) return 'X';
    if (frameIndex > 0 && frames[frameIndex - 1] + score == 10) return '/';
    return score.toString();
  }
}
