import { useState } from "react";
import { FileSignature, Loader2 } from "lucide-react";
import { useMutation, useQuery } from "@tanstack/react-query";
import toast from "react-hot-toast";

import { api } from "@/services/api";
import { ContractSignaturePad } from "@/components/bookings/ContractSignaturePad";
import { StampUpload } from "@/components/contracts/StampUpload";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { useAuth } from "@/auth/useAuth";
import {
  Button,
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  Input,
  Label,
} from "@edr/ui-common";

/**
 * Lets the signed-in user view and update the reusable signature stored on
 * their profile. The same signature is offered for approval when signing a
 * booking contract.
 */
export function MySignatureCard() {
  const { user } = useAuth();
  const { data: saved, isLoading } = useQuery(
    api.signatures.mySignature.queryOptions({ staleTime: 60_000 }),
  );
  const saveMutation = useMutation(api.signatures.save.mutationOptions());

  const [open, setOpen] = useState(false);
  const [signerName, setSignerName] = useState("");
  const [signatureData, setSignatureData] = useState<string | null>(null);
  const [stampData, setStampData] = useState<string | null>(null);

  const defaultName =
    user?.name?.en || user?.username || user?.email || "";

  const openDialog = () => {
    setSignerName(saved?.signerDisplayName ?? defaultName);
    setSignatureData(null);
    setStampData(saved?.stampImageUrl ?? null);
    setOpen(true);
  };

  const save = () => {
    if (!signatureData || !signerName.trim()) return;
    saveMutation.mutate(
      {
        signerDisplayName: signerName.trim(),
        signatureImageBase64: signatureData,
        // Only send the stamp when it changed — omitted keeps the saved one.
        ...(stampData && stampData !== saved?.stampImageUrl
          ? { stampImageBase64: stampData }
          : {}),
      },
      {
        onSuccess: () => {
          toast.success("Signature saved");
          setOpen(false);
        },
        onError: () => toast.error("Failed to save signature"),
      },
    );
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <FileSignature className="size-4" />
          My signature
        </CardTitle>
        <CardDescription>
          This signature can be reused to sign booking contracts.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {isLoading ? (
          <div className="flex h-36 items-center justify-center">
            <Loader2 className="size-6 animate-spin text-primary" />
          </div>
        ) : saved?.signatureImageUrl ? (
          <div className="space-y-2">
            <div className="overflow-hidden rounded-lg border-2 border-dashed border-border bg-white">
              <img
                src={saved.signatureImageUrl}
                alt="My saved signature"
                className="mx-auto h-36 w-full object-contain"
              />
            </div>
            <p className="text-xs text-muted-foreground">
              Saved as {saved.signerDisplayName}
            </p>
          </div>
        ) : (
          <p className="text-sm text-muted-foreground">
            You have not saved a signature yet.
          </p>
        )}
        {saved?.stampImageUrl && (
          <div className="space-y-2">
            <div className="overflow-hidden rounded-lg border-2 border-dashed border-border bg-white">
              <img
                src={saved.stampImageUrl}
                alt="My saved company stamp"
                className="mx-auto h-24 w-full object-contain"
              />
            </div>
            <p className="text-xs text-muted-foreground">Company stamp</p>
          </div>
        )}
        <Button variant="outline" size="sm" onClick={openDialog}>
          {saved?.signatureImageUrl ? "Update signature" : "Add signature"}
        </Button>
      </CardContent>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Save your signature</DialogTitle>
            <DialogDescription>
              Draw your signature below. It will be stored on your profile for
              future contracts.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="profileSignerName">Full name</Label>
              <Input
                id="profileSignerName"
                value={signerName}
                onChange={(e) => setSignerName(e.target.value)}
                placeholder="As shown on contracts"
              />
            </div>
            <ContractSignaturePad onChange={setSignatureData} />
            <StampUpload
              value={stampData}
              onChange={setStampData}
              description="Stored on your profile and prefilled when you sign contracts."
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <Button
              disabled={
                saveMutation.isPending || !signatureData || !signerName.trim()
              }
              onClick={save}
            >
              {saveMutation.isPending ? (
                <Loader2 className="size-4 animate-spin" />
              ) : (
                "Save signature"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
