import 'package:asciineverdie/src/core/model/combat_state.dart';
import 'package:asciineverdie/src/core/model/task_info.dart';

/// 진행 바 상태 (Progress Bar State)
class ProgressBarState {
  const ProgressBarState({required this.position, required this.max});

  final int position;
  final int max;

  factory ProgressBarState.empty() =>
      const ProgressBarState(position: 0, max: 1);

  ProgressBarState copyWith({int? position, int? max}) {
    return ProgressBarState(
      position: position ?? this.position,
      max: max ?? this.max,
    );
  }
}

/// 히스토리 엔트리 (Plot/Quest 진행 기록)
class HistoryEntry {
  const HistoryEntry({required this.caption, required this.isComplete});

  /// 표시 텍스트 (예: "Prologue", "Act I", "Exterminate the Goblins")
  final String caption;

  /// 완료 여부 (원본 StateIndex: 0=진행중, 1=완료)
  final bool isComplete;

  HistoryEntry copyWith({String? caption, bool? isComplete}) {
    return HistoryEntry(
      caption: caption ?? this.caption,
      isComplete: isComplete ?? this.isComplete,
    );
  }
}

/// 현재 퀘스트 몬스터 정보 (원본 fQuest)
class QuestMonsterInfo {
  const QuestMonsterInfo({
    required this.monsterData,
    required this.monsterIndex,
  });

  /// 몬스터 데이터 문자열 (예: "Goblin|3|ear")
  final String monsterData;

  /// 몬스터 인덱스 (Config.monsters에서의 인덱스)
  final int monsterIndex;

  static const empty = QuestMonsterInfo(monsterData: '', monsterIndex: -1);
}

/// 최종 보스 상태 (Final Boss State)
enum FinalBossState {
  /// 최종 보스 등장 전
  notSpawned,

  /// 최종 보스 전투 중
  fighting,

  /// 최종 보스 처치 완료
  defeated,
}

/// 진행 상태 (Progress State)
///
/// 태스크, 퀘스트, 플롯, 경험치, 무게 등의 진행 상태를 관리
class ProgressState {
  const ProgressState({
    required this.task,
    required this.quest,
    required this.plot,
    required this.exp,
    required this.encumbrance,
    required this.currentTask,
    required this.plotStageCount,
    required this.questCount,
    this.plotHistory = const [],
    this.questHistory = const [],
    this.currentQuestMonster,
    this.currentCombat,
    this.monstersKilled = 0,
    this.deathCount = 0,
    this.finalBossState = FinalBossState.notSpawned,
    this.pendingActCompletion = false,
    this.bossLevelingEndTime,
  });

  final ProgressBarState task;
  final ProgressBarState quest;
  final ProgressBarState plot;
  final ProgressBarState exp;
  final ProgressBarState encumbrance;
  final TaskInfo currentTask;
  final int plotStageCount;
  final int questCount;

  /// 플롯 히스토리 (Prologue, Act I, Act II, ...)
  final List<HistoryEntry> plotHistory;

  /// 퀘스트 히스토리 (완료된/진행중인 퀘스트 목록)
  final List<HistoryEntry> questHistory;

  /// 현재 퀘스트 몬스터 정보 (Exterminate 타입용)
  final QuestMonsterInfo? currentQuestMonster;

  /// 현재 전투 상태 (킬 태스크 진행 중)
  final CombatState? currentCombat;

  /// 처치한 몬스터 수
  final int monstersKilled;

  /// 사망 횟수
  final int deathCount;

  /// 최종 보스 상태 (Act V)
  final FinalBossState finalBossState;

  /// Act Boss 처치 대기 중 여부 (처치 후 시네마틱 재생 트리거)
  final bool pendingActCompletion;

  /// 보스 사망 후 레벨링 모드 종료 시간 (milliseconds since epoch)
  /// null이면 레벨링 모드 아님, 값이 있으면 해당 시간까지 레벨링
  final int? bossLevelingEndTime;

  factory ProgressState.empty() => ProgressState(
    task: ProgressBarState.empty(),
    quest: ProgressBarState.empty(),
    plot: ProgressBarState.empty(),
    exp: ProgressBarState.empty(),
    encumbrance: ProgressBarState.empty(),
    currentTask: TaskInfo.empty(),
    plotStageCount: 1, // Prologue
    questCount: 0,
    plotHistory: const [HistoryEntry(caption: 'Prologue', isComplete: false)],
    questHistory: const [],
    currentQuestMonster: null,
    currentCombat: null,
  );

  ProgressState copyWith({
    ProgressBarState? task,
    ProgressBarState? quest,
    ProgressBarState? plot,
    ProgressBarState? exp,
    ProgressBarState? encumbrance,
    TaskInfo? currentTask,
    int? plotStageCount,
    int? questCount,
    List<HistoryEntry>? plotHistory,
    List<HistoryEntry>? questHistory,
    QuestMonsterInfo? currentQuestMonster,
    CombatState? currentCombat,
    int? monstersKilled,
    int? deathCount,
    FinalBossState? finalBossState,
    bool? pendingActCompletion,
    int? bossLevelingEndTime,
    bool clearBossLevelingEndTime = false,
    bool clearCurrentCombat = false,
  }) {
    return ProgressState(
      task: task ?? this.task,
      quest: quest ?? this.quest,
      plot: plot ?? this.plot,
      exp: exp ?? this.exp,
      encumbrance: encumbrance ?? this.encumbrance,
      currentTask: currentTask ?? this.currentTask,
      plotStageCount: plotStageCount ?? this.plotStageCount,
      questCount: questCount ?? this.questCount,
      plotHistory: plotHistory ?? this.plotHistory,
      questHistory: questHistory ?? this.questHistory,
      currentQuestMonster: currentQuestMonster ?? this.currentQuestMonster,
      currentCombat: clearCurrentCombat
          ? null
          : (currentCombat ?? this.currentCombat),
      monstersKilled: monstersKilled ?? this.monstersKilled,
      deathCount: deathCount ?? this.deathCount,
      finalBossState: finalBossState ?? this.finalBossState,
      pendingActCompletion: pendingActCompletion ?? this.pendingActCompletion,
      bossLevelingEndTime: clearBossLevelingEndTime
          ? null
          : (bossLevelingEndTime ?? this.bossLevelingEndTime),
    );
  }

  /// 현재 레벨링 모드인지 확인
  bool get isInBossLevelingMode {
    if (bossLevelingEndTime == null) return false;
    return DateTime.now().millisecondsSinceEpoch < bossLevelingEndTime!;
  }
}
