import { useEffect, useMemo, useState } from 'react';
import { Loader2, Plus, Trash2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { applyPdfTextLayoutEdits, type PdfTextLayoutEdit } from '@/components/applicant/initiative-draft/pdfLayoutEditor';
import { downloadPdfBlob } from '@/components/applicant/initiative-draft/applicationFormOfficialPdf';

type PdfTextLayoutEditorDialogProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  pdfBlob: Blob | null;
  fileName: string;
  onPdfUpdated: (blob: Blob) => void;
  initialEdits?: PdfTextLayoutEdit[] | null;
  onSaveLayout?: (edits: PdfTextLayoutEdit[], editedPdfBlob: Blob) => Promise<void>;
};

const DEFAULT_EDIT = (): PdfTextLayoutEdit => ({
  id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
  text: '',
  page: 1,
  x: 72,
  y: 740,
  fontSize: 12,
  lineHeight: 14,
  boxWidth: 240,
  letterSpacing: 0,
  textAlign: 'left',
  fontName: 'TimesRoman',
  colorHex: '#111827',
});

const FONT_OPTIONS: Array<{ value: PdfTextLayoutEdit['fontName']; label: string }> = [
  { value: 'TimesRoman', label: 'Times Roman' },
  { value: 'TimesRomanBold', label: 'Times Roman Bold' },
  { value: 'Helvetica', label: 'Helvetica' },
  { value: 'HelveticaBold', label: 'Helvetica Bold' },
];

export function PdfTextLayoutEditorDialog({
  open,
  onOpenChange,
  pdfBlob,
  fileName,
  onPdfUpdated,
  initialEdits,
  onSaveLayout,
}: PdfTextLayoutEditorDialogProps) {
  const [edits, setEdits] = useState<PdfTextLayoutEdit[]>([DEFAULT_EDIT()]);
  const [saving, setSaving] = useState(false);
  const [savingLayout, setSavingLayout] = useState(false);

  const objectUrl = useMemo(() => (pdfBlob ? URL.createObjectURL(pdfBlob) : null), [pdfBlob]);
  useEffect(() => {
    return () => {
      if (objectUrl) URL.revokeObjectURL(objectUrl);
    };
  }, [objectUrl]);

  useEffect(() => {
    if (!open) {
      setEdits([DEFAULT_EDIT()]);
    }
  }, [open]);

  useEffect(() => {
    if (!open) return;
    if (Array.isArray(initialEdits) && initialEdits.length > 0) {
      setEdits(initialEdits);
      return;
    }
    setEdits([DEFAULT_EDIT()]);
  }, [open, initialEdits]);

  const updateEdit = <K extends keyof PdfTextLayoutEdit>(id: string, key: K, value: PdfTextLayoutEdit[K]) => {
    setEdits((prev) => prev.map((edit) => (edit.id === id ? { ...edit, [key]: value } : edit)));
  };

  const handleApply = async () => {
    if (!pdfBlob || saving) return;
    setSaving(true);
    try {
      const nextBlob = await applyPdfTextLayoutEdits(pdfBlob, edits);
      onPdfUpdated(nextBlob);
      onOpenChange(false);
    } finally {
      setSaving(false);
    }
  };

  const handleApplyAndDownload = async () => {
    if (!pdfBlob || saving) return;
    setSaving(true);
    try {
      const nextBlob = await applyPdfTextLayoutEdits(pdfBlob, edits);
      onPdfUpdated(nextBlob);
      downloadPdfBlob(nextBlob, fileName || 'application-form-edited.pdf');
      onOpenChange(false);
    } finally {
      setSaving(false);
    }
  };

  const handleSaveLayout = async () => {
    if (!pdfBlob || saving || savingLayout || !onSaveLayout) return;
    setSavingLayout(true);
    try {
      const nextBlob = await applyPdfTextLayoutEdits(pdfBlob, edits);
      onPdfUpdated(nextBlob);
      await onSaveLayout(edits, nextBlob);
      onOpenChange(false);
    } finally {
      setSavingLayout(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-h-[92vh] max-w-7xl flex-col gap-0 overflow-hidden p-0 sm:rounded-lg">
        <DialogHeader className="space-y-1 border-b border-border px-6 py-4 pr-14 text-left">
          <DialogTitle>Chỉnh bố cục chữ trên PDF</DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            Thêm các lớp chữ phủ lên PDF theo tọa độ (đơn vị point). Gốc tọa độ ở góc trái dưới trang. Font chuẩn PDF hỗ
            trợ tiếng Việt hạn chế.
          </DialogDescription>
        </DialogHeader>

        <div className="grid min-h-[68vh] grid-cols-1 gap-0 md:grid-cols-[380px_minmax(0,1fr)]">
          <div className="overflow-y-auto border-b border-border p-4 md:border-b-0 md:border-r">
            <div className="mb-3 flex items-center justify-between">
              <h3 className="text-sm font-medium">Các chỉnh sửa chữ</h3>
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="gap-1.5"
                onClick={() => setEdits((prev) => [...prev, DEFAULT_EDIT()])}
              >
                <Plus className="h-3.5 w-3.5" aria-hidden />
                Thêm dòng
              </Button>
            </div>

            <div className="space-y-3">
              {edits.map((edit, idx) => (
                <div key={edit.id} className="rounded-md border border-border p-3">
                  <div className="mb-2 flex items-center justify-between">
                    <p className="text-xs font-medium text-muted-foreground">Mục {idx + 1}</p>
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      className="h-7 px-2 text-destructive"
                      disabled={edits.length <= 1}
                      onClick={() =>
                        setEdits((prev) => (prev.length <= 1 ? prev : prev.filter((x) => x.id !== edit.id)))
                      }
                    >
                      <Trash2 className="h-3.5 w-3.5" aria-hidden />
                    </Button>
                  </div>

                  <label className="mb-1 block text-xs text-muted-foreground">Nội dung chữ</label>
                  <Textarea
                    value={edit.text}
                    onChange={(e) => updateEdit(edit.id, 'text', e.target.value)}
                    placeholder="Nhập nội dung muốn chèn"
                    className="mb-2 min-h-[90px]"
                  />

                  <div className="grid grid-cols-2 gap-2">
                    <Input
                      type="number"
                      value={edit.page}
                      onChange={(e) => updateEdit(edit.id, 'page', Number(e.target.value))}
                      placeholder="Trang"
                    />
                    <Input
                      type="number"
                      value={edit.fontSize}
                      onChange={(e) => updateEdit(edit.id, 'fontSize', Number(e.target.value))}
                      placeholder="Font"
                    />
                    <Input
                      type="number"
                      value={edit.x}
                      onChange={(e) => updateEdit(edit.id, 'x', Number(e.target.value))}
                      placeholder="X"
                    />
                    <Input
                      type="number"
                      value={edit.y}
                      onChange={(e) => updateEdit(edit.id, 'y', Number(e.target.value))}
                      placeholder="Y"
                    />
                    <Input
                      type="number"
                      value={edit.lineHeight}
                      onChange={(e) => updateEdit(edit.id, 'lineHeight', Number(e.target.value))}
                      placeholder="Line height"
                    />
                    <Input
                      type="number"
                      value={edit.boxWidth}
                      onChange={(e) => updateEdit(edit.id, 'boxWidth', Number(e.target.value))}
                      placeholder="Width (pt)"
                    />
                    <Input
                      type="number"
                      value={edit.letterSpacing}
                      onChange={(e) => updateEdit(edit.id, 'letterSpacing', Number(e.target.value))}
                      placeholder="Letter spacing"
                    />
                    <Input
                      type="text"
                      value={edit.colorHex}
                      onChange={(e) => updateEdit(edit.id, 'colorHex', e.target.value)}
                      placeholder="#111827"
                    />
                  </div>

                  <div className="mt-2 grid grid-cols-2 gap-2">
                    <div>
                      <label className="mb-1 block text-xs text-muted-foreground">Font</label>
                      <select
                        className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm"
                        value={edit.fontName}
                        onChange={(e) =>
                          updateEdit(
                            edit.id,
                            'fontName',
                            (e.target.value as PdfTextLayoutEdit['fontName']) || 'TimesRoman',
                          )
                        }
                      >
                        {FONT_OPTIONS.map((opt) => (
                          <option key={opt.value} value={opt.value}>
                            {opt.label}
                          </option>
                        ))}
                      </select>
                    </div>
                    <div>
                      <label className="mb-1 block text-xs text-muted-foreground">Canh lề</label>
                      <select
                        className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm"
                        value={edit.textAlign}
                        onChange={(e) =>
                          updateEdit(
                            edit.id,
                            'textAlign',
                            (e.target.value as PdfTextLayoutEdit['textAlign']) || 'left',
                          )
                        }
                      >
                        <option value="left">Trái</option>
                        <option value="center">Giữa</option>
                        <option value="right">Phải</option>
                      </select>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="relative min-h-[68vh] bg-muted/30">
            {objectUrl ? (
              <iframe title="PDF chỉnh bố cục" src={objectUrl} className="absolute inset-0 h-full w-full border-0" />
            ) : (
              <div className="flex h-full items-center justify-center text-sm text-muted-foreground">Chưa có PDF.</div>
            )}
          </div>
        </div>

        <DialogFooter className="flex-row flex-wrap gap-2 border-t border-border px-6 py-4 sm:justify-between">
          <Button type="button" variant="outline" size="sm" onClick={() => onOpenChange(false)}>
            Đóng
          </Button>
          <div className="flex flex-wrap gap-2">
            <Button type="button" variant="outline" size="sm" disabled={!pdfBlob || saving} onClick={() => void handleApply()}>
              {saving ? (
                <>
                  <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" aria-hidden />
                  Đang áp dụng...
                </>
              ) : (
                'Áp dụng vào bản xem trước'
              )}
            </Button>
            <Button
              type="button"
              variant="outline"
              size="sm"
              disabled={!pdfBlob || saving || savingLayout || !onSaveLayout}
              onClick={() => void handleSaveLayout()}
            >
              {savingLayout ? (
                <>
                  <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" aria-hidden />
                  Đang lưu máy chủ...
                </>
              ) : (
                'Áp dụng và lưu máy chủ'
              )}
            </Button>
            <Button type="button" size="sm" disabled={!pdfBlob || saving} onClick={() => void handleApplyAndDownload()}>
              {saving ? (
                <>
                  <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" aria-hidden />
                  Đang xuất...
                </>
              ) : (
                'Áp dụng và tải PDF'
              )}
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
