import { useCallback, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
  ArrowLeft,
  Download,
  FileSignature,
  Loader2,
  Printer,
} from "lucide-react";
import toast from "react-hot-toast";

import { ContractSignaturePad } from "@/components/bookings/ContractSignaturePad";
import {
  bookingsService,
  type SignContractPayload,
} from "@/services/bookings.service";
import { Button } from "@edr/ui-common";

export default function BookingContractPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const qc = useQueryClient();
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const [signOpen, setSignOpen] = useState(false);
  const [signerName, setSignerName] = useState("");
  const [signatureData, setSignatureData] = useState<string | null>(null);
  // When a saved signature exists we offer it for approval first; the customer
  // can switch to drawing a fresh one.
  const [drawNew, setDrawNew] = useState(false);

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ["booking-contract-view", id],
    queryFn: () => bookingsService.getContractView(id!),
    enabled: Boolean(id),
  });

  const savedSignature = data?.savedSignature ?? null;
  const savedSignatureImage = savedSignature?.signatureImageUrl ?? null;
  const usingSaved = Boolean(savedSignatureImage) && !drawNew;

  const openSign = () => {
    // Prefill from the saved signature so the customer only has to approve it.
    setSignerName(savedSignature?.signerDisplayName ?? "");
    setSignatureData(null);
    setDrawNew(false);
    setSignOpen(true);
  };

  const confirmSign = () => {
    if (!signerName.trim()) return;
    // Approve the saved signature, or submit the freshly drawn one.
    const image = usingSaved ? savedSignatureImage : signatureData;
    if (!image) return;
    signMutation.mutate({
      role: "CUSTOMER",
      signatureImageBase64: image,
      signerDisplayName: signerName.trim(),
      consentText: "I agree to the terms of this contract.",
    });
  };

  const signMutation = useMutation({
    mutationFn: (payload: SignContractPayload) =>
      bookingsService.signContract(id!, payload),
    onSuccess: () => {
      toast.success("Contract signed successfully");
      setSignOpen(false);
      void refetch();
      qc.invalidateQueries({ queryKey: ["booking", id] });
    },
    onError: () => toast.error("Failed to sign contract"),
  });

  const downloadPdf = useCallback(async () => {
    if (!id) return;
    try {
      const blob = await bookingsService.downloadContractDocument(id);
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `contract-${data?.reference ?? id}.pdf`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {
      toast.error("PDF not ready yet. Contact EDR if this persists.");
    }
  }, [id, data?.reference]);

  const handlePrint = useCallback(() => {
    if (iframeRef.current?.contentWindow) {
      iframeRef.current.contentWindow.print();
    }
  }, []);

  if (isLoading) {
    return (
      <div className="flex min-h-[40vh] items-center justify-center">
        <Loader2 className="size-8 animate-spin text-primary" />
      </div>
    );
  }

  if (isError || !data) {
    return (
      <div className="p-8">
        <p className="text-muted-foreground">Could not load contract.</p>
        <Button variant="outline" className="mt-4" onClick={() => navigate(-1)}>
          Go back
        </Button>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-muted/30 p-4 md:p-8">
      <div className="mx-auto max-w-4xl">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-3 print:hidden">
          <Button variant="ghost" size="sm" onClick={() => navigate(`/bookings/${id}`)}>
            <ArrowLeft className="mr-2 size-4" />
            Back to booking
          </Button>
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" size="sm" onClick={handlePrint}>
              <Printer className="mr-2 size-4" />
              Print
            </Button>
            <Button variant="outline" size="sm" onClick={downloadPdf}>
              <Download className="mr-2 size-4" />
              PDF
            </Button>
            {data.canSignCustomer && (
              <Button size="sm" onClick={openSign}>
                <FileSignature className="mr-2 size-4" />
                {usingSaved ? "Approve & sign" : "Sign contract"}
              </Button>
            )}
          </div>
        </div>

        <iframe
          ref={iframeRef}
          srcDoc={data.html}
          className="w-full rounded-lg border bg-white shadow-sm"
          style={{ minHeight: "80vh" }}
          title="Contract document"
        />
      </div>

      {signOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 print:hidden">
          <div className="w-full max-w-md rounded-xl bg-background p-6 shadow-xl">
            <h2 className="text-lg font-semibold">
              {usingSaved ? "Approve signature" : "Sign contract"}
            </h2>
            <p className="mt-1 text-sm text-muted-foreground">
              {usingSaved
                ? `${data.reference} — review your saved signature and approve it.`
                : `${data.reference} — your signature will be stored securely.`}
            </p>
            <div className="mt-4 space-y-3">
              <label className="text-sm font-medium" htmlFor="portalSigner">
                Full name
              </label>
              <input
                id="portalSigner"
                className="w-full rounded-md border px-3 py-2 text-sm"
                value={signerName}
                onChange={(e) => setSignerName(e.target.value)}
              />
              {usingSaved ? (
                <div className="space-y-2">
                  <div className="overflow-hidden rounded-lg border-2 border-dashed border-border bg-white">
                    <img
                      src={savedSignatureImage ?? undefined}
                      alt="Saved signature"
                      className="mx-auto h-36 w-full object-contain"
                    />
                  </div>
                  <button
                    type="button"
                    className="text-xs text-primary underline"
                    onClick={() => {
                      setDrawNew(true);
                      setSignatureData(null);
                    }}
                  >
                    Draw a new signature instead
                  </button>
                </div>
              ) : (
                <ContractSignaturePad onChange={setSignatureData} />
              )}
            </div>
            <div className="mt-6 flex justify-end gap-2">
              <Button variant="outline" onClick={() => setSignOpen(false)}>
                Cancel
              </Button>
              <Button
                disabled={
                  signMutation.isPending ||
                  (!usingSaved && !signatureData) ||
                  !signerName.trim()
                }
                onClick={confirmSign}
              >
                {usingSaved ? "Approve & sign" : "Confirm signature"}
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
