import { useEffect, useMemo, useState } from 'react';
import {
  Award, Pencil, Plus, Search, Sparkles, Trophy,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Switch } from '@/components/ui/switch';
import { Spinner } from '@/components/ui/spinner';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { notify } from '@/lib/notify';
import { cn } from '@/lib/utils';
import { api } from '../../api/client';
import { useAdminGuard } from '../../layouts/AdminLayout';
import type { BadgeDef } from '../../api/types';
import {
  BADGE_ICON_OPTIONS,
  BADGE_METRIC_OPTIONS,
  badgeIcon,
  formatBadgeCondition,
} from '../../utils/badgeIcons';
import AdminSortableList, { SortableDragHandle, SortableMoveButtons } from '../../components/admin/AdminSortableList';
import { mergeReorderedSubset, persistSortOrderChanges, shouldShowSortableMoveButtons } from '../../utils/sortOrder';

type KindTab = 'all' | 'auto' | 'limited';

const EMPTY: Partial<BadgeDef> = {
  code: '',
  name: '',
  description: '',
  icon: 'star',
  kind: 'limited',
  metric: 'tenure_days',
  threshold: 30,
  sort_order: 100,
  enabled: true,
};

function slugifyCode(name: string): string {
  const ascii = name
    .trim()
    .toLowerCase()
    .replace(/\s+/g, '_')
    .replace(/[^a-z0-9_-]/g, '');
  return ascii.slice(0, 32) || `badge_${Date.now().toString(36)}`;
}

/** 后台：徽章定义（卡片预览 + 弹窗编辑） */
export default function AdminBadgesPage() {
  const { ready } = useAdminGuard();
  const [rows, setRows] = useState<BadgeDef[]>([]);
  const [loading, setLoading] = useState(true);
  const [tab, setTab] = useState<KindTab>('all');
  const [query, setQuery] = useState('');
  const [dialogOpen, setDialogOpen] = useState(false);
  const [form, setForm] = useState<Partial<BadgeDef>>({ ...EMPTY });
  const [saving, setSaving] = useState(false);
  const [togglingId, setTogglingId] = useState<number | null>(null);
  const [reordering, setReordering] = useState(false);

  const load = () => {
    setLoading(true);
    api.adminListBadges()
      .then(d => setRows(d.badges ?? []))
      .catch(e => notify.error(e.message))
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    if (ready) load();
  }, [ready]);

  const counts = useMemo(() => ({
    all: rows.length,
    auto: rows.filter(b => b.kind === 'auto').length,
    limited: rows.filter(b => b.kind === 'limited').length,
    disabled: rows.filter(b => !b.enabled).length,
  }), [rows]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    return rows.filter(b => {
      if (tab === 'auto' && b.kind !== 'auto') return false;
      if (tab === 'limited' && b.kind !== 'limited') return false;
      if (!q) return true;
      return [b.code, b.name, b.description, b.icon, b.metric]
        .join(' ')
        .toLowerCase()
        .includes(q);
    });
  }, [rows, tab, query]);

  const openCreate = () => {
    setForm({ ...EMPTY });
    setDialogOpen(true);
  };

  const openEdit = (b: BadgeDef) => {
    setForm({ ...b });
    setDialogOpen(true);
  };

  const save = async () => {
    const name = form.name?.trim() || '';
    let code = form.code?.trim() || '';
    if (!name) {
      notify.warning('请填写徽章名称');
      return;
    }
    if (!form.id && !code) {
      code = slugifyCode(name);
    }
    if (!code) {
      notify.warning('请填写徽章代码');
      return;
    }
    if (form.kind === 'auto' && !form.metric) {
      notify.warning('请选择自动成就指标');
      return;
    }
    setSaving(true);
    try {
      const r = await api.adminUpsertBadge({
        ...form,
        code,
        name,
        kind: form.kind || 'limited',
        metric: form.kind === 'auto' ? (form.metric || 'tenure_days') : '',
        threshold: form.kind === 'auto' ? (form.threshold ?? 0) : 0,
        icon: form.icon || 'star',
        enabled: form.enabled !== false,
      });
      notify.success(r.message);
      setDialogOpen(false);
      resetForm();
      load();
    } catch (e: unknown) {
      notify.error(e instanceof Error ? e.message : '保存失败');
    } finally {
      setSaving(false);
    }
  };

  const resetForm = () => setForm({ ...EMPTY });

  const toggleEnabled = async (b: BadgeDef) => {
    setTogglingId(b.id);
    try {
      await api.adminUpsertBadge({ ...b, enabled: !b.enabled });
      notify.success(b.enabled ? '已停用' : '已启用');
      load();
    } catch (e: unknown) {
      notify.error(e instanceof Error ? e.message : '操作失败');
    } finally {
      setTogglingId(null);
    }
  };

  const handleBadgeReorder = async (reorderedFiltered: BadgeDef[]) => {
    const subsetBefore = [...filtered];
    const before = [...rows];
    setReordering(true);
    try {
      const merged = mergeReorderedSubset(before, subsetBefore, reorderedFiltered);
      const after = await persistSortOrderChanges(before, merged, badge =>
        api.adminUpsertBadge({ ...badge, sort_order: badge.sort_order }),
      );
      setRows(after);
      notify.success('徽章排序已更新');
    } catch (e: unknown) {
      setRows(before);
      notify.error(e instanceof Error ? e.message : '排序保存失败');
    } finally {
      setReordering(false);
    }
  };

  const showMoveButtons = shouldShowSortableMoveButtons(filtered.length);

  if (!ready) return null;

  const PreviewIcon = badgeIcon(form.icon);
  const isEdit = !!form.id;

  return (
    <div className="admin-page">
      <div className="admin-page-head">
        <div className="admin-page-head-row">
          <div>
            <h1>徽章管理</h1>
            <p>设计自动成就与限定徽章；限定徽章在「用户管理」中颁发给用户</p>
          </div>
          <Button onClick={openCreate}>
            <Plus size={16} />
            新建徽章
          </Button>
        </div>
      </div>

      <div className="admin-badge-stats" aria-label="徽章统计">
        <div className="admin-badge-stat">
          <strong>{counts.all}</strong>
          <span>全部</span>
        </div>
        <div className="admin-badge-stat">
          <strong>{counts.auto}</strong>
          <span>自动成就</span>
        </div>
        <div className="admin-badge-stat">
          <strong>{counts.limited}</strong>
          <span>限定徽章</span>
        </div>
        <div className="admin-badge-stat">
          <strong>{counts.disabled}</strong>
          <span>已停用</span>
        </div>
      </div>

      <div className="admin-badge-toolbar">
        <div className="admin-tabs" role="tablist" aria-label="徽章类型">
          {([
            ['all', '全部'],
            ['auto', '自动成就'],
            ['limited', '限定徽章'],
          ] as const).map(([key, label]) => (
            <button
              key={key}
              type="button"
              role="tab"
              aria-selected={tab === key}
              className={cn('admin-tab', tab === key && 'active')}
              onClick={() => setTab(key)}
            >
              {label}
            </button>
          ))}
        </div>
        <div className="admin-badge-search">
          <Search size={15} aria-hidden />
          <Input
            value={query}
            onChange={e => setQuery(e.target.value)}
            placeholder="搜索名称、代码、说明…"
            aria-label="搜索徽章"
          />
        </div>
      </div>

      {loading ? (
        <div className="flex justify-center py-16"><Spinner size="lg" /></div>
      ) : filtered.length === 0 ? (
        <div className="admin-badge-empty">
          <Award size={36} strokeWidth={1.25} aria-hidden />
          <h3>{query ? '没有匹配的徽章' : '还没有徽章'}</h3>
          <p>
            {query
              ? '试试其他关键词，或切换类型筛选'
              : '创建自动成就（达条件发放）或限定徽章（站长颁发）'}
          </p>
          {!query && (
            <Button onClick={openCreate}>
              <Plus size={16} />
              创建第一个徽章
            </Button>
          )}
        </div>
      ) : (
        <AdminSortableList
          strategy="grid"
          className="admin-badge-grid"
          items={filtered}
          getId={b => b.id}
          onReorder={handleBadgeReorder}
          showMoveButtons="auto"
          ariaLabel="徽章列表排序"
          renderItem={(b, _index, controls) => {
            const Icon = badgeIcon(b.icon);
            return (
              <article
                ref={controls.setNodeRef}
                style={controls.style}
                className={cn(
                  'admin-badge-card',
                  'admin-sortable-grid-item',
                  !b.enabled && 'is-disabled',
                  controls.isDragging && 'is-dragging',
                )}
              >
                <div className="admin-sortable-grid-item__handle-wrap">
                  <SortableDragHandle label={`拖拽调整「${b.name}」顺序`} {...controls.dragHandleProps} />
                </div>
                <div className="admin-badge-card-top">
                  <div className={cn('admin-badge-preview', b.kind === 'limited' && 'is-limited')}>
                    <Icon size={22} aria-hidden />
                  </div>
                  <div className="admin-badge-card-meta">
                    <div className="admin-badge-card-title-row">
                      <h3>{b.name}</h3>
                      {b.kind === 'auto'
                        ? <Badge variant="secondary">自动</Badge>
                        : <Badge variant="orange">限定</Badge>}
                      {!b.enabled && <Badge variant="destructive">停用</Badge>}
                    </div>
                    <code className="admin-badge-code">{b.code}</code>
                  </div>
                </div>

                <p className="admin-badge-desc">
                  {b.description?.trim() || (b.kind === 'limited' ? '站长手动颁发的限定徽章' : '达成条件后自动获得')}
                </p>

                <div className="admin-badge-card-foot">
                  <span className="admin-badge-condition" title="获得条件">
                    {b.kind === 'auto' ? <Sparkles size={13} aria-hidden /> : <Trophy size={13} aria-hidden />}
                    {formatBadgeCondition(b)}
                  </span>
                  <div className="admin-badge-card-actions">
                    {showMoveButtons && <SortableMoveButtons controls={controls} />}
                    <label className="admin-badge-switch" title={b.enabled ? '点击停用' : '点击启用'}>
                      <span className="sr-only">启用</span>
                      <Switch
                        checked={b.enabled}
                        disabled={togglingId === b.id || reordering}
                        onCheckedChange={() => toggleEnabled(b)}
                      />
                    </label>
                    <Button size="sm" variant="outline" onClick={() => openEdit(b)} disabled={reordering}>
                      <Pencil size={13} />
                      编辑
                    </Button>
                  </div>
                </div>
              </article>
            );
          }}
        />
      )}

      <Dialog open={dialogOpen} onOpenChange={(open) => {
        setDialogOpen(open);
        if (!open) resetForm();
      }}>
        <DialogContent className="admin-badge-dialog sm:max-w-xl">
          <DialogHeader>
            <DialogTitle>{isEdit ? '编辑徽章' : '新建徽章'}</DialogTitle>
            <DialogDescription>
              {isEdit
                ? '修改后立即对展示生效；代码不可更改。'
                : '自动成就按指标发放，限定徽章需在用户管理中手动颁发。'}
            </DialogDescription>
          </DialogHeader>

          <div className="admin-badge-dialog-preview">
            <div className={cn('admin-badge-preview admin-badge-preview--lg', form.kind === 'limited' && 'is-limited')}>
              <PreviewIcon size={28} aria-hidden />
            </div>
            <div>
              <div className="admin-badge-dialog-preview-name">{form.name?.trim() || '徽章名称'}</div>
              <div className="admin-badge-dialog-preview- Cond">
                {formatBadgeCondition({
                  kind: form.kind,
                  metric: form.metric,
                  threshold: form.threshold,
                  description: form.description,
                })}
              </div>
            </div>
          </div>

          <div className="admin-badge-dialog-fields">
            <div className="admin-badge-kind-seg" role="group" aria-label="徽章类型">
              <button
                type="button"
                className={cn(form.kind !== 'limited' && 'active')}
                onClick={() => setForm(f => ({ ...f, kind: 'auto', metric: f.metric || 'tenure_days' }))}
              >
                <Sparkles size={14} />
                自动成就
              </button>
              <button
                type="button"
                className={cn(form.kind === 'limited' && 'active')}
                onClick={() => setForm(f => ({ ...f, kind: 'limited' }))}
              >
                <Trophy size={14} />
                限定徽章
              </button>
            </div>

            <div className="admin-badge-field-row">
              <div className="admin-badge-field">
                <Label htmlFor="badge-name">名称</Label>
                <Input
                  id="badge-name"
                  value={form.name || ''}
                  onChange={e => {
                    const name = e.target.value;
                    setForm(f => ({
                      ...f,
                      name,
                      code: isEdit ? f.code : (f.code?.trim() ? f.code : slugifyCode(name)),
                    }));
                  }}
                  placeholder="例如：资深居民"
                  autoFocus
                />
              </div>
              <div className="admin-badge-field">
                <Label htmlFor="badge-code">代码</Label>
                <Input
                  id="badge-code"
                  value={form.code || ''}
                  onChange={e => setForm(f => ({ ...f, code: e.target.value }))}
                  placeholder="tenure_365"
                  disabled={isEdit}
                  className="font-mono text-sm"
                />
              </div>
            </div>

            <div className="admin-badge-field">
              <Label htmlFor="badge-desc">说明</Label>
              <Input
                id="badge-desc"
                value={form.description || ''}
                onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
                placeholder="鼠标悬停时显示的获得条件"
              />
            </div>

            <div className="admin-badge-field">
              <Label>图标</Label>
              <div className="admin-badge-icon-picker" role="listbox" aria-label="选择图标">
                {BADGE_ICON_OPTIONS.map(opt => {
                  const active = (form.icon || 'star') === opt.key;
                  return (
                    <button
                      key={opt.key}
                      type="button"
                      role="option"
                      aria-selected={active}
                      title={opt.label}
                      className={cn('admin-badge-icon-opt', active && 'active')}
                      onClick={() => setForm(f => ({ ...f, icon: opt.key }))}
                    >
                      <opt.Icon size={18} aria-hidden />
                    </button>
                  );
                })}
              </div>
            </div>

            {form.kind === 'auto' && (
              <div className="admin-badge-field-row">
                <div className="admin-badge-field">
                  <Label htmlFor="badge-metric">达成指标</Label>
                  <select
                    id="badge-metric"
                    className="admin-select"
                    value={form.metric || 'tenure_days'}
                    onChange={e => setForm(f => ({ ...f, metric: e.target.value }))}
                  >
                    {BADGE_METRIC_OPTIONS.map(m => (
                      <option key={m.value} value={m.value}>{m.label}</option>
                    ))}
                  </select>
                  <span className="admin-badge-field-hint">
                    {BADGE_METRIC_OPTIONS.find(m => m.value === (form.metric || 'tenure_days'))?.hint}
                  </span>
                </div>
                <div className="admin-badge-field">
                  <Label htmlFor="badge-threshold">阈值</Label>
                  <Input
                    id="badge-threshold"
                    type="number"
                    min={0}
                    value={form.threshold ?? 0}
                    onChange={e => setForm(f => ({ ...f, threshold: Number(e.target.value) || 0 }))}
                  />
                </div>
              </div>
            )}

            <div className="admin-badge-field-row admin-badge-field-row--end">
              <div className="admin-badge-field">
                <Label htmlFor="badge-sort">排序权重</Label>
                <Input
                  id="badge-sort"
                  type="number"
                  value={form.sort_order ?? 100}
                  onChange={e => setForm(f => ({ ...f, sort_order: Number(e.target.value) || 0 }))}
                />
              </div>
              <label className="admin-badge-enable-row">
                <Switch
                  checked={form.enabled !== false}
                  onCheckedChange={v => setForm(f => ({ ...f, enabled: v }))}
                />
                <span>启用此徽章</span>
              </label>
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)} disabled={saving}>
              取消
            </Button>
            <Button onClick={save} loading={saving}>
              {isEdit ? '保存修改' : '创建徽章'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
