import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lanebow/theme/badges.dart';
import 'package:lanebow/utils/enum_mappings.dart';

class PublicUserNameRow extends StatelessWidget {
  final String name;
  final String? gender;
  final String? memberType;
  final int? userHandicap;
  final num? userAverage;
  final int? rank; // 1: 금, 2: 은, 3: 동

  const PublicUserNameRow({
    super.key,
    required this.name,
    this.gender,
    this.memberType,
    this.userHandicap,
    this.userAverage,
    this.rank,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        if (rank != null) ...[_rankBadge(rank!), const SizedBox(width: 6)],
        Expanded(
          child: RichText(
            text: TextSpan(
              style: const TextStyle(
                fontWeight: FontWeight.bold,
                color: Colors
                    .black, // DefaultTextStyle.of(context).style.color 사용도 가능
              ),
              children: [
                TextSpan(text: name),
                const WidgetSpan(child: SizedBox(width: 4)), // 이름-아이콘 간격
                WidgetSpan(
                  alignment: PlaceholderAlignment.middle, // 베이스라인 정렬
                  child: _genderIcon(gender),
                ),
              ],
            ),
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
        ),
        const SizedBox(width: 6),
        _hcBadge(userHandicap),
        if (userAverage != null) ...[
          const SizedBox(width: 4),
          _avgBadge(userAverage),
        ],
      ],
    );
  }

  Widget _genderIcon(String? gender) {
    final g = (gender ?? '').toLowerCase();
    final isFemale = g == 'female' || g == 'f' || g == '여' || g == '여성';
    final icon = isFemale ? Icons.female : Icons.male;
    final color = isFemale ? Colors.pink : Colors.blue;
    return CircleAvatar(
      radius: 10,
      backgroundColor: color.withOpacity(0.1),
      child: Icon(icon, size: 14, color: color),
    );
  }

  Widget _avgBadge(num? avg) {
    if (avg == null) return const SizedBox.shrink();
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Colors.indigo.withOpacity(0.10),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.indigo.withOpacity(0.25)),
      ),
      child: Text(
        (avg is double ? avg : avg.toDouble()).toStringAsFixed(1),
        style: const TextStyle(
          fontSize: 11,
          fontWeight: FontWeight.w600,
          color: Colors.indigo,
        ),
      ),
    );
  }

  Widget _hcBadge(int? hc) {
    if (hc == null || hc == 0) return const SizedBox.shrink();
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Colors.deepPurple.withOpacity(0.10),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.deepPurple.withOpacity(0.25)),
      ),
      child: Text(
        hc > 0 ? '+$hc' : '$hc',
        style: const TextStyle(
          fontSize: 11,
          fontWeight: FontWeight.w600,
          color: Colors.deepPurple,
        ),
      ),
    );
  }

  Widget _rankBadge(int r) {
    String label;
    Color bg;
    Color fg = Colors.black87;
    if (r == 1) {
      label = r.toString();
      bg = Colors.amber.shade200;
    } else if (r == 2) {
      label = r.toString();
      bg = Colors.blueGrey.shade200;
    } else if (r == 3) {
      label = r.toString();
      bg = Colors.brown.shade200;
    } else {
      label = r.toString();
      bg = Colors.grey.shade300;
    }
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Text(
        label,
        style: TextStyle(fontSize: 11, fontWeight: FontWeight.w700, color: fg),
      ),
    );
  }
}

class PublicUserGameEditors extends StatelessWidget {
  final int gameCount;
  final String participantId;
  final List<int?> rawScores;
  final List<int> handicaps;
  final bool enabled;
  final String Function(String pid, int gameNumber) keyFor;
  final Widget Function(String key) stateIcon;
  final void Function(int gameNumber, int value) onScoreChanged;
  final void Function(int gameNumber, int value) onHandicapChanged;
  final double? eventAverage; // optional, to show at right
  final int? memberHandicap; // optional default per-game handicap

  const PublicUserGameEditors({
    super.key,
    required this.gameCount,
    required this.participantId,
    required this.rawScores,
    required this.handicaps,
    required this.enabled,
    required this.keyFor,
    required this.stateIcon,
    required this.onScoreChanged,
    required this.onHandicapChanged,
    this.eventAverage,
    this.memberHandicap,
  });

  bool _hasRaw(int g) =>
      (g - 1 >= 0 && g - 1 < rawScores.length && rawScores[g - 1] != null);
  int _rawAt(int g) => _hasRaw(g) ? rawScores[g - 1]! : 0;
  int _hcAt(int g) {
    int hv = (g - 1 >= 0 && g - 1 < handicaps.length) ? handicaps[g - 1] : 0;
    if (hv == 0 && (memberHandicap ?? 0) != 0) return memberHandicap!;
    return hv;
  }

  int _overallRawTotal() {
    int s = 0;
    for (int g = 1; g <= gameCount; g++) {
      if (_hasRaw(g)) s += _rawAt(g);
    }
    return s;
  }

  double? _avgRaw() {
    int count = 0;
    int sum = 0;
    for (int g = 1; g <= gameCount; g++) {
      if (_hasRaw(g)) {
        sum += _rawAt(g);
        count++;
      }
    }
    if (count == 0) return null;
    return sum / count;
  }


  bool _hasAnyPerGameHandicap() {
    // Consider effective handicap (per-game or member fallback)
    for (int g = 1; g <= gameCount; g++) {
      if (_hcAt(g) != 0) return true;
    }
    return false;
  }

  int _totalWithPerGameHcAt(int g) {
    if (!_hasRaw(g)) return 0;
    // Use effective handicap (includes memberHandicap fallback)
    return _rawAt(g) + _hcAt(g);
  }

  int _overallWithPerGameHcTotal() {
    int s = 0;
    for (int g = 1; g <= gameCount; g++) {
      if (_hasRaw(g)) s += _totalWithPerGameHcAt(g);
    }
    return s;
  }

  double? _avgWithPerGameHc() {
    int count = 0;
    int sum = 0;
    for (int g = 1; g <= gameCount; g++) {
      if (_hasRaw(g)) {
        sum += _totalWithPerGameHcAt(g);
        count++;
      }
    }
    if (count == 0) return null;
    return sum / count;
  }

  Color _valueColor(num v) => v >= 200 ? Colors.red : Colors.black87;

  int _playedGames() {
    int c = 0;
    for (int g = 1; g <= gameCount; g++) {
      if (_hasRaw(g)) c++;
    }
    return c;
  }

  Color _totalColor(int total) {
    final n = _playedGames();
    if (n <= 0) return Colors.blueGrey;
    final thresh = 200 * n;
    return total >= thresh ? Colors.red : Colors.blueGrey;
  }

  @override
  Widget build(BuildContext context) {
    if (!enabled) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Flexible(
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Row(
                    children: [
                      for (int g = 1; g <= gameCount; g++)
                        Padding(
                          padding: const EdgeInsets.only(right: 6),
                          child: SizedBox(
                            width: 60,
                            child: Column(
                              children: [
                                Container(
                                  padding: const EdgeInsets.symmetric(
                                    vertical: 2,
                                  ),
                                  alignment: Alignment.center,
                                  child: Text(
                                    _hasRaw(g) ? _rawAt(g).toString() : '',
                                    style: TextStyle(
                                      fontSize: _hcAt(g) != 0 ? 11 : 17,
                                      fontWeight: _hcAt(g) != 0
                                          ? FontWeight.w300
                                          : FontWeight.w700,
                                      color: _valueColor(_rawAt(g)),
                                    ),
                                  ),
                                ),
                                // tighter spacing between raw and handicap
                                if (_hcAt(g) != 0)
                                  Text(
                                    (_hcAt(g) > 0
                                        ? '+${_hcAt(g)}'
                                        : _hcAt(g).toString()),
                                    style: const TextStyle(
                                      fontSize: 11,
                                      color: Colors.black54,
                                      height: 1.0,
                                    ),
                                  ),
                                if (_hcAt(g) != 0) ...[
                                  Align(
                                    alignment: Alignment.centerRight,
                                    child: Transform.rotate(
                                      angle: -0.2,
                                      child: Container(
                                        width: 40,
                                        height: 1,
                                        color: Colors.black26,
                                      ),
                                    ),
                                  ),
                                  Align(
                                    alignment: Alignment.centerRight,
                                    child: Text(
                                      _totalWithPerGameHcAt(g).toString(),
                                      style: TextStyle(
                                        fontSize: 17,
                                        fontWeight: FontWeight.w700,
                                        color: _valueColor(
                                          _totalWithPerGameHcAt(g),
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ],
                            ),
                          ),
                        ),
                    ],
                  ),
                ),
              ),
              const SizedBox(width: 4),
              Align(
                alignment: Alignment.topRight,
                child: IntrinsicWidth(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 8,
                          vertical: 4,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.blueGrey.withOpacity(0.10),
                          border: Border.all(
                            color: Colors.blueGrey.withOpacity(0.25),
                          ),
                          borderRadius: BorderRadius.circular(12),
                        ),
                        child: Builder(
                          builder: (context) {
                            final hasGameHc = _hasAnyPerGameHandicap();
                            final raw = _overallRawTotal();
                            if (hasGameHc) {
                              final withHc = _overallWithPerGameHcTotal();
                              if (withHc != raw) {
                                return Text(
                                  '$raw ($withHc)',
                                  style: TextStyle(
                                    fontSize: 13,
                                    fontWeight: FontWeight.w600,
                                    color: _totalColor(withHc),
                                  ),
                                );
                              }
                            }
                            return Text(
                              '$raw',
                              style: TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.w600,
                                color: _totalColor(raw),
                              ),
                            );
                          },
                        ),
                      ),
                      const SizedBox(height: 6),
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 8,
                          vertical: 4,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.indigo.withOpacity(0.10),
                          border: Border.all(
                            color: Colors.indigo.withOpacity(0.25),
                          ),
                          borderRadius: BorderRadius.circular(12),
                        ),
                        child: Builder(
                          builder: (context) {
                            final hasGameHc = _hasAnyPerGameHandicap();
                            final rawAvg = (eventAverage ?? _avgRaw() ?? 0)
                                .toStringAsFixed(1);
                            if (hasGameHc) {
                              final withHcAvg = (_avgWithPerGameHc() ?? 0)
                                  .toStringAsFixed(1);
                              if (withHcAvg != rawAvg) {
                                return Text(
                                  '$rawAvg ($withHcAvg)',
                                  style: TextStyle(
                                    fontSize: 13,
                                    fontWeight: FontWeight.w600,
                                    color: _valueColor(
                                      double.tryParse(withHcAvg) ?? 0,
                                    ),
                                  ),
                                );
                              }
                            }
                            return Text(
                              rawAvg,
                              style: TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.w600,
                                color: _valueColor(
                                  double.tryParse(rawAvg) ?? 0,
                                ),
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ],
      );
    }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Flexible(
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  children: [
                    for (int g = 1; g <= gameCount; g++)
                      Padding(
                        padding: const EdgeInsets.only(right: 6),
                        child: SizedBox(
                          width: 60,
                          child: Column(
                            children: [
                              Stack(
                                clipBehavior: Clip.none,
                                children: [
                                  TextFormField(
                                    key: Key(
                                      'cell_${participantId}_${g}_${_rawAt(g)}',
                                    ),
                                    initialValue:
                                        (g - 1 < rawScores.length &&
                                            rawScores[g - 1] != null)
                                        ? rawScores[g - 1].toString()
                                        : '',
                                    keyboardType: TextInputType.number,
                                    style: TextStyle(
                                      fontSize: _hcAt(g) != 0 ? 12 : 14,
                                      fontWeight: FontWeight.w600,
                                      color: _valueColor(_rawAt(g)),
                                    ),
                                    decoration: InputDecoration(
                                      isDense: true,
                                      labelText: '${g}G 점수',
                                      floatingLabelBehavior:
                                          FloatingLabelBehavior.auto,
                                      labelStyle: const TextStyle(fontSize: 10),
                                      floatingLabelStyle: const TextStyle(
                                        fontSize: 10,
                                      ),
                                      hintText: '${g}G 점수',
                                      hintStyle: const TextStyle(fontSize: 9),
                                      counterText: '',
                                      contentPadding:
                                          const EdgeInsets.symmetric(
                                            vertical: 6,
                                            horizontal: 8,
                                          ),
                                    ),
                                    maxLength: 3,
                                    inputFormatters: [
                                      FilteringTextInputFormatter.digitsOnly,
                                    ],
                                    enabled: enabled,
                                    onChanged: (v) {
                                      if (v.isEmpty) {
                                        onScoreChanged(g, 0);
                                        return;
                                      }
                                      final val = int.tryParse(v);
                                      if (val != null &&
                                          val >= 0 &&
                                          val <= 300) {
                                        onScoreChanged(g, val);
                                      }
                                    },
                                  ),
                                  Positioned(
                                    top: -8,
                                    right: -8,
                                    child: IgnorePointer(
                                      child: stateIcon(
                                        keyFor(participantId, g),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                              const SizedBox(height: 4),
                              TextFormField(
                                key: Key(
                                  'cell_hc_${participantId}_${g}_${_hcAt(g)}',
                                ),
                                initialValue: (() {
                                  int hv = (g - 1 < handicaps.length)
                                      ? handicaps[g - 1]
                                      : 0;
                                  if (hv == 0 && (memberHandicap ?? 0) != 0) {
                                    return memberHandicap!.toString();
                                  }
                                  return hv.toString();
                                })(),
                                keyboardType: TextInputType.number,
                                decoration: InputDecoration(
                                  isDense: true,
                                  labelText: '${g}G 핸디캡',
                                  floatingLabelBehavior:
                                      FloatingLabelBehavior.auto,
                                  labelStyle: const TextStyle(fontSize: 10),
                                  floatingLabelStyle: const TextStyle(
                                    fontSize: 10,
                                  ),
                                  hintText: '${g}G 핸디캡',
                                  hintStyle: const TextStyle(fontSize: 9),
                                  counterText: '',
                                  contentPadding: const EdgeInsets.symmetric(
                                    vertical: 4,
                                    horizontal: 8,
                                  ),
                                ),
                                maxLength: 3,
                                inputFormatters: [
                                  FilteringTextInputFormatter.digitsOnly,
                                ],
                                enabled: enabled,
                                onChanged: (v) {
                                  if (v.isEmpty) {
                                    onHandicapChanged(g, 0);
                                    return;
                                  }
                                  final val = int.tryParse(v);
                                  if (val != null && val >= 0 && val <= 100) {
                                    onHandicapChanged(g, val);
                                  }
                                },
                              ),
                              const SizedBox(height: 2),
                              if (_hcAt(g) != 0) ...[
                                Align(
                                  alignment: Alignment.centerRight,
                                  child: Transform.rotate(
                                    angle: -0.2,
                                    child: Container(
                                      width: 40,
                                      height: 1,
                                      color: Colors.black26,
                                    ),
                                  ),
                                ),
                                Align(
                                  alignment: Alignment.centerRight,
                                  child: Text(
                                    _totalWithPerGameHcAt(g).toString(),
                                    style: TextStyle(
                                      fontSize: 16,
                                      fontWeight: FontWeight.w700,
                                      color: _valueColor(
                                        _totalWithPerGameHcAt(g),
                                      ),
                                    ),
                                  ),
                                ),
                              ],
                            ],
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
            const SizedBox(width: 4),
            Align(
              alignment: Alignment.topRight,
              child: IntrinsicWidth(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 8,
                        vertical: 4,
                      ),
                      decoration: BoxDecoration(
                        color: Colors.blueGrey.withOpacity(0.10),
                        border: Border.all(
                          color: Colors.blueGrey.withOpacity(0.25),
                        ),
                        borderRadius: BorderRadius.circular(12),
                      ),
                      child: Builder(
                        builder: (context) {
                          final hasGameHc = _hasAnyPerGameHandicap();
                          final raw = _overallRawTotal();
                          if (hasGameHc) {
                            final withHc = _overallWithPerGameHcTotal();
                            if (withHc != raw) {
                              return Text(
                                '$raw ($withHc)',
                                style: TextStyle(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w600,
                                  color: _totalColor(withHc),
                                ),
                              );
                            }
                          }
                          return Text(
                            '$raw',
                            style: TextStyle(
                              fontSize: 12,
                              fontWeight: FontWeight.w600,
                              color: _totalColor(raw),
                            ),
                          );
                        },
                      ),
                    ),
                    const SizedBox(height: 6),
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 8,
                        vertical: 4,
                      ),
                      decoration: BoxDecoration(
                        color: Colors.indigo.withOpacity(0.10),
                        border: Border.all(
                          color: Colors.indigo.withOpacity(0.25),
                        ),
                        borderRadius: BorderRadius.circular(12),
                      ),
                      child: Builder(
                        builder: (context) {
                          final hasGameHc = _hasAnyPerGameHandicap();
                          final rawAvg = (eventAverage ?? _avgRaw() ?? 0)
                              .toStringAsFixed(1);
                          if (hasGameHc) {
                            final withHcAvg = (_avgWithPerGameHc() ?? 0)
                                .toStringAsFixed(1);
                            if (withHcAvg != rawAvg) {
                              return Text(
                                '$rawAvg ($withHcAvg)',
                                style: TextStyle(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w600,
                                  color: _valueColor(
                                    double.tryParse(withHcAvg) ?? 0,
                                  ),
                                ),
                              );
                            }
                          }
                          return Text(
                            rawAvg,
                            style: TextStyle(
                              fontSize: 12,
                              fontWeight: FontWeight.w600,
                              color: _valueColor(double.tryParse(rawAvg) ?? 0),
                            ),
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

class PublicUserChipsRow extends StatelessWidget {
  final String? status;
  final String? paymentStatus;
  final String? memberType;

  const PublicUserChipsRow({
    super.key,
    this.status,
    this.paymentStatus,
    this.memberType,
  });

  bool _isPaid(String? paymentStatus) {
    final s = (paymentStatus ?? '').toLowerCase();
    return s == 'paid' || s == '납부' || s == '납부완료' || s == '완납';
  }

  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 6,
      runSpacing: 6,
      children: [
        BadgeStyles.participantStatus(toKoreanParticipantStatus(status)),
        if ((paymentStatus ?? '').isNotEmpty)
          BadgeStyles.payment(_isPaid(paymentStatus)),
        if ((memberType ?? '').isNotEmpty)
          BadgeStyles.memberType(getMemberTypeLabel(memberType)),
      ],
    );
  }
}
