import 'package:flutter/foundation.dart';

import 'package:asciineverdie/data/game_text_l10n.dart' as game_l10n;
import 'package:asciineverdie/src/core/model/combat_event.dart';
import 'package:asciineverdie/src/core/model/combat_state.dart';
import 'package:asciineverdie/src/features/game/widgets/combat_log.dart';

/// 전투 로그 컨트롤러
///
/// GamePlayScreen에서 추출된 전투 로그 관련 로직 담당:
/// - 로그 엔트리 관리 (최대 50개 유지)
/// - 전투 이벤트 → 로그 메시지 변환
/// - 태스크 변경 시 로그 추가
class CombatLogController extends ChangeNotifier {
  CombatLogController({this.onCombatEvent});

  /// 전투 이벤트 발생 시 호출되는 콜백 (SFX 재생 등에 사용)
  final void Function(CombatEvent event)? onCombatEvent;

  // 로그 엔트리 목록
  final List<CombatLogEntry> _entries = [];

  // 이벤트 처리 추적
  int _lastProcessedEventCount = 0;
  String _lastTaskCaption = '';

  /// 로그 엔트리 목록 (읽기 전용)
  List<CombatLogEntry> get entries => List.unmodifiable(_entries);

  /// 로그 엔트리 추가
  void addLog(String message, CombatLogType type) {
    _entries.add(
      CombatLogEntry(message: message, timestamp: DateTime.now(), type: type),
    );
    // 최대 50개 유지
    if (_entries.length > 50) {
      _entries.removeAt(0);
    }
    notifyListeners();
  }

  /// 태스크 변경 처리
  ///
  /// 새 태스크 시작 시 로그에 추가하고 이벤트 카운터 리셋
  void onTaskChanged(String caption) {
    if (caption.isNotEmpty && caption != _lastTaskCaption) {
      addLog(caption, CombatLogType.normal);
      _lastTaskCaption = caption;
      // 새 태스크 시작 시 이벤트 카운터 리셋
      _lastProcessedEventCount = 0;
    }
  }

  /// 전투 이벤트 처리
  ///
  /// 새 전투 이벤트를 로그로 변환하고 콜백 호출
  void processCombatEvents(CombatState? combat) {
    if (combat == null || !combat.isActive) {
      _lastProcessedEventCount = 0;
      return;
    }

    final events = combat.recentEvents;
    if (events.isEmpty || events.length <= _lastProcessedEventCount) {
      return;
    }

    // 새 이벤트만 처리
    final newEvents = events.skip(_lastProcessedEventCount);
    for (final event in newEvents) {
      final (message, type) = _formatCombatEvent(event);
      addLog(message, type);

      // 오디오 콜백 호출 (SFX 재생)
      onCombatEvent?.call(event);
    }

    _lastProcessedEventCount = events.length;
  }

  /// 레벨업 로그 추가
  void addLevelUpLog(int level) {
    addLog('${game_l10n.uiLevelUp} Lv.$level', CombatLogType.levelUp);
  }

  /// 퀘스트 완료 로그 추가
  void addQuestCompleteLog(String questCaption) {
    addLog(
      game_l10n.uiQuestComplete(questCaption),
      CombatLogType.questComplete,
    );
  }

  /// 전투 이벤트를 메시지와 타입으로 변환
  (String, CombatLogType) _formatCombatEvent(CombatEvent event) {
    final target = event.targetName ?? '';
    // 스킬/포션 이름 번역 (전역 로케일 사용)
    final skillName = event.skillName != null
        ? game_l10n.translateSpell(event.skillName!)
        : '';
    return switch (event.type) {
      CombatEventType.playerAttack =>
        event.isCritical
            ? (
                game_l10n.combatCritical(event.damage, target),
                CombatLogType.critical,
              )
            : (
                game_l10n.combatYouHit(target, event.damage),
                CombatLogType.damage,
              ),
      CombatEventType.monsterAttack => (
        game_l10n.combatMonsterHitsYou(target, event.damage),
        CombatLogType.monsterAttack,
      ),
      CombatEventType.playerEvade => (
        game_l10n.combatYouEvaded(target),
        CombatLogType.evade,
      ),
      CombatEventType.monsterEvade => (
        game_l10n.combatMonsterEvaded(target),
        CombatLogType.evade,
      ),
      CombatEventType.playerBlock => (
        game_l10n.combatBlocked(event.damage),
        CombatLogType.block,
      ),
      CombatEventType.playerParry => (
        game_l10n.combatParried(event.damage),
        CombatLogType.parry,
      ),
      CombatEventType.playerSkill =>
        event.isCritical
            ? (
                game_l10n.combatSkillCritical(skillName, event.damage),
                CombatLogType.critical,
              )
            : (
                game_l10n.combatSkillDamage(skillName, event.damage),
                CombatLogType.skill,
              ),
      CombatEventType.playerHeal => (
        game_l10n.combatSkillHeal(
          skillName.isNotEmpty ? skillName : game_l10n.uiHeal,
          event.healAmount,
        ),
        CombatLogType.heal,
      ),
      CombatEventType.playerBuff => (
        game_l10n.combatBuffActivated(skillName),
        CombatLogType.buff,
      ),
      CombatEventType.playerDebuff => (
        game_l10n.combatDebuffApplied(skillName, target),
        CombatLogType.debuff,
      ),
      CombatEventType.dotTick => (
        game_l10n.combatDotTick(skillName, event.damage),
        CombatLogType.dotTick,
      ),
      CombatEventType.playerPotion => (
        game_l10n.combatPotionUsed(skillName, event.healAmount, target),
        CombatLogType.potion,
      ),
      CombatEventType.potionDrop => (
        game_l10n.combatPotionDrop(skillName),
        CombatLogType.potionDrop,
      ),
    };
  }

  /// 로그 초기화
  void reset() {
    _entries.clear();
    _lastProcessedEventCount = 0;
    _lastTaskCaption = '';
    notifyListeners();
  }
}
