<script setup lang="ts">
import { computed, onActivated, onMounted, ref } from 'vue'
import localforage from 'localforage'
import { getMajorDictEntries, isMajorIdInIndustryScope } from '@/sql'
import CommonAgGrid from '@/components/common/xmCommonAgGrid.vue'

interface DictLeaf {
  id: string
  code: string
  name: string
  hasCost: boolean
  hasArea: boolean
}

interface DictGroup {
  id: string
  code: string
  name: string
  children: DictLeaf[]
}

interface DetailRow {
  id: string
  groupCode: string
  groupName: string
  majorCode: string
  majorName: string
  hasCost: boolean
  hasArea: boolean
  amount: number | null
  landArea: number | null
  path: string[]
}

interface XmInfoState {
  projectName: string
  detailRows: DetailRow[]
}
interface XmBaseInfoState {
  projectIndustry?: string
}

const props = defineProps<{
  contractId: string
}>()
const DB_KEY = computed(() => `ht-info-v3-${props.contractId}`)
const XM_DB_KEY = 'xm-info-v3'
const BASE_INFO_KEY = 'xm-base-info-v1'
const activeIndustryId = ref('')

const detailRows = ref<DetailRow[]>([])

type majorLite = { code: string; name: string; hasCost?: boolean; hasArea?: boolean }
const serviceEntries = getMajorDictEntries().map(({ id, item }) => [id, item] as [string, majorLite])
const majorIdAliasMap = new Map(getMajorDictEntries().map(({ rawId, id }) => [rawId, id]))

const detailDict: DictGroup[] = (() => {
  const groupMap = new Map<string, DictGroup>()
  const groupOrder: string[] = []
  const codeLookup = new Map(serviceEntries.map(([key, item]) => [item.code, { id: key, code: item.code, name: item.name }]))

  for (const [key, item] of serviceEntries) {
    const code = item.code
    const isGroup = !code.includes('-')
    if (isGroup) {
      if (!groupMap.has(code)) groupOrder.push(code)
      groupMap.set(code, {
        id: key,
        code,
        name: item.name,
        children: []
      })
      continue
    }

    const parentCode = code.split('-')[0]
    if (!groupMap.has(parentCode)) {
      const parent = codeLookup.get(parentCode)
      if (!groupOrder.includes(parentCode)) groupOrder.push(parentCode)
      groupMap.set(parentCode, {
        id: parent?.id || `group-${parentCode}`,
        code: parentCode,
        name: parent?.name || parentCode,
        children: []
      })
    }

    groupMap.get(parentCode)!.children.push({
      id: key,
      code,
      name: item.name,
      hasCost: item.hasCost !== false,
      hasArea: item.hasArea !== false
    })
  }

  return groupOrder.map(code => groupMap.get(code)).filter((group): group is DictGroup => Boolean(group))
})()

const buildDefaultRows = (): DetailRow[] => {
  if (!activeIndustryId.value) return []
  const rows: DetailRow[] = []
  for (const group of detailDict) {
    if (activeIndustryId.value && !isMajorIdInIndustryScope(group.id, activeIndustryId.value)) continue
    for (const child of group.children) {
      rows.push({
        id: child.id,
        groupCode: group.code,
        groupName: group.name,
        majorCode: child.code,
        majorName: child.name,
        hasCost: child.hasCost,
        hasArea: child.hasArea,
        amount: null,
        landArea: null,
        path: [`${group.code} ${group.name}`, `${child.code} ${child.name}`]
      })
    }
  }
  return rows
}

const mergeWithDictRows = (rowsFromDb: DetailRow[] | undefined): DetailRow[] => {
  const dbValueMap = new Map<string, DetailRow>()
  for (const row of rowsFromDb || []) {
    const rowId = String(row.id)
    dbValueMap.set(rowId, row)
    const aliasId = majorIdAliasMap.get(rowId)
    if (aliasId && !dbValueMap.has(aliasId)) {
      dbValueMap.set(aliasId, row)
    }
  }

  return buildDefaultRows().map(row => {
    const fromDb = dbValueMap.get(row.id)
    if (!fromDb) return row

    return {
      ...row,
      amount: row.hasCost && typeof fromDb.amount === 'number' ? fromDb.amount : null,
      landArea: row.hasArea && typeof fromDb.landArea === 'number' ? fromDb.landArea : null
    }
  })
}

const loadFromIndexedDB = async () => {
  try {
    const baseInfo = await localforage.getItem<XmBaseInfoState>(BASE_INFO_KEY)
    activeIndustryId.value =
      typeof baseInfo?.projectIndustry === 'string' ? baseInfo.projectIndustry.trim() : ''

    const data = await localforage.getItem<XmInfoState>(DB_KEY.value)
    if (data) {
      detailRows.value = mergeWithDictRows(data.detailRows)
      return
    }

    // 首次创建合同段时，默认继承项目规模信息（同一套专业字典，按 id 对齐）
    const xmData =
      (await localforage.getItem<XmInfoState>(XM_DB_KEY)) 
    if (xmData?.detailRows) {
      detailRows.value = mergeWithDictRows(xmData.detailRows)
      return
    }

    detailRows.value = buildDefaultRows()
  } catch (error) {
    console.error('loadFromIndexedDB failed:', error)
    detailRows.value = buildDefaultRows()
  }
}

onMounted(async () => {
  await loadFromIndexedDB()
})

onActivated(() => {
  void loadFromIndexedDB()
})
</script>

<template>
  <CommonAgGrid title="合同规模明细" :rowData="detailRows" :dbKey="DB_KEY" />
</template>
