'use client';

import { useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { Plus, Pencil, Trash2, Folder, FileText, Loader2 } from 'lucide-react';
import { AdminHeader } from '@/components/admin/AdminHeader';
import { TableToolbar } from '@/components/admin/TableToolbar';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Badge } from '@/components/ui/badge';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { RichEditor } from '@/components/admin/RichEditor';
import { MarkdownImport } from '@/components/admin/MarkdownImport';
import { adminApi } from '@/lib/admin-services';
import { useAdminStore } from '@/store/adminStore';
import { cn } from '@/lib/utils';
import { isHTMLContent } from '@/lib/content';
import type { Manual, ManualContentFormat, ManualNodeType, ManualTreeNode } from '@/lib/types';

type ContentMode = 'rich' | 'markdown';

interface FormState {
  parentId: number | null;
  title: string;
  type: ManualNodeType;
  content: string;
  sort: number;
  isShow: number;
}

const FORM_DEFAULT: FormState = {
  parentId: null,
  title: '',
  type: 1,
  content: '',
  sort: 0,
  isShow: 1,
};

/** 将树形结构展平为带缩进层级的列表，便于在表格中展示 */
interface FlatRow extends Manual {
  _depth: number;
}
function flattenTree(nodes: ManualTreeNode[], depth = 0, acc: FlatRow[] = []): FlatRow[] {
  for (const n of nodes) {
    acc.push({
      id: n.id,
      parentId: n.parentId,
      title: n.title,
      type: n.type,
      content: null,
      contentFormat: 'html',
      sort: n.sort,
      isShow: n.isShow,
      createdAt: '',
      updatedAt: '',
      _depth: depth,
    });
    if (n.children.length > 0) {
      flattenTree(n.children, depth + 1, acc);
    }
  }
  return acc;
}

/** 生成父节点下拉的缩进选项（排除 selfId 及其子孙） */
function buildParentOptions(
  nodes: ManualTreeNode[],
  selfId: number | null,
): { id: number; label: string; depth: number }[] {
  const options: { id: number; label: string; depth: number }[] = [];
  const walk = (list: ManualTreeNode[], depth: number) => {
    for (const n of list) {
      if (n.id === selfId) continue;
      options.push({ id: n.id, label: n.title, depth });
      if (n.children.length > 0) walk(n.children, depth + 1);
    }
  };
  walk(nodes, 0);
  return options;
}

export default function ManualAdminPage() {
  const [hydrated, setHydrated] = useState(false);
  const [keyword, setKeyword] = useState('');
  const [searchKw, setSearchKw] = useState('');
  const [open, setOpen] = useState(false);
  const [editId, setEditId] = useState<number | null>(null);
  const [saving, setSaving] = useState(false);
  const [contentMode, setContentMode] = useState<ContentMode>('rich');
  const [form, setForm] = useState<FormState>(FORM_DEFAULT);

  const isSuperAdmin = useAdminStore((s) => s.admin?.role) === 'super_admin';

  useEffect(() => setHydrated(true), []);

  const { data: tree, isLoading, mutate } = useSWR<ManualTreeNode[]>(
    hydrated ? '/admin/manual/tree' : null,
    () => adminApi.manualTree(),
  );

  const rows = useMemo(() => {
    const flat = flattenTree(tree ?? []);
    if (!searchKw) return flat;
    return flat.filter((r) => r.title.toLowerCase().includes(searchKw.toLowerCase()));
  }, [tree, searchKw]);

  const parentOptions = useMemo(
    () => buildParentOptions(tree ?? [], editId),
    [tree, editId],
  );

  const openCreate = (presetParentId?: number | null) => {
    setEditId(null);
    setContentMode('rich');
    setForm({ ...FORM_DEFAULT, parentId: presetParentId ?? null });
    setOpen(true);
  };

  const openEdit = async (id: number) => {
    const detail = await adminApi.manualDetail(id);
    setEditId(id);
    // 优先使用持久化的 contentFormat；旧数据无该字段时回退到内容探测
    const detected =
      detail.contentFormat === 'markdown'
        ? 'markdown'
        : detail.content && isHTMLContent(detail.content)
          ? 'rich'
          : 'markdown';
    setContentMode(detected);
    setForm({
      parentId: detail.parentId,
      title: detail.title,
      type: detail.type,
      content: detail.content ?? '',
      sort: detail.sort,
      isShow: detail.isShow,
    });
    setOpen(true);
  };

  const onSave = async () => {
    if (!form.title.trim()) {
      alert('请填写标题');
      return;
    }
    setSaving(true);
    try {
      const contentFormat: ManualContentFormat =
        form.type === 0 || contentMode !== 'markdown' ? 'html' : 'markdown';
      const payload: Partial<Manual> = {
        parentId: form.parentId,
        title: form.title.trim(),
        type: form.type,
        content: form.type === 0 ? null : form.content,
        contentFormat,
        sort: form.sort,
        isShow: form.isShow,
      };
      if (editId) {
        await adminApi.manualUpdate(editId, payload);
      } else {
        await adminApi.manualCreate(payload);
      }
      setOpen(false);
      await mutate();
    } catch (e) {
      alert((e as Error).message);
    } finally {
      setSaving(false);
    }
  };

  const onDelete = async (id: number) => {
    if (!confirm('确认删除该节点？若其下有子节点需先删除子节点。')) return;
    try {
      await adminApi.manualDelete(id);
      await mutate();
    } catch (e) {
      alert((e as Error).message);
    }
  };

  return (
    <div>
      <AdminHeader
        title="使用手册"
        description="维护多级树形使用手册（目录 + 文档，文档支持富文本/Markdown）"
      />

      <TableToolbar
        left={
          <>
            <Input
              placeholder="搜索标题"
              value={keyword}
              onChange={(e) => setKeyword(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter') setSearchKw(keyword);
              }}
              className="max-w-xs"
            />
            <Button variant="outline" onClick={() => setSearchKw(keyword)}>
              搜索
            </Button>
          </>
        }
        right={
          <Button onClick={() => openCreate(null)}>
            <Plus className="h-4 w-4" /> 新增节点
          </Button>
        }
      />

      <div className="mt-4 rounded-md border border-gray-200">
        <Table>
          <TableHeader>
            <TableRow className="bg-gray-50">
              <TableHead style={{ width: 60 }}>ID</TableHead>
              <TableHead>标题 / 层级</TableHead>
              <TableHead style={{ width: 100 }}>类型</TableHead>
              <TableHead style={{ width: 80 }}>状态</TableHead>
              <TableHead style={{ width: 260 }}>操作</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {isLoading && (
              <TableRow>
                <TableCell colSpan={5} className="h-32">
                  <div className="flex items-center justify-center gap-2 text-gray-400">
                    <Loader2 className="h-5 w-5 animate-spin" />
                    <span className="text-sm">加载中…</span>
                  </div>
                </TableCell>
              </TableRow>
            )}
            {!isLoading && rows.length === 0 && (
              <TableRow>
                <TableCell colSpan={5} className="h-32 text-center text-gray-400">
                  暂无数据，请新增节点
                </TableCell>
              </TableRow>
            )}
            {rows.map((r) => (
              <TableRow key={r.id}>
                <TableCell className="text-gray-500">{r.id}</TableCell>
                <TableCell>
                  <div className="flex items-center">
                    {/* 缩进引导线：每层级一条垂直线 */}
                    {Array.from({ length: r._depth }).map((_, i) => (
                      <span key={i} className="flex w-6 justify-center">
                        <span className="h-6 w-px bg-gray-200" />
                      </span>
                    ))}
                    {/* 节点图标：目录=琥珀色底，文档=灰色底 */}
                    <span
                      className={cn(
                        'flex h-7 w-7 shrink-0 items-center justify-center rounded-md',
                        r.type === 0 ? 'bg-amber-50' : 'bg-slate-50',
                      )}
                    >
                      {r.type === 0 ? (
                        <Folder className="h-4 w-4 text-amber-500" />
                      ) : (
                        <FileText className="h-4 w-4 text-slate-400" />
                      )}
                    </span>
                    <span
                      className={cn(
                        'ml-2',
                        r.type === 0
                          ? 'font-semibold text-gray-900'
                          : 'font-medium text-gray-600',
                      )}
                    >
                      {r.title}
                    </span>
                  </div>
                </TableCell>
                <TableCell>
                  {r.type === 0 ? (
                    <Badge variant="warning">目录</Badge>
                  ) : (
                    <Badge variant="secondary">文档</Badge>
                  )}
                </TableCell>
                <TableCell>
                  {r.isShow === 1 ? (
                    <Badge variant="success">显示</Badge>
                  ) : (
                    <Badge variant="outline">隐藏</Badge>
                  )}
                </TableCell>
                <TableCell>
                  <div className="flex items-center gap-1.5 whitespace-nowrap">
                    {r.type === 0 && (
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => openCreate(r.id)}
                      >
                        <Plus className="h-3 w-3" /> 子节点
                      </Button>
                    )}
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={() => openEdit(r.id)}
                    >
                      <Pencil className="h-3 w-3" /> 编辑
                    </Button>
                    {isSuperAdmin && (
                      <Button
                        size="sm"
                        variant="destructive"
                        onClick={() => onDelete(r.id)}
                      >
                        <Trash2 className="h-3 w-3" /> 删除
                      </Button>
                    )}
                  </div>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </div>

      {/* 新增 / 编辑节点 */}
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>{editId ? '编辑节点' : '新增节点'}</DialogTitle>
          </DialogHeader>
          <div className="max-h-[70vh] space-y-4 overflow-y-auto pr-2">
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <Label>类型 *</Label>
                <div className="flex items-center gap-4 pt-1">
                  <label className="flex items-center gap-2 text-sm">
                    <input
                      type="radio"
                      name="node-type"
                      checked={form.type === 0}
                      onChange={() => setForm({ ...form, type: 0 })}
                    />
                    目录
                  </label>
                  <label className="flex items-center gap-2 text-sm">
                    <input
                      type="radio"
                      name="node-type"
                      checked={form.type === 1}
                      onChange={() => setForm({ ...form, type: 1 })}
                    />
                    文档
                  </label>
                </div>
              </div>
              <div className="space-y-1.5">
                <Label>父节点</Label>
                <select
                  className="h-10 w-full rounded-md border border-gray-300 px-3 text-sm"
                  value={form.parentId ?? ''}
                  onChange={(e) =>
                    setForm({
                      ...form,
                      parentId: e.target.value ? Number(e.target.value) : null,
                    })
                  }
                >
                  <option value="">（顶级）</option>
                  {parentOptions.map((opt) => (
                    <option key={opt.id} value={opt.id}>
                      {`${'　'.repeat(opt.depth)}${opt.depth > 0 ? '└ ' : ''}${opt.label}`}
                    </option>
                  ))}
                </select>
              </div>
            </div>

            <div className="space-y-1.5">
              <Label>标题 *</Label>
              <Input
                value={form.title}
                maxLength={200}
                onChange={(e) => setForm({ ...form, title: e.target.value })}
                placeholder={form.type === 0 ? '目录名称' : '文档标题'}
              />
            </div>

            {form.type === 1 && (
              <div className="space-y-1.5">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <Label>正文内容</Label>
                  <div className="flex items-center gap-2">
                    <div className="flex rounded-md border border-gray-200 p-0.5">
                      <button
                        type="button"
                        onClick={() => setContentMode('rich')}
                        className={cn(
                          'rounded px-2.5 py-0.5 text-xs transition-colors',
                          contentMode === 'rich'
                            ? 'bg-brand-600 text-white'
                            : 'text-gray-600 hover:text-gray-900',
                        )}
                      >
                        富文本
                      </button>
                      <button
                        type="button"
                        onClick={() => setContentMode('markdown')}
                        className={cn(
                          'rounded px-2.5 py-0.5 text-xs transition-colors',
                          contentMode === 'markdown'
                            ? 'bg-brand-600 text-white'
                            : 'text-gray-600 hover:text-gray-900',
                        )}
                      >
                        Markdown
                      </button>
                    </div>
                    {contentMode === 'markdown' && (
                      <MarkdownImport
                        onImport={(md) => setForm({ ...form, content: md })}
                        onError={(msg) => alert(msg)}
                      />
                    )}
                  </div>
                </div>
                {contentMode === 'rich' ? (
                  <RichEditor
                    value={form.content}
                    onChange={(html) => setForm({ ...form, content: html })}
                  />
                ) : (
                  <Textarea
                    rows={12}
                    placeholder="支持 Markdown 语法。可点击右上角上传 .md 文档"
                    className="font-mono text-sm"
                    value={form.content}
                    onChange={(e) =>
                      setForm({ ...form, content: e.target.value })
                    }
                  />
                )}
              </div>
            )}

            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <Label>排序（越小越靠前）</Label>
                <Input
                  type="number"
                  value={form.sort}
                  onChange={(e) =>
                    setForm({ ...form, sort: Number(e.target.value) })
                  }
                />
              </div>
              <div className="space-y-1.5">
                <Label>状态</Label>
                <select
                  className="h-10 w-full rounded-md border border-gray-300 px-3 text-sm"
                  value={form.isShow}
                  onChange={(e) =>
                    setForm({ ...form, isShow: Number(e.target.value) })
                  }
                >
                  <option value={1}>显示</option>
                  <option value={0}>隐藏</option>
                </select>
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setOpen(false)}>
              取消
            </Button>
            <Button onClick={onSave} disabled={saving}>
              {saving ? (
                <>
                  <Loader2 className="h-4 w-4 animate-spin" />
                  保存中…
                </>
              ) : (
                '保存'
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
