<script setup lang="ts">
import { computed, onActivated, onMounted, ref, watch } from 'vue'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { useKvStore } from '@/pinia/kv'
import { useTabStore } from '@/pinia/tab'
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
import { ArrowRight, Calculator, PencilLine } from 'lucide-vue-next'
import { industryTypeList } from '@/sql'
import { formatThousands } from '@/lib/numberFormat'
import { roundTo } from '@/lib/decimal'
import { initializeProjectFactorStates } from '@/lib/projectWorkspace'
import {
  QUICK_CONSULT_CATEGORY_FACTOR_KEY,
  QUICK_CONTRACT_FALLBACK_NAME,
  QUICK_CONTRACT_ID,
  QUICK_CONTRACT_META_KEY,
  QUICK_MAJOR_FACTOR_KEY,
  QUICK_PROJECT_INFO_KEY,
  QUICK_PROJECT_SCALE_KEY,
  createDefaultQuickContractMeta,
  writeWorkspaceMode
} from '@/lib/workspace'

interface QuickProjectInfoState {
  projectIndustry?: string
  projectName?: string
  preparedBy?: string
  reviewedBy?: string
  preparedCompany?: string
  preparedDate?: string
}

interface QuickContractMetaState {
  id?: string
  name?: string
  updatedAt?: string
}

interface HtFeeMainRowLike {
  id?: unknown
}

interface RateMethodStateLike {
  budgetFee?: unknown
}

interface HourlyMethodRowLike {
  serviceBudget?: unknown
  adoptedBudgetUnitPrice?: unknown
  personnelCount?: unknown
  workdayCount?: unknown
}

interface HourlyMethodStateLike {
  detailRows?: HourlyMethodRowLike[]
}

interface QuantityMethodRowLike {
  id?: unknown
  budgetFee?: unknown
  quantity?: unknown
  unitPrice?: unknown
}

interface QuantityMethodStateLike {
  detailRows?: QuantityMethodRowLike[]
}

const kvStore = useKvStore()
const tabStore = useTabStore()
const zxFwPricingStore = useZxFwPricingStore()

const contractName = ref(QUICK_CONTRACT_FALLBACK_NAME)
const projectIndustry = ref(String(industryTypeList[0]?.id || ''))
const quickBudget = ref<number | null>(null)
const savingIndustry = ref(false)
let budgetRefreshTimer: ReturnType<typeof setTimeout> | null = null

const availableIndustries = computed(() =>
  industryTypeList.map(item => ({
    id: String(item.id),
    name: item.name
  }))
)

const formatBudgetAmount = (value: number | null | undefined) =>
  typeof value === 'number' && Number.isFinite(value) ? `${formatThousands(value, 2)} 元` : '--'

const toFiniteNumber = (value: unknown): number | null => {
  if (value == null || value === '') return null
  const num = Number(value)
  return Number.isFinite(num) ? num : null
}

const sumHourlyMethodFee = (state: HourlyMethodStateLike | null): number | null => {
  const rows = Array.isArray(state?.detailRows) ? state.detailRows : []
  if (rows.length === 0) return null
  let hasValid = false
  let total = 0
  for (const row of rows) {
    const serviceBudget = toFiniteNumber(row?.serviceBudget)
    if (serviceBudget != null) {
      total += serviceBudget
      hasValid = true
      continue
    }
    const adopted = toFiniteNumber(row?.adoptedBudgetUnitPrice)
    const personnel = toFiniteNumber(row?.personnelCount)
    const workday = toFiniteNumber(row?.workdayCount)
    if (adopted == null || personnel == null || workday == null) continue
    total += adopted * personnel * workday
    hasValid = true
  }
  return hasValid ? roundTo(total, 2) : null
}

const sumQuantityMethodFee = (state: QuantityMethodStateLike | null): number | null => {
  const rows = Array.isArray(state?.detailRows) ? state.detailRows : []
  if (rows.length === 0) return null
  const subtotalRow = rows.find(row => String(row?.id || '') === 'fee-subtotal-fixed')
  const subtotal = toFiniteNumber(subtotalRow?.budgetFee)
  if (subtotal != null) return roundTo(subtotal, 2)

  let hasValid = false
  let total = 0
  for (const row of rows) {
    if (String(row?.id || '') === 'fee-subtotal-fixed') continue
    const budget = toFiniteNumber(row?.budgetFee)
    if (budget != null) {
      total += budget
      hasValid = true
      continue
    }
    const quantity = toFiniteNumber(row?.quantity)
    const unitPrice = toFiniteNumber(row?.unitPrice)
    if (quantity == null || unitPrice == null) continue
    total += quantity * unitPrice
    hasValid = true
  }
  return hasValid ? roundTo(total, 2) : null
}

const loadHtMethodTotalByRow = async (mainStorageKey: string, rowId: string) => {
  const [rateState, hourlyState, quantityState] = await Promise.all([
    zxFwPricingStore.loadHtFeeMethodState<RateMethodStateLike>(mainStorageKey, rowId, 'rate-fee'),
    zxFwPricingStore.loadHtFeeMethodState<HourlyMethodStateLike>(mainStorageKey, rowId, 'hourly-fee'),
    zxFwPricingStore.loadHtFeeMethodState<QuantityMethodStateLike>(mainStorageKey, rowId, 'quantity-unit-price-fee')
  ])
  const parts = [
    toFiniteNumber(rateState?.budgetFee),
    sumHourlyMethodFee(hourlyState),
    sumQuantityMethodFee(quantityState)
  ]
  const validParts = parts.filter((item): item is number => typeof item === 'number' && Number.isFinite(item))
  if (validParts.length === 0) return null
  return roundTo(validParts.reduce((sum, value) => sum + value, 0), 2)
}

const loadHtMainTotalFee = async (mainStorageKey: string) => {
  const mainState = await zxFwPricingStore.loadHtFeeMainState<HtFeeMainRowLike>(mainStorageKey)
  const rows = Array.isArray(mainState?.detailRows) ? mainState.detailRows : []
  const rowIds = rows.map(row => String(row?.id || '').trim()).filter(Boolean)
  if (rowIds.length === 0) return null
  const rowTotals = await Promise.all(rowIds.map(rowId => loadHtMethodTotalByRow(mainStorageKey, rowId)))
  const validTotals = rowTotals.filter((item): item is number => typeof item === 'number' && Number.isFinite(item))
  if (validTotals.length === 0) return null
  return roundTo(validTotals.reduce((sum, value) => sum + value, 0), 2)
}

const refreshQuickBudget = async () => {
  await zxFwPricingStore.loadContract(QUICK_CONTRACT_ID)
  const serviceFee = zxFwPricingStore.getBaseSubtotal(QUICK_CONTRACT_ID)
  const [additionalFee, reserveFee] = await Promise.all([
    loadHtMainTotalFee(`htExtraFee-${QUICK_CONTRACT_ID}-additional-work`),
    loadHtMainTotalFee(`htExtraFee-${QUICK_CONTRACT_ID}-reserve`)
  ])
  const parts = [serviceFee, additionalFee, reserveFee]
  const validParts = parts.filter((item): item is number => typeof item === 'number' && Number.isFinite(item))
  quickBudget.value = validParts.length === 0 ? null : roundTo(validParts.reduce((sum, value) => sum + value, 0), 2)
}

const scheduleRefreshQuickBudget = () => {
  if (budgetRefreshTimer) clearTimeout(budgetRefreshTimer)
  budgetRefreshTimer = setTimeout(() => {
    void refreshQuickBudget()
  }, 80)
}

const normalizeQuickContractMeta = (value: QuickContractMetaState | null) => ({
  id: typeof value?.id === 'string' && value.id.trim() ? value.id.trim() : QUICK_CONTRACT_ID,
  name: typeof value?.name === 'string' && value.name.trim() ? value.name.trim() : QUICK_CONTRACT_FALLBACK_NAME,
  updatedAt:
    typeof value?.updatedAt === 'string' && value.updatedAt.trim()
      ? value.updatedAt
      : new Date().toISOString()
})

const ensureQuickWorkspaceReady = async () => {
  const [savedInfo, savedMeta] = await Promise.all([
    kvStore.getItem<QuickProjectInfoState>(QUICK_PROJECT_INFO_KEY),
    kvStore.getItem<QuickContractMetaState>(QUICK_CONTRACT_META_KEY)
  ])

  const defaultIndustry = String(industryTypeList[0]?.id || '')
  const nextIndustry =
    typeof savedInfo?.projectIndustry === 'string' && savedInfo.projectIndustry.trim()
      ? savedInfo.projectIndustry.trim()
      : defaultIndustry

  projectIndustry.value = nextIndustry
  contractName.value = normalizeQuickContractMeta(savedMeta).name

  await kvStore.setItem(QUICK_PROJECT_INFO_KEY, {
    projectIndustry: nextIndustry,
    projectName: '快速计算'
  })

  const consultState = await kvStore.getItem(QUICK_CONSULT_CATEGORY_FACTOR_KEY)
  const majorState = await kvStore.getItem(QUICK_MAJOR_FACTOR_KEY)
  if (!consultState || !majorState) {
    await initializeProjectFactorStates(
      kvStore,
      nextIndustry,
      QUICK_CONSULT_CATEGORY_FACTOR_KEY,
      QUICK_MAJOR_FACTOR_KEY
    )
  }

  await kvStore.setItem(QUICK_CONTRACT_META_KEY, {
    ...createDefaultQuickContractMeta(),
    ...normalizeQuickContractMeta(savedMeta)
  })
}

const persistQuickContractMeta = async () => {
  await kvStore.setItem(QUICK_CONTRACT_META_KEY, {
    id: QUICK_CONTRACT_ID,
    name: contractName.value.trim() || QUICK_CONTRACT_FALLBACK_NAME,
    updatedAt: new Date().toISOString()
  })
}

const persistQuickIndustry = async (industry: string) => {
  if (!industry) return
  savingIndustry.value = true
  try {
    const current = await kvStore.getItem<QuickProjectInfoState>(QUICK_PROJECT_INFO_KEY)
    await kvStore.setItem(QUICK_PROJECT_INFO_KEY, {
      ...current,
      projectIndustry: industry,
      projectName: '快速计算'
    })
    await initializeProjectFactorStates(
      kvStore,
      industry,
      QUICK_CONSULT_CATEGORY_FACTOR_KEY,
      QUICK_MAJOR_FACTOR_KEY
    )
  } finally {
    savingIndustry.value = false
  }
}

const openQuickContract = () => {
  writeWorkspaceMode('quick')
  tabStore.openTab({
    id: `contract-${QUICK_CONTRACT_ID}`,
    title: `快速计算-${contractName.value.trim() || QUICK_CONTRACT_FALLBACK_NAME}`,
    componentName: 'ContractDetailView',
    props: {
      contractId: QUICK_CONTRACT_ID,
      contractName: contractName.value.trim() || QUICK_CONTRACT_FALLBACK_NAME,
      projectInfoKey: QUICK_PROJECT_INFO_KEY,
      projectScaleKey: QUICK_PROJECT_SCALE_KEY,
      projectConsultCategoryFactorKey: QUICK_CONSULT_CATEGORY_FACTOR_KEY,
      projectMajorFactorKey: QUICK_MAJOR_FACTOR_KEY
    }
  })
}

watch(
  () => contractName.value,
  () => {
    void persistQuickContractMeta()
  }
)

watch(
  () => projectIndustry.value,
  nextIndustry => {
    if (!nextIndustry) return
    void persistQuickIndustry(nextIndustry)
  }
)

watch(
  () => [
    zxFwPricingStore.contractVersions[QUICK_CONTRACT_ID] || 0,
    zxFwPricingStore.getKeyVersion(`htExtraFee-${QUICK_CONTRACT_ID}-additional-work`),
    zxFwPricingStore.getKeyVersion(`htExtraFee-${QUICK_CONTRACT_ID}-reserve`),
    Object.entries(zxFwPricingStore.keyVersions)
      .filter(([key]) =>
        key.startsWith(`htExtraFee-${QUICK_CONTRACT_ID}-additional-work-`) ||
        key.startsWith(`htExtraFee-${QUICK_CONTRACT_ID}-reserve-`)
      )
      .map(([key, version]) => `${key}:${version}`)
      .join('|')
  ],
  scheduleRefreshQuickBudget
)

onMounted(async () => {
  writeWorkspaceMode('quick')
  await ensureQuickWorkspaceReady()
  await refreshQuickBudget()
})

onActivated(() => {
  writeWorkspaceMode('quick')
  scheduleRefreshQuickBudget()
})
</script>

<template>
  <div class="mx-auto flex h-full w-full max-w-6xl flex-col gap-6">
    <div class="grid gap-4 lg:grid-cols-[minmax(0,1.25fr)_minmax(320px,0.75fr)]">
      <Card class="border-border/70">
        <CardHeader>
          <CardTitle class="flex items-center gap-2 text-2xl">
            <Calculator class="h-5 w-5" />
            快速计算
          </CardTitle>
          <CardDescription>
            保留一个默认合同卡片，不再经过项目卡片入口，直接进入单合同预算费用计算。
          </CardDescription>
        </CardHeader>
        <CardContent class="grid gap-4 md:grid-cols-2">
          <label class="space-y-2">
            <span class="text-sm font-medium text-foreground">工程行业</span>
            <select
              v-model="projectIndustry"
              class="h-11 w-full rounded-md border bg-background px-3 text-sm outline-none transition focus-visible:ring-2 focus-visible:ring-ring"
            >
              <option v-for="item in availableIndustries" :key="item.id" :value="item.id">
                {{ item.name }}
              </option>
            </select>
          </label>
          <label class="space-y-2">
            <span class="text-sm font-medium text-foreground">合同名称</span>
            <div class="relative">
              <PencilLine class="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <input
                v-model="contractName"
                type="text"
                maxlength="40"
                class="h-11 w-full rounded-md border bg-background pl-9 pr-3 text-sm outline-none transition focus-visible:ring-2 focus-visible:ring-ring"
                placeholder="请输入合同名称"
              />
            </div>
          </label>
        </CardContent>
      </Card>

      <Card class="border-border/70 bg-muted/25">
        <CardHeader class="pb-3">
          <CardTitle class="text-base">当前状态</CardTitle>
        </CardHeader>
        <CardContent class="grid gap-2 text-sm text-muted-foreground">
          <div>模式：单合同快速计算</div>
          <div>合同ID：{{ QUICK_CONTRACT_ID }}</div>
          <div>行业切换会同步重建快速计算专用系数基线</div>
          <div>{{ savingIndustry ? '正在切换行业并刷新系数...' : '行业与合同名称已自动保存' }}</div>
        </CardContent>
      </Card>
    </div>

    <Card
      class="group cursor-pointer border-border/70 transition-colors hover:border-primary"
      @click="openQuickContract"
    >
      <CardHeader class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
        <div class="space-y-2">
          <CardTitle class="text-xl">
            {{ contractName.trim() || QUICK_CONTRACT_FALLBACK_NAME }}
          </CardTitle>
          <CardDescription>默认单合同卡片，点击后进入预算费用计算详情。</CardDescription>
        </div>
        <Button class="shrink-0 md:self-center" @click.stop="openQuickContract">
          进入计算
          <ArrowRight class="ml-1 h-4 w-4" />
        </Button>
      </CardHeader>
      <CardContent class="grid gap-4 border-t pt-5 text-sm text-muted-foreground md:grid-cols-3">
        <div>
          <div class="text-xs uppercase tracking-[0.24em] text-muted-foreground/80">合同ID</div>
          <div class="mt-2 break-all text-foreground">{{ QUICK_CONTRACT_ID }}</div>
        </div>
        <div>
          <div class="text-xs uppercase tracking-[0.24em] text-muted-foreground/80">预算费用</div>
          <div class="mt-2 text-foreground">{{ formatBudgetAmount(quickBudget) }}</div>
        </div>
        <div>
          <div class="text-xs uppercase tracking-[0.24em] text-muted-foreground/80">行业</div>
          <div class="mt-2 text-foreground">
            {{ availableIndustries.find(item => item.id === projectIndustry)?.name || '--' }}
          </div>
        </div>
      </CardContent>
    </Card>
  </div>
</template>
