import { Button } from "@/components/ui/button";
import { Eraser } from "lucide-react";
import { forwardRef, useEffect, useImperativeHandle, useRef, useState, type PointerEvent } from "react";

export type SignaturePadHandle = {
  clear: () => void;
  getDataUrl: () => string;
  isEmpty: () => boolean;
};

type SignaturePadProps = {
  label: string;
  onChange?: (value: string) => void;
};

export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(function SignaturePad(
  { label, onChange },
  ref
) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [hasDrawing, setHasDrawing] = useState(false);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const rect = canvas.getBoundingClientRect();
    const ratio = window.devicePixelRatio || 1;
    canvas.width = Math.floor(rect.width * ratio);
    canvas.height = Math.floor(rect.height * ratio);
    const context = canvas.getContext("2d");
    if (!context) return;
    context.scale(ratio, ratio);
    context.lineWidth = 2;
    context.lineCap = "round";
    context.lineJoin = "round";
    context.strokeStyle = "#0f172a";
    context.fillStyle = "#ffffff";
    context.fillRect(0, 0, rect.width, rect.height);
  }, []);

  const getContext = () => {
    const canvas = canvasRef.current;
    if (!canvas) return null;
    return canvas.getContext("2d");
  };

  const getCoordinates = (event: React.PointerEvent<HTMLCanvasElement>) => {
    const rect = event.currentTarget.getBoundingClientRect();
    return {
      x: event.clientX - rect.left,
      y: event.clientY - rect.top,
    };
  };

  const clear = () => {
    const canvas = canvasRef.current;
    const context = getContext();
    if (!canvas || !context) return;
    context.clearRect(0, 0, canvas.width, canvas.height);
    const rect = canvas.getBoundingClientRect();
    context.fillStyle = "#ffffff";
    context.fillRect(0, 0, rect.width, rect.height);
    setHasDrawing(false);
    onChange?.("");
  };

  useImperativeHandle(ref, () => ({
    clear,
    getDataUrl: () => canvasRef.current?.toDataURL("image/png") || "",
    isEmpty: () => !hasDrawing,
  }), [hasDrawing]);

  const finishDrawing = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    setIsDrawing(false);
    setHasDrawing(true);
    onChange?.(canvas.toDataURL("image/png"));
  };

  return (
    <div className="space-y-2">
      <div className="flex items-center justify-between gap-3">
        <p className="text-sm font-medium">{label}</p>
        <Button type="button" variant="ghost" size="sm" onClick={clear}>
          <Eraser className="mr-2 h-4 w-4" />
          Effacer
        </Button>
      </div>
      <div className="rounded-lg border bg-white overflow-hidden">
        <canvas
          ref={canvasRef}
          className="block h-36 w-full touch-none bg-white"
          onPointerDown={(event: PointerEvent<HTMLCanvasElement>) => {
            const context = getContext();
            if (!context) return;
            const point = getCoordinates(event);
            context.beginPath();
            context.moveTo(point.x, point.y);
            setIsDrawing(true);
          }}
          onPointerMove={(event: PointerEvent<HTMLCanvasElement>) => {
            if (!isDrawing) return;
            const context = getContext();
            if (!context) return;
            const point = getCoordinates(event);
            context.lineTo(point.x, point.y);
            context.stroke();
            if (!hasDrawing) {
              setHasDrawing(true);
            }
          }}
          onPointerUp={() => {
            if (!isDrawing) return;
            finishDrawing();
          }}
          onPointerLeave={() => {
            if (!isDrawing) return;
            finishDrawing();
          }}
        />
      </div>
      <p className="text-xs text-muted-foreground">
        Signez directement au doigt ou au stylet.
      </p>
    </div>
  );
});
