import { useEffect, useMemo, useState, type FormEvent } from 'react';
import { useQuery } from '@tanstack/react-query';
import { ArrowLeft, Download, FileText } from 'lucide-react';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  Button,
  Input,
  Label,
  Badge,
  listTemplates,
  renderTemplate,
  arrayBufferToObjectUrl,
  saveArrayBufferAs,
  TEMPLATE_PDF_MIME,
  detailFromApiError,
} from '@ump/shared';
import { toast } from 'sonner';

/**
 * Applicant flow: pick an admin-managed template → fill a form generated from its fields →
 * render a PDF on the server (docxtpl + LibreOffice) → preview + download.
 */
export default function TemplatesFillPage() {
  const [selectedId, setSelectedId] = useState<string | null>(null);

  const templatesQuery = useQuery({ queryKey: ['templates'], queryFn: listTemplates });
  const templates = templatesQuery.data ?? [];
  const selected = useMemo(
    () => templates.find((t) => t.id === selectedId) ?? null,
    [templates, selectedId],
  );

  if (selected) {
    return <FillTemplate template={selected} onBack={() => setSelectedId(null)} />;
  }

  return (
    <div className="space-y-4">
      <div>
        <h1 className="text-xl font-semibold tracking-tight">Mẫu tài liệu</h1>
        <p className="text-sm text-muted-foreground">
          Chọn một mẫu, điền thông tin và tải về tệp PDF hoàn chỉnh.
        </p>
      </div>

      {templatesQuery.isLoading ? (
        <p className="text-sm text-muted-foreground">Đang tải…</p>
      ) : templatesQuery.isError ? (
        <p className="text-sm text-destructive">Không tải được danh sách mẫu.</p>
      ) : templates.length === 0 ? (
        <Card>
          <CardContent className="py-10 text-center text-muted-foreground">
            Hiện chưa có mẫu nào. Vui lòng quay lại sau.
          </CardContent>
        </Card>
      ) : (
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {templates.map((t) => (
            <Card key={t.id} className="flex flex-col">
              <CardHeader>
                <CardTitle className="flex items-center gap-2 text-base">
                  <FileText className="h-4 w-4 shrink-0 text-muted-foreground" />
                  {t.name}
                </CardTitle>
              </CardHeader>
              <CardContent className="flex flex-1 flex-col gap-3">
                <p className="line-clamp-3 text-sm text-muted-foreground">
                  {t.description || 'Không có mô tả.'}
                </p>
                <div className="mt-auto flex items-center justify-between">
                  <Badge variant="secondary">{t.fields.length} trường</Badge>
                  <Button size="sm" onClick={() => setSelectedId(t.id)}>
                    Điền mẫu
                  </Button>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}

function FillTemplate({
  template,
  onBack,
}: {
  template: { id: string; name: string; fields: { key: string; label: string; type: string }[] };
  onBack: () => void;
}) {
  const [values, setValues] = useState<Record<string, string>>({});
  const [rendering, setRendering] = useState(false);
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [pdfBuf, setPdfBuf] = useState<ArrayBuffer | null>(null);

  // Revoke the object URL when it changes / on unmount.
  useEffect(() => {
    return () => {
      if (pdfUrl) URL.revokeObjectURL(pdfUrl);
    };
  }, [pdfUrl]);

  const handleRender = async (e: FormEvent) => {
    e.preventDefault();
    setRendering(true);
    try {
      const buf = await renderTemplate(template.id, values, 'pdf');
      setPdfBuf(buf);
      setPdfUrl((prev) => {
        if (prev) URL.revokeObjectURL(prev);
        return arrayBufferToObjectUrl(buf, TEMPLATE_PDF_MIME);
      });
    } catch (err) {
      toast.error(detailFromApiError(err, 'Không tạo được PDF.'));
    } finally {
      setRendering(false);
    }
  };

  return (
    <div className="space-y-4">
      <div className="space-y-1">
        <Button variant="ghost" size="sm" onClick={onBack} className="-ml-2 gap-2">
          <ArrowLeft className="h-4 w-4" />
          Chọn mẫu khác
        </Button>
        <h1 className="text-xl font-semibold tracking-tight">{template.name}</h1>
      </div>

      <div className="grid gap-4 lg:grid-cols-2">
        <Card>
          <CardHeader>
            <CardTitle className="text-base">Điền thông tin</CardTitle>
          </CardHeader>
          <CardContent>
            {template.fields.length === 0 ? (
              <p className="text-sm text-muted-foreground">
                Mẫu này không có trường nào để điền — bạn vẫn có thể tạo PDF.
              </p>
            ) : null}
            <form onSubmit={handleRender} className="space-y-4">
              {template.fields.map((f) => (
                <div key={f.key} className="space-y-1.5">
                  <Label htmlFor={`f-${f.key}`}>{f.label}</Label>
                  <Input
                    id={`f-${f.key}`}
                    value={values[f.key] ?? ''}
                    onChange={(e) => setValues((v) => ({ ...v, [f.key]: e.target.value }))}
                    disabled={rendering}
                  />
                </div>
              ))}
              <Button type="submit" disabled={rendering} className="w-full">
                {rendering ? 'Đang tạo PDF…' : 'Tạo PDF'}
              </Button>
            </form>
          </CardContent>
        </Card>

        <Card className="flex flex-col">
          <CardHeader className="flex flex-row items-center justify-between gap-2 space-y-0">
            <CardTitle className="text-base">Xem trước PDF</CardTitle>
            {pdfBuf ? (
              <Button
                size="sm"
                variant="outline"
                className="gap-2"
                onClick={() => saveArrayBufferAs(pdfBuf, `${template.name}.pdf`, TEMPLATE_PDF_MIME)}
              >
                <Download className="h-4 w-4" />
                Tải về
              </Button>
            ) : null}
          </CardHeader>
          <CardContent className="flex-1">
            {pdfUrl ? (
              <iframe title="PDF preview" src={pdfUrl} className="h-[70vh] w-full rounded-md border" />
            ) : (
              <div className="flex h-[70vh] items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground">
                Điền thông tin rồi bấm « Tạo PDF » để xem trước.
              </div>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
