<template>
  <AppShell>
    <NSpin :show="loading">
      <div class="space-y-4">
        <!-- Header -->
        <div class="flex items-center justify-between">
          <h1 class="text-2xl font-semibold">Issue 列表</h1>
          <NButton type="primary" @click="showCreate = true">新建 Issue</NButton>
        </div>

        <!-- Filter chips -->
        <div class="flex items-center gap-2 flex-wrap">
          <NButton
            :type="filter === 'all' ? 'primary' : 'default'"
            size="small"
            @click="setFilter('all')"
          >
            全部
          </NButton>
          <NButton
            :type="filter === 'none' ? 'primary' : 'default'"
            size="small"
            @click="setFilter('none')"
          >
            游离
          </NButton>
          <NButton
            v-for="req in requirements"
            :key="req.number"
            :type="filter === String(req.number) ? 'primary' : 'default'"
            size="small"
            @click="setFilter(String(req.number))"
          >
            R-{{ req.number }}
          </NButton>
        </div>

        <!-- Table -->
        <NDataTable
          :columns="columns"
          :data="items"
          :row-props="rowProps"
          :bordered="false"
          striped
        />

        <div v-if="!loading && items.length === 0" class="text-gray-400 text-sm py-8 text-center">
          暂无 Issue。
        </div>
      </div>
    </NSpin>

    <!-- Create modal -->
    <NModal v-model:show="showCreate" preset="card" title="新建 Issue" class="w-full max-w-md">
      <NForm @submit.prevent="onSubmit">
        <NFormItem label="标题">
          <NInput v-model:value="form.title" placeholder="Issue 标题" />
        </NFormItem>
        <NFormItem label="描述">
          <NInput v-model:value="form.description" type="textarea" :rows="4" placeholder="（可选）" />
        </NFormItem>
        <NFormItem label="挂载到 Requirement（可选）">
          <NSelect
            v-model:value="form.requirement_number"
            :options="requirementOptions"
            placeholder="不挂载"
            clearable
          />
        </NFormItem>
        <div class="flex justify-end gap-2 mt-4">
          <NButton @click="showCreate = false">取消</NButton>
          <NButton type="primary" attr-type="submit" :loading="creating">创建</NButton>
        </div>
      </NForm>
      <p v-if="createError" class="text-red-500 text-sm mt-2">{{ createError }}</p>
    </NModal>
  </AppShell>
</template>

<script setup lang="ts">
import { h, ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
  NButton,
  NTag,
  NDataTable,
  NModal,
  NForm,
  NFormItem,
  NInput,
  NSelect,
  NSpin,
} from 'naive-ui'
import type { DataTableColumns } from 'naive-ui'
import AppShell from '@/layouts/AppShell.vue'
import { projectsApi } from '@/api/projects'
import type { Issue, Requirement } from '@/api/projects'

const route = useRoute()
const router = useRouter()

const slug = route.params.slug as string

const loading = ref(false)
const items = ref<Issue[]>([])
const requirements = ref<Requirement[]>([])
const filter = ref<'all' | 'none' | string>('all')

const requirementOptions = computed(() =>
  requirements.value.map((r) => ({ label: `R-${r.number}: ${r.title}`, value: r.number })),
)

async function fetchIssues() {
  loading.value = true
  try {
    const params: { requirement?: number | 'none' } = {}
    if (filter.value === 'none') {
      params.requirement = 'none'
    } else if (filter.value !== 'all') {
      params.requirement = Number(filter.value)
    }
    const res = await projectsApi.listIssues(slug, params)
    items.value = res.items
  } finally {
    loading.value = false
  }
}

async function setFilter(value: 'all' | 'none' | string) {
  filter.value = value
  await fetchIssues()
}

// ---- Table columns ----
const columns: DataTableColumns<Issue> = [
  {
    title: '#',
    key: 'number',
    width: 60,
    render: (row) => h('span', { class: 'font-mono text-xs text-gray-400' }, `#${row.number}`),
  },
  {
    title: '标题',
    key: 'title',
  },
  {
    title: 'Requirement',
    key: 'requirement_id',
    width: 120,
    render: (row) => {
      if (!row.requirement_id) return h('span', { class: 'text-gray-300 text-xs' }, '—')
      const req = requirements.value.find((r) => r.id === row.requirement_id)
      return req
        ? h(NTag, { size: 'small' }, { default: () => `R-${req.number}` })
        : h('span', { class: 'text-gray-300 text-xs' }, '—')
    },
  },
  {
    title: '状态',
    key: 'status',
    width: 80,
    render: (row) =>
      h(
        NTag,
        { size: 'small', type: row.status === 'open' ? 'success' : 'default' },
        { default: () => (row.status === 'open' ? '开放' : '关闭') },
      ),
  },
]

function rowProps(row: Issue) {
  return {
    style: 'cursor: pointer',
    onClick: () => router.push({ name: 'issue-detail', params: { slug, number: row.number } }),
  }
}

// ---- Create modal ----
const showCreate = ref(false)
const creating = ref(false)
const createError = ref('')
const form = ref<{ title: string; description: string; requirement_number: number | null }>({
  title: '',
  description: '',
  requirement_number: null,
})

async function onSubmit() {
  createError.value = ''
  if (!form.value.title.trim()) {
    createError.value = '标题不能为空'
    return
  }
  creating.value = true
  try {
    const body: { title: string; description?: string; requirement_number?: number } = {
      title: form.value.title,
    }
    if (form.value.description) body.description = form.value.description
    if (form.value.requirement_number !== null) body.requirement_number = form.value.requirement_number
    const created = await projectsApi.createIssue(slug, body)
    showCreate.value = false
    form.value = { title: '', description: '', requirement_number: null }
    router.push({ name: 'issue-detail', params: { slug, number: created.number } })
  } catch (e) {
    createError.value = e instanceof Error ? e.message : '创建失败'
  } finally {
    creating.value = false
  }
}

onMounted(async () => {
  const [, reqs] = await Promise.all([fetchIssues(), projectsApi.listRequirements(slug)])
  requirements.value = reqs.items
})
</script>
