<template>
  <UCard>
    <template #header>
      <div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
        <div class="flex flex-wrap items-center gap-3">
          <div class="flex items-center gap-2">
            <UIcon name="i-heroicons-squares-2x2-20-solid" class="h-5 w-5 text-sky-400" />
            <span class="text-lg font-semibold">{{ appTitle }}</span>
          </div>
          <UBadge
            :color="store.dirty ? 'primary' : 'neutral'"
            variant="soft"
            class="text-xs"
          >
            {{ fileStatus }}
          </UBadge>
        </div>
        <div class="flex flex-wrap items-center gap-2">
          <UButton color="neutral" variant="soft" icon="i-heroicons-folder-open-20-solid" @click="triggerOpen">
            打开文件
          </UButton>
          <UButton color="primary" icon="i-heroicons-arrow-down-tray-20-solid" @click="onSave">
            导出 JSON
          </UButton>
          <UButton color="neutral" variant="soft" icon="i-heroicons-arrow-path-rounded-square-20-solid" @click="triggerImport">
            导入/合并
          </UButton>
          <UButton color="neutral" variant="ghost" icon="i-heroicons-plus-circle-20-solid" @click="newOpen = true">
            新建看板
          </UButton>
          <UDropdown :items="localMenu" mode="hover">
            <UButton color="neutral" variant="ghost" icon="i-heroicons-device-phone-mobile-20-solid">
              本地存储
            </UButton>
          </UDropdown>
        </div>
      </div>
    </template>

    <div class="grid gap-3 lg:grid-cols-4">
      <UInput
        v-model="q"
        icon="i-heroicons-magnifying-glass-20-solid"
        placeholder="搜索任务（标题或描述）"
        color="neutral"
      />
      <USelectMenu
        v-model="cat"
        :options="categoryOptions"
        value-attribute="value"
        option-attribute="label"
        searchable
        placeholder="筛选类别"
      />
      <UInput
        v-model="actor"
        icon="i-heroicons-user-circle-20-solid"
        placeholder="记录操作人名称（写入历史）"
      />
      <div class="flex items-center justify-end text-xs text-slate-400">
        最近保存于：{{ lastSaved }}
      </div>
    </div>
  </UCard>

  <input ref="openInput" type="file" accept="application/json" class="hidden" @change="handleOpen" />
  <input ref="importInput" type="file" accept="application/json" class="hidden" @change="handleImport" />

  <UModal v-model="newOpen">
    <UCard>
      <template #header>
        <div class="flex items-center gap-2">
          <UIcon name="i-heroicons-plus-circle-20-solid" class="h-5 w-5 text-sky-400" />
          <span class="font-semibold">新建看板</span>
        </div>
      </template>
      <div class="space-y-4 text-sm text-slate-300">
        <p>当前更改尚未导出。继续新建将清空现有看板数据。</p>
      </div>
      <div class="mt-6 flex justify-end gap-2">
        <UButton color="neutral" variant="ghost" @click="newOpen = false">取消</UButton>
        <UButton color="primary" @click="createNewBoard">确认新建</UButton>
      </div>
    </UCard>
  </UModal>

  <UModal v-model="clearLocalOpen">
    <UCard>
      <template #header>
        <div class="flex items-center gap-2">
          <UIcon name="i-heroicons-exclamation-triangle-20-solid" class="h-5 w-5 text-amber-400" />
          <span class="font-semibold">清空本地缓存</span>
        </div>
      </template>
      <p class="text-sm text-slate-300">
        清空后将无法恢复，确认继续吗？
      </p>
      <div class="mt-6 flex justify-end gap-2">
        <UButton color="neutral" variant="ghost" @click="clearLocalOpen = false">取消</UButton>
        <UButton color="rose" @click="clearLocalData">清空数据</UButton>
      </div>
    </UCard>
  </UModal>
</template>

<script setup lang="ts">
import { useBoardStore } from '~/stores/board'

const store = useBoardStore()
const config = useRuntimeConfig().public
const toast = useToast()

const appTitle = computed(() => config.appTitle)
const actor = computed({
  get: () => store.board.meta?.actor || '',
  set: (v: string) => store.setActor(v)
})
const q = defineModel<string>('query', { required: true })
const cat = defineModel<string | ''>('category', { required: true })

const openInput = ref<HTMLInputElement | null>(null)
const importInput = ref<HTMLInputElement | null>(null)

const categoryOptions = computed(() => [
  { label: '全部类别', value: '' },
  ...store.board.categories.map((c) => ({ label: c.title, value: c.uuid }))
])

const fileStatus = computed(() => {
  const name = store.filename || '未命名'
  const indicator = store.dirty ? '（未保存修改）' : '（已同步）'
  return `${name} ${indicator}`
})

const lastSaved = computed(() => {
  const ts = store.board.meta?.modifiedAt
  if (!ts) return '尚未记录'
  try {
    return new Intl.DateTimeFormat('zh-CN', { dateStyle: 'short', timeStyle: 'short' }).format(new Date(ts))
  } catch {
    return ts
  }
})

function triggerOpen() {
  openInput.value?.click()
}

function triggerImport() {
  importInput.value?.click()
}

function handleOpen(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file) return
  const reader = new FileReader()
  reader.onload = () => {
    try {
      const json = JSON.parse(String(reader.result))
      store.setBoard(json, file.name)
      store.log('load-file', { name: file.name, size: file.size })
      toast.add({ color: 'primary', title: `已载入 ${file.name}` })
    } catch (err: any) {
      toast.add({ color: 'rose', title: '解析 JSON 失败', description: err?.message })
    }
  }
  reader.readAsText(file)
  input.value = ''
}

const emit = defineEmits<{ (e: 'open-merge', imported: any, diff: any, name: string): void }>()

function handleImport(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file) return
  const reader = new FileReader()
  reader.onload = () => {
    try {
      const data = JSON.parse(String(reader.result))
      const diff = store.diffBoards(store.board as any, data)
      emit('open-merge', data, diff, file.name)
      toast.add({ color: 'neutral', title: `已分析 ${file.name}` })
    } catch (err: any) {
      toast.add({ color: 'rose', title: '解析 JSON 失败', description: err?.message })
    }
  }
  reader.readAsText(file)
  input.value = ''
}

function onSave() {
  store.downloadCurrent()
  toast.add({ color: 'primary', title: '已导出文件' })
}

const newOpen = ref(false)

function createNewBoard() {
  store.setBoard(
    {
      categories: [],
      stages: [],
      tasks: [],
      layout: { columns: [] },
      meta: {
        id: 'open-kanban',
        version: '1.0.0',
        createdAt: new Date().toISOString(),
        modifiedAt: new Date().toISOString(),
        actor: store.board.meta?.actor,
        history: []
      }
    },
    ''
  )
  store.log('new-board', {})
  toast.add({ color: 'neutral', title: '已创建新的空白看板' })
  newOpen.value = false
}

function loadLocal() {
  if (!store.loadFromLocal()) {
    toast.add({ color: 'rose', title: '本地没有保存的数据' })
    return
  }
  toast.add({ color: 'neutral', title: '已从本地加载看板' })
}

function saveLocal() {
  store.saveToLocal()
  toast.add({ color: 'primary', title: '已同步至本地存储' })
}

const clearLocalOpen = ref(false)

function clearLocalData() {
  store.clearLocal()
  toast.add({ color: 'neutral', title: '本地数据已清空' })
  clearLocalOpen.value = false
}

const localMenu = computed(() => [
  [
    {
      label: '保存至本地',
      icon: 'i-heroicons-arrow-down-on-square-20-solid',
      click: () => saveLocal()
    },
    {
      label: '从本地恢复',
      icon: 'i-heroicons-arrow-up-on-square-20-solid',
      click: () => loadLocal()
    }
  ],
  [
    {
      label: '清空本地缓存',
      icon: 'i-heroicons-trash-20-solid',
      click: () => {
        clearLocalOpen.value = true
      },
      color: 'rose'
    }
  ]
])
</script>
