"use client";
//deixa o getStroke da npm i ai parceiro
import getStroke from "perfect-freehand";
import React, { useEffect, useRef, useState } from "react";

type Point = { x: number; y: number; pressure: number };

export default function SignaturePad({ setPng }: any) {
  const svgRef = useRef<SVGSVGElement | null>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [currentStroke, setCurrentStroke] = useState<Point[]>([]);
  // const [strokes, setStrokes] = useState<Point[][]>([]);
  // const [undoneStrokes, setUndoneStrokes] = useState<Point[][]>([]);
  const [strokes, setStrokes] = useState<{ points: Point[]; color: string }[]>(
    []
  );
  const [undoneStrokes, setUndoneStrokes] = useState<
    { points: Point[]; color: string }[]
  >([]);
  const [color, setColor] = useState("#000000");

  // Utilitário para converter coordenadas corretamente dentro do SVG
  function clientToSvgPoint(
    svg: SVGSVGElement,
    clientX: number,
    clientY: number
  ) {
    const pt = svg.createSVGPoint();
    pt.x = clientX;
    pt.y = clientY;
    const ctm = svg.getScreenCTM();
    if (!ctm) {
      const rect = svg.getBoundingClientRect();
      return { x: clientX - rect.left, y: clientY - rect.top };
    }
    const inverse = ctm.inverse();
    const p = pt.matrixTransform(inverse);
    return { x: p.x, y: p.y };
  }

  const handlePointerDown = (e: React.PointerEvent) => {
    e.preventDefault();
    const svg = svgRef.current!;
    const { x, y } = clientToSvgPoint(svg, e.clientX, e.clientY);
    setCurrentStroke([{ x, y, pressure: e.pressure ?? 0.5 }]);
    setIsDrawing(true);
    try {
      e.currentTarget.setPointerCapture(e.pointerId);
    } catch {}
  };

  const handlePointerMove = (e: React.PointerEvent) => {
    if (!isDrawing) return;
    const svg = svgRef.current!;
    const { x, y } = clientToSvgPoint(svg, e.clientX, e.clientY);
    setCurrentStroke((prev) => [
      ...prev,
      { x, y, pressure: e.pressure ?? 0.5 },
    ]);
  };

  const handlePointerUp = (e?: React.PointerEvent) => {
    if (currentStroke.length > 0) {
      setStrokes((prev) => [...prev, { points: currentStroke, color }]);
      setUndoneStrokes([]); // limpa o histórico de redo
      setCurrentStroke([]);
    }
    setIsDrawing(false);
    if (e) {
      try {
        e.currentTarget.releasePointerCapture(e.pointerId);
      } catch {}
    }
  };

  const undo = () => {
    setStrokes((prev) => {
      if (prev.length === 0) return prev;
      const newStrokes = [...prev];
      const undone = newStrokes.pop()!;
      setUndoneStrokes((u) => [...u, undone]);
      return newStrokes;
    });
  };

  const redo = () => {
    setUndoneStrokes((prev) => {
      if (prev.length === 0) return prev;
      const newUndone = [...prev];
      const redone = newUndone.pop()!;
      setStrokes((s) => [...s, redone]);
      return newUndone;
    });
  };

  // atalhos de teclado
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const isMac = navigator.platform.toUpperCase().includes("MAC");
      const ctrlOrCmd = isMac ? e.metaKey : e.ctrlKey;

      if (ctrlOrCmd && e.key.toLowerCase() === "z") {
        e.preventDefault();
        if (e.shiftKey) redo();
        else undo();
      }

      if (ctrlOrCmd && e.key.toLowerCase() === "y") {
        e.preventDefault();
        redo();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, []);

  const clear = () => {
    setStrokes([]);
    setUndoneStrokes([]);
    setCurrentStroke([]);
  };

  const getSvgPathFromStroke = (stroke: any) => {
    const outlinePoints = stroke(stroke, {
      size: 5,
      smoothing: 0.6,
      thinning: 0.6,
      streamline: 0.5,
      easing: (t: any) => t,
      start: {
        taper: 0,
        cap: true,
      },
      end: {
        taper: 0,
        cap: true,
      },
      simulatePressure: true,
    });

    if (!outlinePoints.length) return "";

    const d = outlinePoints.reduce(
      (acc: any, [x0, y0]: [any, any], i: any, arr: any) => {
        const [x1, y1] = arr[(i + 1) % arr.length];
        acc += `${i === 0 ? "M" : "L"}${x0.toFixed(2)},${y0.toFixed(2)} `;
        if (i === arr.length - 1) acc += "Z";
        return acc;
      },
      ""
    );
    return d;
  };

  useEffect(() => {
    // const svgElement = (
    //   <svg ref={svgRef} className="w-[100%] h-[300px] touch-none">
    //     {[...strokes, currentStroke].map(
    //       (stroke, i) =>
    //         stroke.length > 1 && (
    //           <path
    //             key={i}
    //             d={getSvgPathFromStroke(stroke)}
    //             fill="black"
    //             stroke="none"
    //           />
    //         )
    //     )}
    //   </svg>
    // );

    // setSvg(svgElement);
    //
    // if (svgRef.current) {
    //   const serializer = new XMLSerializer();
    //   const svgString = serializer.serializeToString(svgRef.current);

    //   setSvg(svgString);
    // }
    //
    if (strokes?.length > 0 && svgRef && svgRef.current) {
      const serializer = new XMLSerializer();
      const svgString = serializer.serializeToString(svgRef.current);

      // Converte para base64
      const svgBase64 = btoa(unescape(encodeURIComponent(svgString)));
      const img = new Image();

      img.onload = () => {
        const canvas = document.createElement("canvas");
        canvas.width = svgRef.current!.width.baseVal.value;
        canvas.height = svgRef.current!.height.baseVal.value;
        const ctx = canvas.getContext("2d");
        if (!ctx) return;

        ctx.drawImage(img, 0, 0);
        const pngDataUrl = canvas.toDataURL("image/png");

        // Envia o PNG para o pai
        setPng(pngDataUrl);
      };

      img.src = `data:image/svg+xml;base64,${svgBase64}`;
    } else {
      setPng("");
    }
    //
  }, [strokes]);

  return (
    <div className="flex flex-col items-center w-full">
      <div className="border border-gray-300 rounded-md bg-white touch-none w-full">
        <svg
          ref={svgRef}
          className="w-[100%] h-[300px] touch-none"
          onPointerDown={handlePointerDown}
          onPointerMove={handlePointerMove}
          onPointerUp={handlePointerUp}
          onPointerLeave={handlePointerUp}
        >
          {[...strokes].map((stroke, i) => {
            if (stroke.points.length > 1) {
              return (
                <path
                  key={i}
                  d={getSvgPathFromStroke(stroke.points)}
                  // fill="black"
                  fill={stroke.color}
                  stroke="none"
                />
              );
            }
            // 🔹 Exibe um pequeno ponto se o traço tiver só um ponto
            if (stroke.points.length === 1) {
              const p = stroke.points[0];
              return (
                <circle
                  key={i}
                  cx={p.x}
                  cy={p.y}
                  r={2.5} // tamanho ajustável
                  fill={stroke.color}
                />
              );
            }
            return null;
          })}
          {currentStroke.length === 1 && (
            <circle
              cx={currentStroke[0].x}
              cy={currentStroke[0].y}
              r={2.5}
              fill={color}
            />
          )}
          {currentStroke.length > 1 && (
            <path
              d={getSvgPathFromStroke(currentStroke)}
              fill={color}
              stroke="none"
            />
          )}
        </svg>
      </div>

      <div className="flex gap-3 mt-3">
        <label className="flex items-center gap-2">
          <span className="text-sm text-gray-600">Cor:</span>
          <input
            type="color"
            value={color}
            onChange={(e) => setColor(e.target.value)}
            className="w-10 h-8 cursor-pointer"
          />
        </label>

        <button
          onClick={undo}
          disabled={strokes.length === 0}
          className="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300 disabled:opacity-50"
        >
          Desfazer (Ctrl+Z)
        </button>
        <button
          onClick={redo}
          disabled={undoneStrokes.length === 0}
          className="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300 disabled:opacity-50"
        >
          Refazer (Ctrl+Y)
        </button>
        <button
          onClick={clear}
          className="px-4 py-2 bg-red-100 rounded hover:bg-red-200"
        >
          Limpar
        </button>
      </div>
    </div>
  );
}
