import 'package:flutter/material.dart';

import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
import 'package:asciineverdie/data/skill_data.dart';
import 'package:asciineverdie/l10n/app_localizations.dart';
import 'package:asciineverdie/src/shared/l10n/game_data_l10n.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/skill.dart';
import 'package:asciineverdie/src/features/game/widgets/active_buff_panel.dart';
import 'package:asciineverdie/src/shared/retro_colors.dart';

/// 스킬 페이지 (캐로셀)
///
/// SkillBook 기반 스킬 목록과 활성 버프 표시.
class SkillsPage extends StatelessWidget {
  const SkillsPage({
    super.key,
    required this.skillBook,
    required this.skillSystem,
  });

  final SkillBook skillBook;
  final SkillSystemState skillSystem;

  @override
  Widget build(BuildContext context) {
    final localizations = L10n.of(context);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        // 스킬 목록
        _buildSectionHeader(context, localizations.spellBook),
        Expanded(flex: 3, child: _buildSkillsList(context)),

        // 활성 버프
        _buildSectionHeader(context, l10n.uiBuffs),
        Expanded(
          flex: 2,
          child: ActiveBuffPanel(
            activeBuffs: skillSystem.activeBuffs,
            currentMs: skillSystem.elapsedMs,
          ),
        ),
      ],
    );
  }

  Widget _buildSectionHeader(BuildContext context, String title) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      color: Theme.of(context).colorScheme.primaryContainer,
      child: Text(
        title,
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 18,
          color: Theme.of(context).colorScheme.onPrimaryContainer,
        ),
      ),
    );
  }

  Widget _buildSkillsList(BuildContext context) {
    if (skillBook.skills.isEmpty) {
      return Center(
        child: Text(
          L10n.of(context).noSpellsYet,
          style: const TextStyle(fontSize: 17, color: Colors.grey),
        ),
      );
    }

    return ListView.builder(
      itemCount: skillBook.skills.length,
      padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
      itemBuilder: (context, index) {
        final skillEntry = skillBook.skills[index];
        final skill = SkillData.getSkillBySpellName(skillEntry.name);
        final skillName = GameDataL10n.getSpellName(context, skillEntry.name);

        // 쿨타임 상태 확인
        final skillState = skill != null
            ? skillSystem.getSkillState(skill.id)
            : null;
        final isOnCooldown =
            skillState != null &&
            !skillState.isReady(skillSystem.elapsedMs, skill!.cooldownMs);

        return _SkillTile(
          skillName: skillName,
          rank: skillEntry.rank,
          skill: skill,
          isOnCooldown: isOnCooldown,
        );
      },
    );
  }
}

/// 스킬 타일 위젯 (ExpansionTile 기반)
class _SkillTile extends StatelessWidget {
  const _SkillTile({
    required this.skillName,
    required this.rank,
    required this.skill,
    required this.isOnCooldown,
  });

  final String skillName;
  final String rank;
  final Skill? skill;
  final bool isOnCooldown;

  @override
  Widget build(BuildContext context) {
    // 스킬 데이터가 없으면 단순 행으로 표시
    if (skill == null) {
      return _SimpleSkillRow(
        skillName: skillName,
        rank: rank,
        isOnCooldown: isOnCooldown,
      );
    }

    final typeColor = _getTypeColor(skill!.type);

    return ExpansionTile(
      tilePadding: const EdgeInsets.symmetric(horizontal: 8),
      childrenPadding: const EdgeInsets.only(left: 16, right: 8, bottom: 8),
      dense: true,
      title: Row(
        children: [
          _SkillTypeIcon(type: skill!.type),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              skillName,
              style: TextStyle(
                fontSize: 18,
                color: isOnCooldown ? Colors.grey : typeColor,
                fontWeight: FontWeight.w500,
              ),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          if (isOnCooldown)
            const Padding(
              padding: EdgeInsets.only(right: 8),
              child: Icon(
                Icons.hourglass_empty,
                size: 14,
                color: Colors.orange,
              ),
            ),
          _RankBadge(rank: rank),
        ],
      ),
      children: [
        _SkillStatsGrid(skill: skill!),
        const SizedBox(height: 4),
        _SkillMetaRow(skill: skill!),
      ],
    );
  }

  Color _getTypeColor(SkillType type) {
    return switch (type) {
      SkillType.attack => Colors.red.shade300,
      SkillType.heal => Colors.green.shade300,
      SkillType.buff => Colors.blue.shade300,
      SkillType.debuff => Colors.purple.shade300,
    };
  }
}

/// 스킬 데이터가 없는 경우의 단순 행
class _SimpleSkillRow extends StatelessWidget {
  const _SimpleSkillRow({
    required this.skillName,
    required this.rank,
    required this.isOnCooldown,
  });

  final String skillName;
  final String rank;
  final bool isOnCooldown;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 8),
      child: Row(
        children: [
          const SizedBox(width: 24),
          Expanded(
            child: Text(
              skillName,
              style: TextStyle(
                fontSize: 18,
                color: isOnCooldown ? Colors.grey : null,
              ),
              overflow: TextOverflow.ellipsis,
            ),
          ),
          if (isOnCooldown)
            const Icon(Icons.hourglass_empty, size: 14, color: Colors.orange),
          const SizedBox(width: 8),
          Text(
            rank,
            style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold),
          ),
        ],
      ),
    );
  }
}

/// 스킬 타입 아이콘
class _SkillTypeIcon extends StatelessWidget {
  const _SkillTypeIcon({required this.type});

  final SkillType type;

  @override
  Widget build(BuildContext context) {
    final (IconData icon, Color color) = switch (type) {
      SkillType.attack => (Icons.flash_on, Colors.red),
      SkillType.heal => (Icons.favorite, Colors.green),
      SkillType.buff => (Icons.arrow_upward, Colors.blue),
      SkillType.debuff => (Icons.arrow_downward, Colors.purple),
    };

    return Icon(icon, size: 18, color: color);
  }
}

/// 랭크 배지
class _RankBadge extends StatelessWidget {
  const _RankBadge({required this.rank});

  final String rank;

  @override
  Widget build(BuildContext context) {
    final gold = RetroColors.goldOf(context);
    final surface = RetroColors.surfaceOf(context);

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: surface,
        border: Border.all(color: gold, width: 1),
        borderRadius: BorderRadius.circular(4),
      ),
      child: Text(
        rank,
        style: TextStyle(
          fontSize: 15,
          fontWeight: FontWeight.bold,
          color: gold,
        ),
      ),
    );
  }
}

/// 스킬 스탯 그리드 (타입별 분기)
class _SkillStatsGrid extends StatelessWidget {
  const _SkillStatsGrid({required this.skill});

  final Skill skill;

  @override
  Widget build(BuildContext context) {
    final entries = <_StatEntry>[];

    // 공통: MP, 쿨타임
    entries.add(_StatEntry(l10n.skillMpCost, '${skill.mpCost}'));
    entries.add(
      _StatEntry(
        l10n.skillCooldown,
        '${(skill.cooldownMs / 1000).toStringAsFixed(1)}${l10n.skillSeconds}',
      ),
    );

    // 타입별 스탯 추가
    switch (skill.type) {
      case SkillType.attack:
        _addAttackStats(entries);
      case SkillType.heal:
        _addHealStats(entries);
      case SkillType.buff:
        _addBuffStats(entries);
      case SkillType.debuff:
        _addDebuffStats(entries);
    }

    return Wrap(
      spacing: 8,
      runSpacing: 4,
      children: entries.map((e) => _StatChip(entry: e)).toList(),
    );
  }

  void _addAttackStats(List<_StatEntry> entries) {
    // 위력 (power × multiplier)
    final power = (skill.power * skill.damageMultiplier).round();
    entries.add(_StatEntry(l10n.skillPower, '$power'));

    // 타격 횟수 (1보다 클 때만)
    if (skill.hitCount > 1) {
      entries.add(_StatEntry(l10n.skillHits, '${skill.hitCount}'));
    }

    // DOT 정보
    if (skill.isDot && skill.baseDotDamage != null) {
      final dotDps =
          skill.baseDotDamage! *
          (skill.baseDotDurationMs! / skill.baseDotTickMs!);
      entries.add(_StatEntry(l10n.skillDot, '${dotDps.round()}'));
    }

    // HP 흡수
    if (skill.lifestealPercent > 0) {
      entries.add(
        _StatEntry(
          l10n.skillLifesteal,
          '${(skill.lifestealPercent * 100).round()}%',
        ),
      );
    }

    // 방어 무시
    if (skill.targetDefReduction > 0) {
      entries.add(
        _StatEntry(
          l10n.skillDefPen,
          '${(skill.targetDefReduction * 100).round()}%',
        ),
      );
    }

    // 자해 데미지
    if (skill.selfDamagePercent > 0) {
      entries.add(
        _StatEntry(
          l10n.skillSelfDmg,
          '${(skill.selfDamagePercent * 100).round()}%',
        ),
      );
    }
  }

  void _addHealStats(List<_StatEntry> entries) {
    // 고정 회복
    if (skill.healAmount > 0) {
      entries.add(_StatEntry(l10n.skillHealFixed, '+${skill.healAmount}'));
    }

    // % 회복
    if (skill.healPercent > 0) {
      entries.add(
        _StatEntry(
          l10n.skillHealPercent,
          '${(skill.healPercent * 100).round()}%',
        ),
      );
    }

    // MP 회복
    if (skill.mpHealAmount > 0) {
      entries.add(_StatEntry(l10n.skillMpHeal, '+${skill.mpHealAmount}'));
    }

    // 부가 버프
    if (skill.buff != null) {
      final buff = skill.buff!;
      entries.add(
        _StatEntry(
          l10n.skillBuffDuration,
          '${(buff.durationMs / 1000).round()}${l10n.skillSeconds}',
        ),
      );
    }
  }

  void _addBuffStats(List<_StatEntry> entries) {
    if (skill.buff == null) return;
    final buff = skill.buff!;

    // 지속시간
    entries.add(
      _StatEntry(
        l10n.skillBuffDuration,
        '${(buff.durationMs / 1000).round()}${l10n.skillSeconds}',
      ),
    );

    // 각 보정치
    if (buff.atkModifier != 0) {
      final sign = buff.atkModifier > 0 ? '+' : '';
      entries.add(
        _StatEntry(
          l10n.skillAtkMod,
          '$sign${(buff.atkModifier * 100).round()}%',
        ),
      );
    }
    if (buff.defModifier != 0) {
      final sign = buff.defModifier > 0 ? '+' : '';
      entries.add(
        _StatEntry(
          l10n.skillDefMod,
          '$sign${(buff.defModifier * 100).round()}%',
        ),
      );
    }
    if (buff.criRateModifier != 0) {
      final sign = buff.criRateModifier > 0 ? '+' : '';
      entries.add(
        _StatEntry(
          l10n.skillCriMod,
          '$sign${(buff.criRateModifier * 100).round()}%',
        ),
      );
    }
    if (buff.evasionModifier != 0) {
      final sign = buff.evasionModifier > 0 ? '+' : '';
      entries.add(
        _StatEntry(
          l10n.skillEvaMod,
          '$sign${(buff.evasionModifier * 100).round()}%',
        ),
      );
    }
  }

  void _addDebuffStats(List<_StatEntry> entries) {
    if (skill.buff == null) return;
    final buff = skill.buff!;

    // 지속시간
    entries.add(
      _StatEntry(
        l10n.skillBuffDuration,
        '${(buff.durationMs / 1000).round()}${l10n.skillSeconds}',
      ),
    );

    // 디버프 효과 (보통 음수)
    if (buff.atkModifier != 0) {
      entries.add(
        _StatEntry(l10n.skillAtkMod, '${(buff.atkModifier * 100).round()}%'),
      );
    }
    if (buff.defModifier != 0) {
      entries.add(
        _StatEntry(l10n.skillDefMod, '${(buff.defModifier * 100).round()}%'),
      );
    }
  }
}

/// 스탯 엔트리
class _StatEntry {
  const _StatEntry(this.label, this.value);
  final String label;
  final String value;
}

/// 스탯 칩 (레트로 스타일)
class _StatChip extends StatelessWidget {
  const _StatChip({required this.entry});

  final _StatEntry entry;

  @override
  Widget build(BuildContext context) {
    final surface = RetroColors.surfaceOf(context);
    final border = RetroColors.borderOf(context);
    final textMuted = RetroColors.textMutedOf(context);
    final textPrimary = RetroColors.textPrimaryOf(context);

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
      decoration: BoxDecoration(
        color: surface,
        border: Border.all(color: border, width: 1),
        borderRadius: BorderRadius.circular(2),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            '${entry.label}: ',
            style: TextStyle(fontSize: 15, color: textMuted),
          ),
          Text(
            entry.value,
            style: TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.bold,
              color: textPrimary,
            ),
          ),
        ],
      ),
    );
  }
}

/// 스킬 메타 정보 행
class _SkillMetaRow extends StatelessWidget {
  const _SkillMetaRow({required this.skill});

  final Skill skill;

  @override
  Widget build(BuildContext context) {
    final textMuted = RetroColors.textMutedOf(context);
    final typeColor = _getTypeColor(skill.type);

    return Row(
      children: [
        // 티어
        Text(
          '${l10n.skillTier} ${_tierToRoman(skill.tier)}',
          style: TextStyle(fontSize: 15, color: textMuted),
        ),
        const SizedBox(width: 8),
        // 타입
        Text(
          _getTypeName(skill.type),
          style: TextStyle(
            fontSize: 15,
            color: typeColor,
            fontWeight: FontWeight.bold,
          ),
        ),
        // 속성 (있는 경우)
        if (skill.element != null) ...[
          const SizedBox(width: 8),
          Text(
            _getElementName(skill.element!),
            style: TextStyle(
              fontSize: 15,
              color: _getElementColor(skill.element!),
              fontWeight: FontWeight.w500,
            ),
          ),
        ],
      ],
    );
  }

  Color _getTypeColor(SkillType type) {
    return switch (type) {
      SkillType.attack => Colors.red,
      SkillType.heal => Colors.green,
      SkillType.buff => Colors.blue,
      SkillType.debuff => Colors.purple,
    };
  }

  Color _getElementColor(SkillElement element) {
    return switch (element) {
      SkillElement.logic => Colors.cyan,
      SkillElement.memory => Colors.teal,
      SkillElement.network => Colors.indigo,
      SkillElement.fire => Colors.orange,
      SkillElement.ice => Colors.lightBlue,
      SkillElement.lightning => Colors.yellow.shade700,
      SkillElement.voidElement => Colors.grey,
      SkillElement.chaos => Colors.pink,
    };
  }

  String _tierToRoman(int tier) {
    return switch (tier) {
      1 => 'I',
      2 => 'II',
      3 => 'III',
      4 => 'IV',
      5 => 'V',
      _ => '$tier',
    };
  }

  String _getTypeName(SkillType type) {
    return switch (type) {
      SkillType.attack => l10n.skillTypeAttack,
      SkillType.heal => l10n.skillTypeHeal,
      SkillType.buff => l10n.skillTypeBuff,
      SkillType.debuff => l10n.skillTypeDebuff,
    };
  }

  String _getElementName(SkillElement element) {
    return switch (element) {
      SkillElement.logic => l10n.elementLogic,
      SkillElement.memory => l10n.elementMemory,
      SkillElement.network => l10n.elementNetwork,
      SkillElement.fire => l10n.elementFire,
      SkillElement.ice => l10n.elementIce,
      SkillElement.lightning => l10n.elementLightning,
      SkillElement.voidElement => l10n.elementVoid,
      SkillElement.chaos => l10n.elementChaos,
    };
  }
}
