<script setup lang="ts">
import { parseDate } from '@internationalized/date'
import { onMounted, ref, watch } from 'vue'
import localforage from 'localforage'
import { industryTypeList } from '@/sql'
import { Calendar as CalendarIcon, CircleHelp } from 'lucide-vue-next'
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from '@/components/ui/tooltip'
import {
  DatePickerAnchor,
  DatePickerArrow,
  DatePickerCalendar,
  DatePickerCell,
  DatePickerCellTrigger,
  DatePickerClose,
  DatePickerContent,
  DatePickerField,
  DatePickerGrid,
  DatePickerGridBody,
  DatePickerGridHead,
  DatePickerGridRow,
  DatePickerHeadCell,
  DatePickerHeader,
  DatePickerHeading,
  DatePickerInput,
  DatePickerNext,
  DatePickerPrev,
  DatePickerRoot,
  DatePickerTrigger
} from 'reka-ui'

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

type MajorParentNode = { id: string; name: string }

const DB_KEY = 'xm-base-info-v1'
const DEFAULT_PROJECT_NAME = 'xxx造价咨询服务'
const INDUSTRY_HINT_TEXT = '变更需要重置后重新选择'
const PROJECT_INIT_CHANGED_EVENT = 'xm-project-init-changed'

const isProjectInitialized = ref(false)
const showCreateDialog = ref(false)
const pendingIndustry = ref('')

const projectName = ref('')
const projectIndustry = ref('')
const preparedBy = ref('')
const reviewedBy = ref('')
const preparedCompany = ref('')
const preparedDate = ref('')
const preparedDatePickerValue = ref<any>(undefined)

const normalizeDateString = (value: unknown): string => {
  if (typeof value !== 'string') return ''
  const trimmed = value.trim()
  if (!trimmed) return ''
  try {
    const parsed = parseDate(trimmed)
    return parsed.toString() === trimmed ? trimmed : ''
  } catch {
    return ''
  }
}

const syncPreparedDatePickerFromString = () => {
  if (!preparedDate.value) {
    preparedDatePickerValue.value = undefined
    return
  }
  try {
    preparedDatePickerValue.value = parseDate(preparedDate.value)
  } catch {
    preparedDatePickerValue.value = undefined
    preparedDate.value = ''
  }
}

const handlePreparedDateSelect = (date: any) => {
  preparedDatePickerValue.value = date
  preparedDate.value = date?.toString() ?? ''
}

const majorParentNodes: MajorParentNode[] = industryTypeList.map(item => ({
  id: item.id,
  name: item.name
}))
const majorParentCodeSet = new Set(majorParentNodes.map(item => item.id))
const DEFAULT_PROJECT_INDUSTRY = majorParentNodes[0]?.id || ''

const saveToIndexedDB = async () => {
  try {
    const payload: XmInfoState = {
      projectIndustry: projectIndustry.value,
      projectName: projectName.value,
      preparedBy: preparedBy.value,
      reviewedBy: reviewedBy.value,
      preparedCompany: preparedCompany.value,
      preparedDate: preparedDate.value
    }
    await localforage.setItem(DB_KEY, payload)
  } catch (error) {
    console.error('saveToIndexedDB failed:', error)
  }
}

const loadFromIndexedDB = async () => {
  try {
    const data = await localforage.getItem<XmInfoState>(DB_KEY)
    if (data) {
      isProjectInitialized.value = true
      projectIndustry.value =
        typeof data.projectIndustry === 'string' && majorParentCodeSet.has(data.projectIndustry)
          ? data.projectIndustry
          : DEFAULT_PROJECT_INDUSTRY
      projectName.value =
        typeof data.projectName === 'string' && data.projectName.trim() ? data.projectName : DEFAULT_PROJECT_NAME
      preparedBy.value = typeof data.preparedBy === 'string' ? data.preparedBy : ''
      reviewedBy.value = typeof data.reviewedBy === 'string' ? data.reviewedBy : ''
      preparedCompany.value = typeof data.preparedCompany === 'string' ? data.preparedCompany : ''
      preparedDate.value = normalizeDateString(data.preparedDate)
      syncPreparedDatePickerFromString()
      return
    }

    isProjectInitialized.value = false
    projectIndustry.value = DEFAULT_PROJECT_INDUSTRY
    projectName.value = DEFAULT_PROJECT_NAME
    preparedBy.value = ''
    reviewedBy.value = ''
    preparedCompany.value = ''
    preparedDate.value = ''
    syncPreparedDatePickerFromString()
  } catch (error) {
    console.error('loadFromIndexedDB failed:', error)
    projectIndustry.value = DEFAULT_PROJECT_INDUSTRY
    projectName.value = DEFAULT_PROJECT_NAME
    preparedBy.value = ''
    reviewedBy.value = ''
    preparedCompany.value = ''
    preparedDate.value = ''
    syncPreparedDatePickerFromString()
  }
}

let persistTimer: ReturnType<typeof setTimeout> | null = null
const schedulePersist = () => {
  if (!isProjectInitialized.value) return
  if (persistTimer) clearTimeout(persistTimer)
  persistTimer = setTimeout(() => {
    void saveToIndexedDB()
  }, 250)
}

const handleProjectNameBlur = () => {
  if (!projectName.value.trim()) {
    projectName.value = DEFAULT_PROJECT_NAME
  }
}

const openCreateDialog = () => {
  pendingIndustry.value = DEFAULT_PROJECT_INDUSTRY
  showCreateDialog.value = true
}

const closeCreateDialog = () => {
  showCreateDialog.value = false
}

const createProject = async () => {
  const selectedIndustry = majorParentCodeSet.has(pendingIndustry.value)
    ? pendingIndustry.value
    : DEFAULT_PROJECT_INDUSTRY

  projectIndustry.value = selectedIndustry
  projectName.value = DEFAULT_PROJECT_NAME
  preparedBy.value = ''
  reviewedBy.value = ''
  preparedCompany.value = ''
  preparedDate.value = ''
  syncPreparedDatePickerFromString()
  isProjectInitialized.value = true
  showCreateDialog.value = false
  await saveToIndexedDB()
  window.dispatchEvent(new CustomEvent<boolean>(PROJECT_INIT_CHANGED_EVENT, { detail: true }))
}

watch(
  [projectIndustry, projectName, preparedBy, reviewedBy, preparedCompany, preparedDate],
  schedulePersist
)

onMounted(async () => {
  await loadFromIndexedDB()
})
</script>

<template>
  <TooltipProvider>
  <div class="space-y-6 h-full">
    <div
      v-if="!isProjectInitialized"
      class=" bg-card p-10 h-full flex items-center justify-center"
    >
      <button
        type="button"
        class="cursor-pointer h-10 rounded-lg bg-primary px-6 text-sm font-medium text-primary-foreground transition hover:opacity-90"
        @click="openCreateDialog"
      >
        新建项目
      </button>
    </div>

    <div v-else class="rounded-xl border bg-card p-4 shadow-sm shrink-0 md:p-5">
      <div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
        <div class="md:col-span-2 xl:col-span-4">
          <label class="block text-sm font-medium text-foreground">项目名称</label>
          <input
            v-model="projectName"
            type="text"
            required
            placeholder="xxx造价咨询服务"
            class="mt-2 h-10 w-full rounded-lg border bg-background px-4 text-sm outline-none ring-offset-background shadow-sm transition placeholder:text-muted-foreground/70 focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring"
            @blur="handleProjectNameBlur"
          />
        </div>

        <div class="md:col-span-2 xl:col-span-4">
          <div class="flex items-center gap-1.5">
            <label class="block text-sm font-medium text-foreground">工程行业</label>
            <TooltipRoot>
              <TooltipTrigger as-child>
                <button
                  type="button"
                  aria-label="工程行业提示"
                  class="inline-flex h-5 w-5  items-center justify-center text-muted-foreground/90 transition hover:text-foreground"
                >
                  <CircleHelp class="h-5 w-5" />
                </button>
              </TooltipTrigger>
              <TooltipContent side="top">{{ INDUSTRY_HINT_TEXT }}</TooltipContent>
            </TooltipRoot>
          </div>
          <div class="mt-2 flex flex-wrap gap-3 rounded-lg border bg-background px-3 py-2">
            <label
              v-for="item in majorParentNodes"
              :key="item.id"
              class="inline-flex items-center gap-2 text-sm text-foreground/80"
            >
              <input
                v-model="projectIndustry"
                type="radio"
                :value="item.id"
                disabled
                class="h-4 w-4 cursor-not-allowed accent-primary"
              />
              <span>{{ item.name }}</span>
            </label>
          </div>
        </div>

        <div>
          <label class="block text-sm font-medium text-foreground">编制人</label>
          <input
            v-model="preparedBy"
            type="text"
            placeholder="请输入编制人"
            class="mt-2 h-10 w-full rounded-lg border bg-background px-4 text-sm outline-none ring-offset-background shadow-sm transition placeholder:text-muted-foreground/70 focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring"
          />
        </div>

        <div>
          <label class="block text-sm font-medium text-foreground">复核人</label>
          <input
            v-model="reviewedBy"
            type="text"
            placeholder="请输入复核人"
            class="mt-2 h-10 w-full rounded-lg border bg-background px-4 text-sm outline-none ring-offset-background shadow-sm transition placeholder:text-muted-foreground/70 focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring"
          />
        </div>

        <div>
          <label class="block text-sm font-medium text-foreground">编制单位</label>
          <input
            v-model="preparedCompany"
            type="text"
            placeholder="请输入编制单位"
            class="mt-2 h-10 w-full rounded-lg border bg-background px-4 text-sm outline-none ring-offset-background shadow-sm transition placeholder:text-muted-foreground/70 focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring"
          />
        </div>

        <div>
          <label class="block text-sm font-medium text-foreground">编制日期</label>
          <DatePickerRoot
            locale="en-CA"
            :model-value="preparedDatePickerValue"
            @update:model-value="handlePreparedDateSelect"
          >
            <DatePickerAnchor class="mt-2 block w-full">
              <DatePickerField
                v-slot="{ segments }"
                class="flex h-10 w-full items-center justify-between rounded-lg border bg-background px-4 text-sm outline-none ring-offset-background shadow-sm transition focus-within:border-primary/60 focus-within:ring-2 focus-within:ring-ring"
              >
                <div class="flex items-center">
                  <template
                    v-for="(segment, index) in segments"
                    :key="`${segment.part}-${index}`"
                  >
                    <DatePickerInput
                      :part="segment.part"
                      :class="segment.part === 'literal' ? 'text-muted-foreground/70' : 'text-foreground'"
                    >
                      {{ segment.part === 'literal' ? '-' : segment.value }}
                    </DatePickerInput>
                  </template>
                </div>
                <DatePickerTrigger as-child>
                  <button type="button" class="inline-flex h-6 w-6 items-center justify-center text-muted-foreground">
                    <CalendarIcon class="h-4 w-4" />
                  </button>
                </DatePickerTrigger>
              </DatePickerField>
            </DatePickerAnchor>
            <DatePickerContent class="z-50 w-[22rem] rounded-lg border bg-card p-4 shadow-lg">
              <DatePickerArrow class="fill-border" />
              <DatePickerCalendar v-slot="{ weekDays, grid }" locale="zh-CN">
                <DatePickerHeader class="mb-2 flex items-center justify-between">
                  <DatePickerPrev as-child>
                    <button
                      type="button"
                      class="inline-flex h-9 w-9 items-center justify-center rounded-md border text-sm transition hover:bg-muted"
                    >
                      ‹
                    </button>
                  </DatePickerPrev>
                  <DatePickerHeading class="text-base font-medium text-foreground" />
                  <DatePickerNext as-child>
                    <button
                      type="button"
                      class="inline-flex h-9 w-9 items-center justify-center rounded-md border text-sm transition hover:bg-muted"
                    >
                      ›
                    </button>
                  </DatePickerNext>
                </DatePickerHeader>
                <div class="space-y-2">
                  <DatePickerGrid
                    v-for="month in grid"
                    :key="month.value.toString()"
                    class="w-full border-collapse select-none"
                  >
                    <DatePickerGridHead>
                      <DatePickerGridRow class="grid grid-cols-7">
                        <DatePickerHeadCell
                          v-for="day in weekDays"
                          :key="day"
                          class="flex h-9 items-center justify-center text-sm text-muted-foreground"
                        >
                          {{ day }}
                        </DatePickerHeadCell>
                      </DatePickerGridRow>
                    </DatePickerGridHead>
                    <DatePickerGridBody>
                      <DatePickerGridRow
                        v-for="(weekDates, index) in month.rows"
                        :key="`${month.value.toString()}-${index}`"
                        class="grid grid-cols-7"
                      >
                        <DatePickerCell
                          v-for="dateValue in weekDates"
                          :key="dateValue.toString()"
                          :date="dateValue"
                          class="h-10 w-full p-0.5"
                        >
                        <DatePickerCellTrigger
                          :day="dateValue"
                          :month="month.value"
                          class="h-full w-full rounded-md border border-transparent bg-transparent text-base outline-none transition hover:bg-muted data-[outside-view]:text-muted-foreground/40 data-[selected]:border-primary data-[selected]:bg-transparent data-[selected]:text-foreground data-[disabled]:opacity-40 data-[unavailable]:text-muted-foreground/40"
                        >
                            {{ dateValue.day }}
                          </DatePickerCellTrigger>
                        </DatePickerCell>
                      </DatePickerGridRow>
                    </DatePickerGridBody>
                  </DatePickerGrid>
                </div>
              </DatePickerCalendar>
              <div class="mt-2 flex justify-end">
                <DatePickerClose as-child>
                  <button
                    type="button"
                    class="h-8 rounded-md border px-3 text-xs text-foreground transition hover:bg-muted"
                  >
                    关闭
                  </button>
                </DatePickerClose>
              </div>
            </DatePickerContent>
          </DatePickerRoot>
        </div>
      </div>
    </div>

    <div
      v-if="showCreateDialog"
      class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4"
      @click.self="closeCreateDialog"
    >
      <div class="w-full max-w-lg rounded-xl border bg-card p-5 shadow-lg">
        <h3 class="text-base font-semibold text-foreground">新建项目</h3>
        <p class="mt-1 text-sm text-muted-foreground">请选择工程行业</p>
        <div class="mt-4 max-h-72 space-y-2 overflow-auto rounded-lg border p-3">
          <label
            v-for="item in majorParentNodes"
            :key="item.id"
            class="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 hover:bg-muted/60"
          >
            <input v-model="pendingIndustry" type="radio" :value="item.id" class="h-4 w-4 accent-primary" />
            <span class="text-sm text-foreground"> {{ item.name }}</span>
          </label>
        </div>
        <div class="mt-5 flex justify-end gap-2">
          <button
            type="button"
            class="cursor-pointer h-9 rounded-lg border px-4 text-sm text-foreground transition hover:bg-muted"
            @click="closeCreateDialog"
          >
            取消
          </button>
          <button
            type="button"
            class="cursor-pointer h-9 rounded-lg bg-primary px-4 text-sm text-primary-foreground transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
            :disabled="!pendingIndustry"
            @click="createProject"
          >
            确定
          </button>
        </div>
      </div>
    </div>
  </div>
  </TooltipProvider>
</template>
