import type { GameData, SceneNode, ChapterInfo, Choice, Condition } from '../types'

export class SceneManager {
  private scenes: Record<string, SceneNode> = {}
  private startScene: string = ''
  chapters: ChapterInfo[] = []

  load(data: GameData) {
    this.scenes = data.scenes
    this.startScene = data.startScene
    this.chapters = data.chapters || []
  }

  getScene(id: string): SceneNode | undefined {
    return this.scenes[id]
  }

  getStartScene(): SceneNode {
    const scene = this.scenes[this.startScene]
    if (!scene) throw new Error(`Start scene "${this.startScene}" not found`)
    return scene
  }

  getAllSceneIds(): string[] {
    return Object.keys(this.scenes)
  }

  getScenes(): Record<string, SceneNode> {
    return this.scenes
  }

  getChapterBySceneId(sceneId: string): ChapterInfo | undefined {
    return this.chapters.find((ch) => ch.startScene === sceneId)
  }

  getChapter(chapterId: string): ChapterInfo | undefined {
    return this.chapters.find((ch) => ch.id === chapterId)
  }

  getCandidateTargetIds(scene: SceneNode, evaluateCondition: (conds?: Condition[]) => boolean): string[] {
    const targets: string[] = []

    if (scene.choices) {
      for (const choice of scene.choices) {
        if (!choice.conditions || evaluateCondition(choice.conditions)) {
          if (!targets.includes(choice.targetScene)) {
            targets.push(choice.targetScene)
          }
        }
      }
    }

    if (scene.nextScene && !targets.includes(scene.nextScene)) {
      targets.push(scene.nextScene)
    }

    return targets
  }

  getCandidateSceneIds(scene: SceneNode, evaluateCondition: (conds?: Condition[]) => boolean): string[] {
    return this.getCandidateTargetIds(scene, evaluateCondition)
  }
}
