import { useState } from "react";
import { FileSignature, Loader2, Stamp } 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 and company
 * stamp stored on their profile — managed independently of each other. Both
 * are offered 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 [signatureOpen, setSignatureOpen] = useState(false);
  const [stampOpen, setStampOpen] = 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 savedName = saved?.signerDisplayName ?? defaultName;

  const openSignatureDialog = () => {
    setSignerName(savedName);
    setSignatureData(null);
    setSignatureOpen(true);
  };

  const saveSignature = () => {
    if (!signatureData || !signerName.trim()) return;
    saveMutation.mutate(
      {
        signerDisplayName: signerName.trim(),
        signatureImageBase64: signatureData,
        // Stamp untouched — it is managed by its own dialog.
      },
      {
        onSuccess: () => {
          toast.success("Signature saved");
          setSignatureOpen(false);
        },
        onError: () => toast.error("Failed to save signature"),
      },
    );
  };

  const openStampDialog = () => {
    setStampData(saved?.stampImageUrl ?? null);
    setStampOpen(true);
  };

  const saveStamp = () => {
    if (!stampData) return;
    saveMutation.mutate(
      {
        signerDisplayName: savedName || defaultName,
        // Signature untouched — stamp-only update.
        stampImageBase64: stampData,
      },
      {
        onSuccess: () => {
          toast.success("Stamp saved");
          setStampOpen(false);
        },
        onError: () => toast.error("Failed to save stamp"),
      },
    );
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <FileSignature className="size-4" />
          Signature &amp; Stamp
        </CardTitle>
        <CardDescription>
          This signature can be reused to sign booking contracts.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        {isLoading ? (
          <div className="flex h-36 items-center justify-center">
            <Loader2 className="size-6 animate-spin text-primary" />
          </div>
        ) : (
          <>
            <div className="space-y-2">
              {saved?.signatureImageUrl ? (
                <>
                  <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>
                </>
              ) : (
                <p className="text-sm text-muted-foreground">
                  You have not saved a signature yet.
                </p>
              )}
              <Button variant="outline" size="sm" onClick={openSignatureDialog}>
                {saved?.signatureImageUrl ? "Update signature" : "Add signature"}
              </Button>
            </div>

            <div className="space-y-2">
              {saved?.stampImageUrl ? (
                <>
                  <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>
                </>
              ) : (
                <p className="text-sm text-muted-foreground">
                  You have not uploaded a company stamp yet.
                </p>
              )}
              <Button variant="outline" size="sm" onClick={openStampDialog}>
                <Stamp className="size-4" />
                {saved?.stampImageUrl ? "Update stamp" : "Upload stamp"}
              </Button>
            </div>
          </>
        )}
      </CardContent>

      <Dialog open={signatureOpen} onOpenChange={setSignatureOpen}>
        <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} />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setSignatureOpen(false)}>
              Cancel
            </Button>
            <Button
              disabled={
                saveMutation.isPending || !signatureData || !signerName.trim()
              }
              onClick={saveSignature}
            >
              {saveMutation.isPending ? (
                <Loader2 className="size-4 animate-spin" />
              ) : (
                "Save signature"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={stampOpen} onOpenChange={setStampOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Company stamp</DialogTitle>
            <DialogDescription>
              Upload your official company stamp or seal as an image. It is
              stored on your profile and applied next to your signature on
              contracts.
            </DialogDescription>
          </DialogHeader>
          <StampUpload
            value={stampData}
            onChange={setStampData}
            description="Stored on your profile and prefilled when you sign contracts."
          />
          <DialogFooter>
            <Button variant="outline" onClick={() => setStampOpen(false)}>
              Cancel
            </Button>
            <Button
              disabled={saveMutation.isPending || !stampData}
              onClick={saveStamp}
            >
              {saveMutation.isPending ? (
                <Loader2 className="size-4 animate-spin" />
              ) : (
                "Save stamp"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
