<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import draggable from 'vuedraggable'
import localforage from 'localforage'
import { Card, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { useTabStore } from '@/pinia/tab'
import { Edit3, Plus, Trash2, X } from 'lucide-vue-next'
import {
  ToastAction,
  ToastDescription,
  ToastProvider,
  ToastRoot,
  ToastTitle,
  ToastViewport
} from 'reka-ui'

interface ContractItem {
  id: string
  name: string
  order: number
  createdAt: string
}

const STORAGE_KEY = 'ht-card-v1'
const formStore = localforage.createInstance({
  name: 'jgjs-pricing-db',
  storeName: 'form_state'
})

const tabStore = useTabStore()



const contracts = ref<ContractItem[]>([])

const showCreateModal = ref(false)
const contractNameInput = ref('')
const editingContractId = ref<string | null>(null)
const toastOpen = ref(false)
const toastTitle = ref('操作成功')
const toastText = ref('')
const modalOffset = ref({ x: 0, y: 0 })
let dragStartX = 0
let dragStartY = 0
let baseOffsetX = 0
let baseOffsetY = 0

const buildDefaultContracts = (): ContractItem[] => [
  
]

const normalizeOrder = (list: ContractItem[]): ContractItem[] =>
  list.map((item, index) => ({
    ...item,
    order: index,
    createdAt: item.createdAt || new Date().toISOString()
  }))

const formatDateTime = (value: string) => {
  if (!value) return '-'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return '-'
  const pad = (n: number) => String(n).padStart(2, '0')
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
}

const notify = (text: string) => {
  toastTitle.value = '操作成功'
  toastText.value = text
  toastOpen.value = false
  requestAnimationFrame(() => {
    toastOpen.value = true
  })
}

const saveContracts = async () => {
  try {
    contracts.value = normalizeOrder(contracts.value)
    await localforage.setItem(STORAGE_KEY, JSON.parse(JSON.stringify(contracts.value)))
  } catch (error) {
    console.error('save contracts failed:', error)
  }
}

const removeForageKeysByContractId = async (store: typeof localforage, contractId: string) => {
  try {
    const keys = await store.keys()
    const targetKeys = keys.filter(key => key.includes(contractId))
    await Promise.all(targetKeys.map(key => store.removeItem(key)))
  } catch (error) {
    console.error('remove forage keys by contract id failed:', contractId, error)
  }
}

const removeRelatedTabsByContractId = (contractId: string) => {
  const relatedTabIds = tabStore.tabs
    .filter(tab => {
      const propsContractId = tab?.props?.contractId
      return (
        tab.id === `contract-${contractId}` ||
        tab.id.startsWith(`zxfw-edit-${contractId}-`) ||
        propsContractId === contractId
      )
    })
    .map(tab => tab.id)

  for (const tabId of relatedTabIds) {
    tabStore.removeTab(tabId)
  }
}

const cleanupContractRelatedData = async (contractId: string) => {
  await Promise.all([
    removeForageKeysByContractId(localforage, contractId),
    removeForageKeysByContractId(formStore as any, contractId)
  ])
}

const loadContracts = async () => {
  try {
    const saved = await localforage.getItem<ContractItem[]>(STORAGE_KEY)
    if (!saved || saved.length === 0) {
      contracts.value = buildDefaultContracts()
      await saveContracts()
      return
    }

    const sorted = [...saved].sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
    contracts.value = normalizeOrder(sorted)
  } catch (error) {
    console.error('load contracts failed:', error)
    contracts.value = buildDefaultContracts()
  }
}

const openCreateModal = () => {
  editingContractId.value = null
  contractNameInput.value = ''
  modalOffset.value = { x: 0, y: 0 }
  showCreateModal.value = true
}

const openEditModal = (item: ContractItem) => {
  editingContractId.value = item.id
  contractNameInput.value = item.name
  modalOffset.value = { x: 0, y: 0 }
  showCreateModal.value = true
}

const closeCreateModal = () => {
  showCreateModal.value = false
  editingContractId.value = null
  contractNameInput.value = ''
  modalOffset.value = { x: 0, y: 0 }
}

const createContract = async () => {
  const name = contractNameInput.value.trim()
  if (!name) return

  if (editingContractId.value) {
    const current = contracts.value.find(item => item.id === editingContractId.value)
    if (!current) return
    if (current.name === name) {
      closeCreateModal()
      return
    }

    contracts.value = contracts.value.map(item =>
      item.id === editingContractId.value ? { ...item, name } : item
    )
    await saveContracts()
    notify('编辑成功')
    closeCreateModal()
    return
  }

  contracts.value = [
    ...contracts.value,
    {
      id: `ct-${Date.now()}-${Math.random().toString(16).slice(2, 6)}`,
      name,
      order: contracts.value.length,
      createdAt: new Date().toISOString()
    }
  ]

  await saveContracts()
  notify('新建成功')
  closeCreateModal()
}

const deleteContract = async (id: string) => {
  // 先关闭合同段及其咨询服务相关 tab，避免页面仍在运行时继续写回缓存
  removeRelatedTabsByContractId(id)
  await nextTick()
  await cleanupContractRelatedData(id)
  // 组件卸载时会异步保存一次，延迟再清一遍避免数据回写
  await new Promise(resolve => setTimeout(resolve, 80))
  await cleanupContractRelatedData(id)

  contracts.value = contracts.value.filter(item => item.id !== id)
  await saveContracts()
  notify('删除成功')
}

const handleDragEnd = async (event: { oldIndex?: number; newIndex?: number }) => {
  if (
    event.oldIndex == null ||
    event.newIndex == null ||
    event.oldIndex === event.newIndex
  ) {
    return
  }

  await saveContracts()
  notify('排序完成')
}

const handleCardClick = (item: ContractItem) => {
  tabStore.openTab({
    id: `contract-${item.id}`,
    title: `合同段${item.name}`,
    componentName: 'ContractDetailView',
    props: { contractId: item.id, contractName: item.name }
  })
}

const onDragMove = (event: MouseEvent) => {
  modalOffset.value = {
    x: baseOffsetX + (event.clientX - dragStartX),
    y: baseOffsetY + (event.clientY - dragStartY)
  }
}

const stopDrag = () => {
  window.removeEventListener('mousemove', onDragMove)
  window.removeEventListener('mouseup', stopDrag)
}

const startDrag = (event: MouseEvent) => {
  dragStartX = event.clientX
  dragStartY = event.clientY
  baseOffsetX = modalOffset.value.x
  baseOffsetY = modalOffset.value.y
  window.addEventListener('mousemove', onDragMove)
  window.addEventListener('mouseup', stopDrag)
}

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

onBeforeUnmount(() => {
  stopDrag()
  void saveContracts()
})
</script>

<template>
  <ToastProvider>
  <div>
    <div class="mb-6 flex items-center justify-between">
      <h3 class="text-lg font-bold">合同段列表</h3>
      <Button @click="openCreateModal">
        <Plus class="mr-2 h-4 w-4" />
        添加合同段
      </Button>
    </div>

    <draggable
      v-model="contracts"
      item-key="id"
      class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3"
      animation="200"
      @end="handleDragEnd"
    >
      <template #item="{ element }">
        <Card
          class="group cursor-pointer transition-colors hover:border-primary"
          @click="handleCardClick(element)"
        >
          <CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
            <CardTitle class="text-sm font-medium">
              <span class="ml-2">{{ element.name }}</span>
            </CardTitle>
            <div class="flex gap-1 opacity-0 transition-opacity group-hover:opacity-100">
              <Button
                variant="ghost"
                size="icon"
                class="h-7 w-7"
                @click.stop="openEditModal(element)"
              >
                <Edit3 class="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                class="h-7 w-7 text-destructive"
                @click.stop="deleteContract(element.id)"
              >
                <Trash2 class="h-4 w-4" />
              </Button>
            </div>
          </CardHeader>
          <div class="px-6 pb-4 text-xs text-muted-foreground">
            创建时间：{{ formatDateTime(element.createdAt) }}
          </div>
        </Card>
      </template>
    </draggable>

    <div
      v-if="showCreateModal"
      class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
    >
      <div
        class="w-full max-w-md rounded-lg border bg-background shadow-xl"
        :style="{ transform: `translate(${modalOffset.x}px, ${modalOffset.y}px)` }"
      >
        <div
          class="flex items-center justify-between border-b px-5 py-4 cursor-move select-none"
          @mousedown.prevent="startDrag"
        >
          <h4 class="text-base font-semibold">
            {{ editingContractId ? '编辑合同段' : '新增合同段' }}
          </h4>
          <Button variant="ghost" size="icon" class="h-8 w-8" @click="closeCreateModal">
            <X class="h-4 w-4" />
          </Button>
        </div>

        <div class="space-y-2 px-5 py-4">
          <label class="block text-sm font-medium text-foreground">合同段名称</label>
          <input
            v-model="contractNameInput"
            type="text"
            placeholder="请输入合同段名称"
            class="h-10 w-full rounded-md border bg-background px-3 text-sm outline-none transition focus-visible:ring-2 focus-visible:ring-ring"
            @keydown.enter="createContract"
          />
        </div>

        <div class="flex items-center justify-end gap-2 border-t px-5 py-3">
          <Button variant="outline" @click="closeCreateModal">取消</Button>
          <Button :disabled="!contractNameInput.trim()" @click="createContract">
            {{ editingContractId ? '保存' : '确定' }}
          </Button>
        </div>
      </div>
    </div>
  </div>
  <ToastRoot
    v-model:open="toastOpen"
    :duration="1800"
    class="group pointer-events-auto flex items-center gap-3 rounded-xl border border-slate-800/90 bg-slate-900 px-4 py-3 text-white shadow-xl"
  >
    <div class="grid gap-1">
      <ToastTitle class="text-sm font-semibold text-white">{{ toastTitle }}</ToastTitle>
      <ToastDescription class="text-xs text-slate-100">{{ toastText }}</ToastDescription>
    </div>
    <ToastAction
      alt-text="知道了"
      class="ml-auto inline-flex h-7 items-center rounded-md border border-white/30 bg-white/10 px-2 text-xs text-white hover:bg-white/20"
      @click="toastOpen = false"
    >
      知道了
    </ToastAction>
  </ToastRoot>
  <ToastViewport class="fixed bottom-5 right-5 z-[80] flex w-[380px] max-w-[92vw] flex-col gap-2 outline-none" />
  </ToastProvider>
</template>
