import { useRef, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { FileDown, Pencil, Plus, Power, Trash2 } from 'lucide-react';
import {
  useAuth,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
  Button,
  buttonVariants,
  Input,
  Label,
  Textarea,
  Badge,
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogCancel,
  AlertDialogAction,
  cn,
  formatIsoToDdMmYyyyHhMm,
  detailFromApiError,
  listTemplates,
  createTemplate,
  updateTemplate,
  deleteTemplate,
  downloadTemplateFile,
  saveArrayBufferAs,
  TEMPLATE_DOCX_MIME,
  type DocumentTemplate,
} from '@ump/shared';
import { toast } from 'sonner';

export function TemplatesPage() {
  const { hasRole } = useAuth();
  const qc = useQueryClient();
  const isAdmin = hasRole('admin');

  const templatesQuery = useQuery({
    queryKey: ['templates'],
    queryFn: listTemplates,
    enabled: isAdmin,
  });
  const templates = templatesQuery.data ?? [];

  const [createOpen, setCreateOpen] = useState(false);
  const [editing, setEditing] = useState<DocumentTemplate | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<DocumentTemplate | null>(null);

  const invalidate = () => qc.invalidateQueries({ queryKey: ['templates'] });

  const createMut = useMutation({
    mutationFn: createTemplate,
    onSuccess: (t) => {
      toast.success(`Đã tạo mẫu "${t.name}" — ${t.fields.length} trường.`);
      setCreateOpen(false);
      void invalidate();
    },
    onError: (e) => toast.error(detailFromApiError(e, 'Không tạo được mẫu.')),
  });

  const updateMut = useMutation({
    mutationFn: (v: { id: string; patch: { name?: string; description?: string; isActive?: boolean } }) =>
      updateTemplate(v.id, v.patch),
    onSuccess: () => {
      setEditing(null);
      void invalidate();
    },
    onError: (e) => toast.error(detailFromApiError(e, 'Không cập nhật được mẫu.')),
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteTemplate(id, { hard: true }),
    onSuccess: () => {
      toast.success('Đã xóa mẫu.');
      setDeleteTarget(null);
      void invalidate();
    },
    onError: (e) => toast.error(detailFromApiError(e, 'Không xóa được mẫu.')),
  });

  const handleDownload = async (t: DocumentTemplate) => {
    try {
      const buf = await downloadTemplateFile(t.id);
      saveArrayBufferAs(buf, t.originalFilename || `${t.name}.docx`, TEMPLATE_DOCX_MIME);
    } catch (e) {
      toast.error(detailFromApiError(e, 'Không tải được tệp mẫu.'));
    }
  };

  if (!isAdmin) {
    return (
      <p className="text-sm text-muted-foreground">
        Chỉ tài khoản quản trị mới quản lý được mẫu tài liệu.
      </p>
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <h1 className="text-xl font-semibold tracking-tight">Mẫu tài liệu</h1>
          <p className="text-sm text-muted-foreground">
            Tải lên mẫu .docx (Word) với các trường <code>{'{{ ten_truong }}'}</code>. Người nộp đơn
            sẽ điền theo từng mẫu.
          </p>
        </div>
        <Button onClick={() => setCreateOpen(true)} className="gap-2">
          <Plus className="h-4 w-4" />
          Tạo mẫu mới
        </Button>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Danh sách mẫu</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="overflow-x-auto rounded-md border">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[50px]">STT</TableHead>
                  <TableHead className="min-w-[200px]">Tên mẫu</TableHead>
                  <TableHead className="min-w-[200px]">Mô tả</TableHead>
                  <TableHead className="w-[90px] text-center">Số trường</TableHead>
                  <TableHead className="w-[120px]">Trạng thái</TableHead>
                  <TableHead className="w-[150px]">Cập nhật</TableHead>
                  <TableHead className="w-[200px] text-center">Thao tác</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {templatesQuery.isLoading ? (
                  <TableRow>
                    <TableCell colSpan={7} className="py-10 text-center text-muted-foreground">
                      Đang tải…
                    </TableCell>
                  </TableRow>
                ) : templatesQuery.isError ? (
                  <TableRow>
                    <TableCell colSpan={7} className="py-10 text-center text-destructive">
                      Không tải được danh sách mẫu.
                    </TableCell>
                  </TableRow>
                ) : templates.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={7} className="py-10 text-center text-muted-foreground">
                      Chưa có mẫu nào. Bấm « Tạo mẫu mới » để tải lên.
                    </TableCell>
                  </TableRow>
                ) : (
                  templates.map((t, i) => (
                    <TableRow key={t.id} data-state={t.isActive ? undefined : 'selected'}>
                      <TableCell>{i + 1}</TableCell>
                      <TableCell className="font-medium" title={t.originalFilename ?? ''}>
                        {t.name}
                      </TableCell>
                      <TableCell className="max-w-[280px] truncate text-muted-foreground" title={t.description ?? ''}>
                        {t.description || '—'}
                      </TableCell>
                      <TableCell className="text-center">
                        <Badge variant="secondary">{t.fields.length}</Badge>
                      </TableCell>
                      <TableCell>
                        {t.isActive ? (
                          <Badge className="bg-green-600 hover:bg-green-600/90">Đang dùng</Badge>
                        ) : (
                          <Badge variant="outline">Ẩn</Badge>
                        )}
                      </TableCell>
                      <TableCell className="text-muted-foreground">
                        {t.updatedAt ? formatIsoToDdMmYyyyHhMm(t.updatedAt) : '—'}
                      </TableCell>
                      <TableCell>
                        <div className="flex items-center justify-center gap-1.5">
                          <Button size="icon" variant="outline" title="Tải tệp .docx" onClick={() => void handleDownload(t)}>
                            <FileDown className="h-4 w-4" />
                          </Button>
                          <Button size="icon" variant="outline" title="Sửa thông tin" onClick={() => setEditing(t)}>
                            <Pencil className="h-4 w-4" />
                          </Button>
                          <Button
                            size="icon"
                            variant="outline"
                            title={t.isActive ? 'Ẩn mẫu (vô hiệu hóa)' : 'Hiện mẫu (kích hoạt)'}
                            disabled={updateMut.isPending}
                            onClick={() => updateMut.mutate({ id: t.id, patch: { isActive: !t.isActive } })}
                          >
                            <Power className={cn('h-4 w-4', t.isActive ? 'text-green-600' : 'text-muted-foreground')} />
                          </Button>
                          <Button size="icon" variant="destructive" title="Xóa vĩnh viễn" onClick={() => setDeleteTarget(t)}>
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      <CreateTemplateDialog
        open={createOpen}
        submitting={createMut.isPending}
        onOpenChange={setCreateOpen}
        onSubmit={(v) => createMut.mutate(v)}
      />

      <EditTemplateDialog
        template={editing}
        submitting={updateMut.isPending}
        onOpenChange={(o) => !o && setEditing(null)}
        onSubmit={(patch) => editing && updateMut.mutate({ id: editing.id, patch })}
      />

      <AlertDialog open={deleteTarget != null} onOpenChange={(o) => !o && setDeleteTarget(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Xóa mẫu vĩnh viễn?</AlertDialogTitle>
            <AlertDialogDescription>
              {deleteTarget ? (
                <>
                  Xóa hẳn mẫu <span className="font-medium text-foreground">"{deleteTarget.name}"</span> và tệp .docx
                  khỏi kho. Thao tác này không thể hoàn tác. Để tạm ẩn thay vì xóa, hãy dùng nút vô hiệu hóa.
                </>
              ) : null}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Hủy</AlertDialogCancel>
            <AlertDialogAction
              className={cn(buttonVariants({ variant: 'destructive' }))}
              onClick={() => deleteTarget && deleteMut.mutate(deleteTarget.id)}
            >
              Xóa vĩnh viễn
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

function CreateTemplateDialog(props: {
  open: boolean;
  submitting: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (v: { name: string; description?: string; file: File }) => void;
}) {
  const { open, submitting, onOpenChange, onSubmit } = props;
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [file, setFile] = useState<File | null>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  const reset = () => {
    setName('');
    setDescription('');
    setFile(null);
    if (fileRef.current) fileRef.current.value = '';
  };

  const submit = () => {
    if (!name.trim()) return toast.error('Nhập tên mẫu.');
    if (!file) return toast.error('Chọn tệp .docx.');
    if (!file.name.toLowerCase().endsWith('.docx')) return toast.error('Chỉ chấp nhận tệp .docx (Word).');
    onSubmit({ name: name.trim(), description: description.trim() || undefined, file });
  };

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) reset();
        onOpenChange(o);
      }}
    >
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Tạo mẫu tài liệu mới</DialogTitle>
        </DialogHeader>
        <div className="space-y-4 py-2">
          <div className="space-y-2">
            <Label htmlFor="tpl-name">Tên mẫu</Label>
            <Input id="tpl-name" value={name} onChange={(e) => setName(e.target.value)} placeholder="VD: Đơn xin nghỉ phép" disabled={submitting} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="tpl-desc">Mô tả (tùy chọn)</Label>
            <Textarea id="tpl-desc" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Mục đích của mẫu này…" disabled={submitting} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="tpl-file">Tệp .docx (Word, chứa các trường {'{{ ten }}'})</Label>
            <Input
              id="tpl-file"
              ref={fileRef}
              type="file"
              accept=".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
              onChange={(e) => setFile(e.target.files?.[0] ?? null)}
              disabled={submitting}
            />
            {file ? <p className="text-xs text-muted-foreground">Đã chọn: {file.name}</p> : null}
          </div>
        </div>
        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
            Hủy
          </Button>
          <Button type="button" onClick={submit} disabled={submitting}>
            {submitting ? 'Đang tải lên…' : 'Tạo mẫu'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function EditTemplateDialog(props: {
  template: DocumentTemplate | null;
  submitting: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (patch: { name?: string; description?: string }) => void;
}) {
  const { template, submitting, onOpenChange, onSubmit } = props;
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');

  // Sync local state when a new template is opened.
  const [syncedId, setSyncedId] = useState<string | null>(null);
  if (template && template.id !== syncedId) {
    setSyncedId(template.id);
    setName(template.name);
    setDescription(template.description ?? '');
  }

  return (
    <Dialog open={template != null} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Sửa thông tin mẫu</DialogTitle>
        </DialogHeader>
        <div className="space-y-4 py-2">
          <div className="space-y-2">
            <Label htmlFor="tpl-edit-name">Tên mẫu</Label>
            <Input id="tpl-edit-name" value={name} onChange={(e) => setName(e.target.value)} disabled={submitting} />
          </div>
          <div className="space-y-2">
            <Label htmlFor="tpl-edit-desc">Mô tả</Label>
            <Textarea id="tpl-edit-desc" value={description} onChange={(e) => setDescription(e.target.value)} disabled={submitting} />
          </div>
          {template ? (
            <div className="space-y-1">
              <Label>Các trường ({template.fields.length})</Label>
              <div className="flex flex-wrap gap-1.5">
                {template.fields.length === 0 ? (
                  <span className="text-xs text-muted-foreground">Không phát hiện trường {'{{ }}'} nào.</span>
                ) : (
                  template.fields.map((f) => (
                    <Badge key={f.key} variant="outline" className="font-mono text-xs">
                      {f.key}
                    </Badge>
                  ))
                )}
              </div>
            </div>
          ) : null}
        </div>
        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
            Hủy
          </Button>
          <Button
            type="button"
            onClick={() => {
              if (!name.trim()) return toast.error('Tên mẫu không được để trống.');
              onSubmit({ name: name.trim(), description: description.trim() });
            }}
            disabled={submitting}
          >
            {submitting ? 'Đang lưu…' : 'Lưu'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
