import { Plus, RefreshCcw, Save, Tags, Trash2 } from 'lucide-react'
import { startTransition, useCallback, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'

import { FormField } from '@/components/form-field'
import { MediaUrlControls } from '@/components/media-url-controls'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import { adminApi, ApiError } from '@/lib/api'
import { emptyToNull, formatDateTime } from '@/lib/admin-format'
import type { TagRecord, TaxonomyPayload } from '@/lib/types'

type TagFormState = {
  name: string
  slug: string
  description: string
  coverImage: string
  accentColor: string
  seoTitle: string
  seoDescription: string
}

const defaultTagForm: TagFormState = {
  name: '',
  slug: '',
  description: '',
  coverImage: '',
  accentColor: '',
  seoTitle: '',
  seoDescription: '',
}

function toFormState(item: TagRecord): TagFormState {
  return {
    name: item.name,
    slug: item.slug,
    description: item.description ?? '',
    coverImage: item.cover_image ?? '',
    accentColor: item.accent_color ?? '',
    seoTitle: item.seo_title ?? '',
    seoDescription: item.seo_description ?? '',
  }
}

function toPayload(form: TagFormState): TaxonomyPayload {
  return {
    name: form.name.trim(),
    slug: emptyToNull(form.slug),
    description: emptyToNull(form.description),
    coverImage: emptyToNull(form.coverImage),
    accentColor: emptyToNull(form.accentColor),
    seoTitle: emptyToNull(form.seoTitle),
    seoDescription: emptyToNull(form.seoDescription),
  }
}

export function TagsPage() {
  const [items, setItems] = useState<TagRecord[]>([])
  const [selectedId, setSelectedId] = useState<number | null>(null)
  const [form, setForm] = useState<TagFormState>(defaultTagForm)
  const [loading, setLoading] = useState(true)
  const [refreshing, setRefreshing] = useState(false)
  const [saving, setSaving] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const [searchTerm, setSearchTerm] = useState('')

  const loadTags = useCallback(async (showToast = false) => {
    try {
      if (showToast) {
        setRefreshing(true)
      }

      const next = await adminApi.listTags()
      startTransition(() => {
        setItems(next)
      })

      if (showToast) {
        toast.success('标签列表已刷新。')
      }
    } catch (error) {
      if (error instanceof ApiError && error.status === 401) {
        return
      }
      toast.error(error instanceof ApiError ? error.message : '无法加载标签列表。')
    } finally {
      setLoading(false)
      setRefreshing(false)
    }
  }, [])

  useEffect(() => {
    void loadTags(false)
  }, [loadTags])

  const filteredItems = useMemo(() => {
    const keyword = searchTerm.trim().toLowerCase()
    if (!keyword) {
      return items
    }

    return items.filter((item) =>
      [item.name, item.slug, item.description ?? '', item.seo_title ?? '']
        .join('\n')
        .toLowerCase()
        .includes(keyword),
    )
  }, [items, searchTerm])

  const selectedItem = useMemo(
    () => items.find((item) => item.id === selectedId) ?? null,
    [items, selectedId],
  )

  const resetForm = useCallback(() => {
    setSelectedId(null)
    setForm(defaultTagForm)
  }, [])

  const handleSave = useCallback(async () => {
    if (!form.name.trim()) {
      toast.error('请先填写标签名称。')
      return
    }

    try {
      setSaving(true)
      if (selectedId) {
        const updated = await adminApi.updateTag(selectedId, toPayload(form))
        startTransition(() => {
          setItems((current) => current.map((item) => (item.id === updated.id ? updated : item)))
          setSelectedId(updated.id)
          setForm(toFormState(updated))
        })
        toast.success('标签已更新。')
      } else {
        const created = await adminApi.createTag(toPayload(form))
        startTransition(() => {
          setItems((current) => [created, ...current])
          setSelectedId(created.id)
          setForm(toFormState(created))
        })
        toast.success('标签已创建。')
      }
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : '保存标签失败。')
    } finally {
      setSaving(false)
    }
  }, [form, selectedId])

  const handleDelete = useCallback(async () => {
    if (!selectedItem) {
      return
    }

    if (!window.confirm(`确认删除标签「${selectedItem.name}」吗？相关文章会同步移除该标签引用。`)) {
      return
    }

    try {
      setDeleting(true)
      await adminApi.deleteTag(selectedItem.id)
      startTransition(() => {
        setItems((current) => current.filter((item) => item.id !== selectedItem.id))
      })
      toast.success('标签已删除。')
      resetForm()
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : '删除标签失败。')
    } finally {
      setDeleting(false)
    }
  }, [resetForm, selectedItem])

  if (loading) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-40 rounded-3xl" />
        <Skeleton className="h-[720px] rounded-3xl" />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
        <div className="space-y-3">
          <Badge variant="secondary">标签管理</Badge>
          <div>
            <h2 className="text-3xl font-semibold tracking-tight">标签库</h2>
            <p className="mt-2 max-w-3xl text-sm leading-7 text-muted-foreground">
              标签现在也支持描述、封面、强调色和 SEO 字段，便于前台标签页做更像专题页的展示。
            </p>
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-3">
          <Button variant="outline" onClick={resetForm}>
            <Plus className="h-4 w-4" />
            新建标签
          </Button>
          <Button variant="secondary" onClick={() => void loadTags(true)} disabled={refreshing}>
            <RefreshCcw className="h-4 w-4" />
            {refreshing ? '刷新中...' : '刷新'}
          </Button>
        </div>
      </div>

      <div className="grid gap-6 xl:grid-cols-[0.92fr_1.08fr]">
        <Card>
          <CardHeader>
            <CardTitle>标签列表</CardTitle>
            <CardDescription>支持按名称、slug、描述和 SEO 标题检索。</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <Input
              data-testid="tags-search"
              placeholder="按标签名 / slug / 描述搜索"
              value={searchTerm}
              onChange={(event) => setSearchTerm(event.target.value)}
            />

            {filteredItems.length ? (
              <div className="space-y-3">
                {filteredItems.map((item) => (
                  <button
                    key={item.id}
                    type="button"
                    data-testid={`tag-item-${item.slug}`}
                    onClick={() => {
                      setSelectedId(item.id)
                      setForm(toFormState(item))
                    }}
                    className={`w-full rounded-3xl border px-4 py-4 text-left transition ${
                      selectedId === item.id
                        ? 'border-primary/30 bg-primary/10 shadow-[0_12px_30px_rgba(37,99,235,0.12)]'
                        : 'border-border/70 bg-background/60 hover:border-border'
                    }`}
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0 space-y-2">
                        <div className="flex flex-wrap items-center gap-2">
                          <span className="font-medium">{item.name}</span>
                          <Badge variant="outline">#{item.slug}</Badge>
                          {item.accent_color ? (
                            <span
                              className="inline-flex h-5 w-5 rounded-full border border-border/80"
                              style={{ backgroundColor: item.accent_color }}
                            />
                          ) : null}
                        </div>
                        <p className="text-sm text-muted-foreground">
                          {item.description || `${item.count} 篇文章引用了这个标签`}
                        </p>
                      </div>
                      <Badge variant={item.count > 0 ? 'success' : 'secondary'}>{item.count}</Badge>
                    </div>
                  </button>
                ))}
              </div>
            ) : (
              <div className="rounded-3xl border border-dashed border-border/70 bg-background/40 px-5 py-10 text-center text-sm text-muted-foreground">
                暂无匹配标签。
              </div>
            )}
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <div className="flex items-center gap-3">
              <div className="flex h-11 w-11 items-center justify-center rounded-2xl border border-primary/20 bg-primary/10 text-primary">
                <Tags className="h-5 w-5" />
              </div>
              <div>
                <CardTitle>{selectedItem ? '编辑标签' : '新建标签'}</CardTitle>
                <CardDescription>
                  标签除了基础名称，还可以直接补 SEO 信息与专题说明。
                </CardDescription>
              </div>
            </div>
          </CardHeader>
          <CardContent className="space-y-6">
            <div className="grid gap-4 lg:grid-cols-2">
              <FormField label="标签名称" hint="例如：astro、rust、workflow。">
                <Input
                  data-testid="tag-name-input"
                  value={form.name}
                  onChange={(event) => setForm((current) => ({ ...current, name: event.target.value }))}
                  placeholder="输入标签名称"
                />
              </FormField>
              <FormField label="标签 slug" hint="留空时自动从英文名称生成；中文建议手填。">
                <Input
                  data-testid="tag-slug-input"
                  value={form.slug}
                  onChange={(event) => setForm((current) => ({ ...current, slug: event.target.value }))}
                  placeholder="astro"
                />
              </FormField>
              <FormField label="封面图 URL" hint="可直接填写外链，也可以上传 / 抓取到媒体库后自动回填。">
                <div className="space-y-3">
                  <Input
                    value={form.coverImage}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, coverImage: event.target.value }))
                    }
                    placeholder="https://cdn.example.com/covers/astro.jpg"
                  />
                  <MediaUrlControls
                    value={form.coverImage}
                    onChange={(coverImage) =>
                      setForm((current) => ({ ...current, coverImage }))
                    }
                    prefix="tag-covers/"
                    contextLabel="标签封面上传"
                    remoteTitle={form.name || form.slug || '标签封面'}
                    dataTestIdPrefix="tag-cover"
                  />
                </div>
              </FormField>
              <FormField label="强调色" hint="可选，用于标签专题头部强调色。">
                <div className="flex items-center gap-3">
                  <Input
                    value={form.accentColor}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, accentColor: event.target.value }))
                    }
                    placeholder="#14b8a6"
                  />
                  <input
                    type="color"
                    value={form.accentColor || '#14b8a6'}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, accentColor: event.target.value }))
                    }
                    className="h-10 w-14 rounded-xl border border-input bg-background px-1"
                  />
                </div>
              </FormField>
            </div>

            <FormField label="标签描述" hint="用于前台标签卡片与专题说明。">
              <Textarea
                value={form.description}
                onChange={(event) =>
                  setForm((current) => ({ ...current, description: event.target.value }))
                }
                rows={4}
                placeholder="介绍这个标签常见主题、适合谁看。"
              />
            </FormField>

            <div className="grid gap-4 lg:grid-cols-2">
              <FormField label="SEO 标题" hint="留空时前台继续使用标签名拼接默认标题。">
                <Input
                  value={form.seoTitle}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, seoTitle: event.target.value }))
                  }
                  placeholder="Astro 相关文章 - Termi"
                />
              </FormField>
              <FormField label="SEO 描述" hint="搜索引擎摘要与分享描述。">
                <Textarea
                  value={form.seoDescription}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, seoDescription: event.target.value }))
                  }
                  rows={4}
                  placeholder="围绕 Astro、内容站与渲染策略的文章汇总。"
                />
              </FormField>
            </div>

            <div className="grid gap-4 rounded-3xl border border-border/70 bg-background/50 p-4 md:grid-cols-3">
              <div>
                <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">引用文章</p>
                <p className="mt-2 text-2xl font-semibold text-foreground">{selectedItem?.count ?? 0}</p>
              </div>
              <div>
                <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">创建时间</p>
                <p className="mt-2 text-sm text-muted-foreground">{formatDateTime(selectedItem?.created_at)}</p>
              </div>
              <div>
                <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">最近更新</p>
                <p className="mt-2 text-sm text-muted-foreground">{formatDateTime(selectedItem?.updated_at)}</p>
              </div>
            </div>

            <div className="flex flex-wrap items-center gap-3">
              <Button onClick={() => void handleSave()} disabled={saving} data-testid="tag-save">
                <Save className="h-4 w-4" />
                {saving ? '保存中...' : selectedItem ? '保存标签' : '创建标签'}
              </Button>
              <Button variant="outline" onClick={resetForm}>
                取消选择
              </Button>
              <Button
                variant="ghost"
                onClick={() => void handleDelete()}
                disabled={!selectedItem || deleting}
                data-testid="tag-delete"
                className="text-rose-600 hover:text-rose-600"
              >
                <Trash2 className="h-4 w-4" />
                {deleting ? '删除中...' : '删除标签'}
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>
    </div>
  )
}
