import type { DataStage } from "../types/global"
import { config } from "../constants/config"
import { createDataStage } from "../types/global"
import { DOStage } from "./DOStage"
import { DOUser } from "./DOUser"
import { LevelManager } from "./LevelManager"

export class StorageManager {
  private static instance: StorageManager
  public static getInstance(): StorageManager {
    if (!StorageManager.instance) {
      StorageManager.instance = new StorageManager()
    }
    return StorageManager.instance
  }

  private user: DOUser
  private userChanged = false

  private stageID: string = ""
  private stageChanged = false
  private stageMap: Map<string, DOStage> = new Map()

  public init(): void {
    if (!this.user) {
      const jsonStr = Laya.LocalStorage.getItem("user")
      if (jsonStr) {
        this.user = new DOUser(JSON.parse(jsonStr))
      } else {
        this.user = new DOUser({ dones: [], trophy_records: [], progresses: [] })
      }
    }
    this.userChanged = false

    this.stageID = ""
    this.stageChanged = false
  }

  public getUser(): DOUser {
    return this.user
  }

  public saveUser(): void {
    if (this.userChanged) {
      this.userChanged = false
      if (this.user) {
        const jsonStr = JSON.stringify(this.user.getData())
        Laya.LocalStorage.setItem("user", jsonStr)
      }
    }
  }

  public onUserChanged(): void {
    this.userChanged = true
  }

  public newStage(stageID: string, type: number, name: string, difficulty: string = config.DIFFICULTY_TYPE.Easy): DOStage {
    this.stageID = stageID
    this.stageChanged = true

    let index
    if (type === config.STAGE_TYPE.MAIN) { // 主线关卡
      index = this.user.get_progress(difficulty)
      const levelStr = LevelManager.getInstance().getLevelStr(difficulty, index)
      if (!levelStr || levelStr.length <= 0) { // 说明当前难度已经打通了，所以给他从头开始
        index = 0
        this.user.update_progress(difficulty, index)
      }
    } else if (type === config.STAGE_TYPE.DC) { // 每天调整如果已经创建过关卡那么就用之前的关卡配置
      const value = this.getStage(stageID)
      if (value) {
        difficulty = value.get_difficulty()
        index = value.get_stageIndex()
      } else {
        let random = Math.random()
        difficulty = config.DIFFICULTY_LIST[Math.floor(random * config.DIFFICULTY_LIST.length)]
        const list = LevelManager.getInstance().getLevelList(difficulty)
        random = Math.random()
        index = Math.floor(random * list.length)
        console.log("每日挑战随机一个关卡", difficulty, index)
      }
    }

    this.user.update_stage_done(this.stageID, 0)// 重置关卡进度
    const dataStage: DataStage = createDataStage(stageID, type, name, difficulty, index)
    const doStage: DOStage = new DOStage(dataStage)
    this.stageMap.set(stageID, doStage)
    return doStage
  }

  public getStage(stageID: string): DOStage { // 获取指定关卡数据对象，注意判空
    if (this.stageMap.has(stageID)) {
      const doStage: DOStage = this.stageMap.get(stageID)
      return doStage
    } else {
      const jsonStr = Laya.LocalStorage.getItem(stageID)
      if (jsonStr) {
        const dataStage: DataStage = JSON.parse(jsonStr)
        const doStage: DOStage = new DOStage(dataStage)
        this.stageMap.set(stageID, doStage)
        return doStage
      }
    }
    return null
  }

  public cleanStage(stageID: string): void {
    if (this.stageMap.has(stageID)) {
      this.stageMap.delete(stageID)
    }
    Laya.LocalStorage.removeItem(stageID)
  }

  public loadStage(stageID: string): DOStage { // 载入关卡
    const doStage = this.getStage(stageID)
    if (doStage) {
      this.stageID = stageID
      this.stageChanged = false
      return doStage
    }
    console.log("载入关卡失败>>>>>", stageID)
    return null
  }

  public saveStage(): void {
    if (this.stageChanged) {
      this.stageChanged = false
      if (this.stageMap.has(this.stageID)) {
        const doStage = this.stageMap.get(this.stageID)
        const jsonStr = JSON.stringify(doStage.getData())
        Laya.LocalStorage.setItem(this.stageID, jsonStr)
      }
    }
  }

  public onStageChanged(): void {
    this.stageChanged = true
  }

  public cleanAll(): void {
    this.user = new DOUser({ dones: [], trophy_records: [], progresses: [] })
    this.userChanged = false

    this.stageID = ""
    this.stageChanged = false
    this.stageMap.clear()

    Laya.LocalStorage.clear()
  }
}
