import type { DataBlock, DataStage, DataUndo } from "../types/global"
import { DOBlock } from "./DOBlock"
import { LevelManager } from "./LevelManager"
import { StorageManager } from "./StorageManager"

export class DOStage {
  private data: DataStage
  private blocks: Array<DOBlock> = []

  private letterToNumber: Map<string, number>
  private numberToLetter: Map<number, string>

  constructor(dataStage: DataStage) {
    this.data = dataStage

    this.letterToNumber = new Map()
    this.letterToNumber.set("A", 1)
    this.letterToNumber.set("B", 2)
    this.letterToNumber.set("C", 3)
    this.letterToNumber.set("D", 4)
    this.letterToNumber.set("E", 5)
    this.letterToNumber.set("F", 6)
    this.letterToNumber.set("G", 7)
    this.letterToNumber.set("H", 8)
    this.letterToNumber.set("I", 9)

    this.numberToLetter = new Map()
    this.numberToLetter.set(1, "a")
    this.numberToLetter.set(2, "b")
    this.numberToLetter.set(3, "c")
    this.numberToLetter.set(4, "d")
    this.numberToLetter.set(5, "e")
    this.numberToLetter.set(6, "f")
    this.numberToLetter.set(7, "g")
    this.numberToLetter.set(8, "h")
    this.numberToLetter.set(9, "i")

    const blockMap: Map<number, DataBlock> = new Map()
    for (var i = 0; i < this.data.blocks.length; i++) {
      var dataBlock = this.data.blocks[i]
      blockMap.set(dataBlock.index, dataBlock)
    }

    const levelStr = LevelManager.getInstance().getLevelStr(this.data.difficulty, this.data.index)
    if (!levelStr || levelStr.length !== 81) {
      console.log("levelStr error", this.data.difficulty, this.data.index, levelStr)
    }
    const list = new Map()
    for (var i = 0; i < levelStr.length; i++) {
      const letter = levelStr[i]
      if (this.letterToNumber.has(letter)) { // 预设格子 使用配置文件初始化
        var show = this.letterToNumber.get(letter)
        var dataBlock: DataBlock = { index: i, show, score: 0, notes: [] }
        var doBlock = new DOBlock(dataBlock, true, show)
        this.blocks.push(doBlock)
      } else {
        var show = this.letterToNumber.get(letter.toUpperCase())
        var dataBlock = blockMap.get(i)
        if (dataBlock) { // 本地有持久化数据
          var doBlock = new DOBlock(dataBlock, false, show)
          this.blocks.push(doBlock)
        } else {
          dataBlock = { index: i, show: 0, score: 0, notes: [] }
          this.data.blocks.push(dataBlock)
          var doBlock = new DOBlock(dataBlock, false, show)
          this.blocks.push(doBlock)
        }

        if (list.has(letter)) {
          list.set(letter, list.get(letter) + 1)
        } else {
          list.set(letter, 1)
        }
      }
    }
  }

  public getData(): DataStage {
    return this.data
  }

  // ====================================持久化数据
  public get_stageID(): string {
    return this.data.id
  }

  public get_stageType(): number {
    return this.data.type
  }

  public get_stageName(): string {
    return this.data.name
  }

  public get_difficulty(): string {
    return this.data.difficulty
  }

  public get_stageIndex(): number {
    return this.data.index
  }

  public get_mistake(): number {
    return this.data.mistake
  }

  public set_mistake(mistake: number): void {
    this.data.mistake = mistake
    StorageManager.getInstance().onStageChanged()
  }

  public get_score(): number {
    return this.data.score
  }

  public set_score(score: number): void {
    this.data.score = score
    StorageManager.getInstance().onStageChanged()
  }

  public get_duration(): number {
    return this.data.duration
  }

  public set_duration(duration: number): void { // 关卡计时
    this.data.duration = duration
    StorageManager.getInstance().onStageChanged()
  }

  public get_last_hit_time(): number {
    return this.data.last_hit_time
  }

  public set_last_hit_time(last_hit_time: number): void {
    this.data.last_hit_time = last_hit_time
    StorageManager.getInstance().onStageChanged()
  }

  public get_note_open(): boolean {
    return this.data.note_open
  }

  public set_note_open(note_open: boolean): void {
    this.data.note_open = note_open
    StorageManager.getInstance().onStageChanged()
  }

  public get_select_index(): number {
    return this.data.select_index
  }

  public set_select_index(select_index: number): void { // 当前选中
    this.data.select_index = select_index
    StorageManager.getInstance().onStageChanged()
  }

  public get_hint(): number {
    return this.data.hint
  }

  public set_hint(hint: number): void { // 提示
    this.data.hint = hint
    StorageManager.getInstance().onStageChanged()
  }

  public get_undos(): Array<DataUndo> {
    return this.data.undos
  }

  public add_undo(index: number, show: number = 0, notes: Array<number> = []): void {
    let _notes: Array<number>
    if (notes) {
      _notes = []
      for (let i = 0; i < notes.length; i++)
        _notes.push(notes[i])
    }
    const dataUndo: DataUndo = { index, show, notes: _notes }
    console.log("add_undo >>>>>>>>>>>>>>>>>>>>>>>>>>>>", JSON.stringify(dataUndo))
    this.data.undos.push(dataUndo)
    StorageManager.getInstance().onStageChanged()
  }

  public pop_undo(): DataUndo {
    let dataUndo: DataUndo
    if (this.data.undos.length > 0) {
      dataUndo = this.data.undos[this.data.undos.length - 1]
      this.data.undos.splice(this.data.undos.length - 1, 1)
      StorageManager.getInstance().onStageChanged()
    }
    return dataUndo
  }
  // ====================================持久化数据

  public get_blocks(): Array<DOBlock> {
    return this.blocks
  }
}
