import { defineStore } from 'pinia'
import { useUserStore } from './user'
import { transformNames } from './roles'
import {
  fetchProject,
  uploadProjectBimScene,
  relaceProjectScenes,
  SceneType,
  deleteProject,
  finishProject,
  updateProject,
  deleteProjectBimScene,
  BimStatus,
  deleteProjectScene,
  updateProjectBimSceneName,
  fetchProjectRoleOptions
} from '@/api'

import type {
  Project,
  Scene,
  BimUploadData,
  UpdateProjectData,
  Bim
} from '@/api'
import { RoutesName } from '@/router/constant'

export const BinType = Symbol('bin')
export const binTypeDesc = 'BIM'
export type { Project, BimUploadData, Bim }
export const DefaultMenus = [
  RoutesName.projectScenes,
  RoutesName.projectTaggings,
  RoutesName.projectMembers,
  RoutesName.projectRoles
]

export type ProjectScene = Omit<Scene, 'type' | 'num' | 'status'> &
  (
    | {
        type: Scene['type']
        status: Scene['status']
        num: Scene['num']
      }
    | {
        type: typeof BinType
        status: BimStatus
      }
  )
export type SelectTypeScenes = {
  [SceneType.SWKJ]: Scene['num'][]
  [SceneType.SWKK]: Scene['num'][]
  [SceneType.SWSS]: Scene['num'][]
  [SceneType.SWSG]: Scene['num'][]
}

type CurrentState = null | Project

export const useProject = defineStore('project', {
  state: () => ({
    current: null as CurrentState,
    roleMenus: DefaultMenus
  }),
  getters: {
    scenes: state => {
      const scenes: ProjectScene[] = state.current?.sceneList || []
      const bimData = state.current?.bimData
      if (bimData) {
        return [
          {
            id: bimData.bimId,
            name: bimData.bimName,
            phone: bimData.userName,
            title: bimData.bimName,
            sceneName: bimData.bimName,
            thumb: bimData.bimOssFilePath,
            createTime: bimData.createTime,
            type: BinType,
            status: bimData.bimStatus
          },
          ...scenes
        ]
      } else {
        return scenes
      }
    },
    isSelf: state => (id?: Project['projectId']) =>
      state.current?.projectId === id
  },
  actions: {
    async setRoles(id: Project['projectId']) {
      if (id) {
        this.roleMenus = transformNames(await fetchProjectRoleOptions(id))
      } else {
        this.roleMenus = DefaultMenus
      }
    },
    async setCurrent(id: Project['projectId']) {
      this.current = await fetchProject(id)
    },
    async updateCurrent(id?: Project['projectId']) {
      if ((id = id || this.current?.projectId)) {
        this.isSelf(id) && (await this.setCurrent(id))
      }
    },
    async delete(id?: Project['projectId']) {
      if ((id = id || this.current?.projectId)) {
        await deleteProject(id)
        await useUserStore().fetchMeta()
        this.current = null
      }
    },
    async update(data: PartialPart<UpdateProjectData, 'projectId'>) {
      const id = data.projectId || this.current?.projectId
      if (id) {
        console.log({
          ...data,
          projectId: id
        })
        await updateProject({
          ...data,
          projectId: id
        })
        await this.updateCurrent(id)
      }
    },
    async finish(id?: Project['projectId']) {
      if ((id = id || this.current?.projectId)) {
        await finishProject(id)
        await useUserStore().fetchMeta()
        await this.updateCurrent(id)
      }
    },
    async addBim(data: BimUploadData, id?: Project['projectId']) {
      if ((id = id || this.current?.projectId)) {
        await uploadProjectBimScene(id, data)
        await useUserStore().fetchMeta()
        await this.updateCurrent(id)
      }
    },
    async updateBimName(bimName: Bim['bimName'], bimId?: Bim['bimId']) {
      if ((bimId = bimId || this.current?.bimData?.bimId)) {
        await updateProjectBimSceneName({ bimId, bimName })
        this.current?.bimData?.bimId === bimId && (await this.updateCurrent())
      }
    },
    async deleteBim(bimId?: Bim['bimId']) {
      if ((bimId = bimId || this.current?.bimData?.bimId)) {
        await deleteProjectBimScene(bimId)
        await useUserStore().fetchMeta()
        this.current?.bimData?.bimId === bimId && (await this.updateCurrent())
      }
    },
    async replaceScenes(
      typeScenes: SelectTypeScenes,
      id?: Project['projectId']
    ) {
      if ((id = id || this.current?.projectId)) {
        const sceneNumParam = Object.entries(typeScenes).map(
          ([type, nums]) => ({
            type: Number(type) as SceneType,
            numList: nums
          })
        )
        await relaceProjectScenes({ id, sceneNumParam })
        await useUserStore().fetchMeta()
        await this.updateCurrent(id)
      }
    },
    async deleteScene(num: Scene['num'], id?: Project['projectId']) {
      if ((id = id || this.current?.projectId)) {
        await deleteProjectScene({ projectId: id, num })
        await useUserStore().fetchMeta()
        await this.updateCurrent(id)
      }
    }
  }
})

export {
  ProjectStatus,
  ProjectStatusDesc,
  BimStatus,
  BimStatusDesc
} from '@/api'
