import React, { useRef, useEffect, useState, useCallback } from 'react';
import { RotateCcw } from 'lucide-react';

const SignatureField = ({
  label = 'Signature',
  required = false,
  onChange,
  value,
  disabled = false,
  readOnly = false,
  backgroundColor = '#ffffff',
  penColor = '#000000',
  penWidth = 2,
  displayWidth = 400,
  displayHeight = 200,
}) => {
  const canvasRef = useRef(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [lastPosition, setLastPosition] = useState({ x: 0, y: 0 });
  const [isEmpty, setIsEmpty] = useState(true);
  const [svgPaths, setSvgPaths] = useState([]);
  const [currentPath, setCurrentPath] = useState('');
  const [smoothingPoints, setSmoothingPoints] = useState([]);

  // Initialiser le canvas
  const initializeCanvas = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const context = canvas.getContext('2d');

    // Support High DPI / Retina displays
    const devicePixelRatio = window.devicePixelRatio || 1;
    // Ajuster la taille physique du canvas pour la haute résolution
    canvas.width = displayWidth * devicePixelRatio;
    canvas.height = displayHeight * devicePixelRatio;

    // Maintenir la taille d'affichage
    canvas.style.width = displayWidth + 'px';
    canvas.style.height = displayHeight + 'px';

    // Adapter le contexte à la densité de pixels
    context.scale(devicePixelRatio, devicePixelRatio);

    // Améliorer l'anti-aliasing et le rendu
    context.imageSmoothingEnabled = true;
    context.imageSmoothingQuality = 'high';
    context.textRenderingOptimization = 'optimizeQuality';

    // Configuration du style de dessin
    context.fillStyle = backgroundColor;
    context.fillRect(0, 0, displayWidth, displayHeight);
    context.strokeStyle = penColor;
    context.lineWidth = penWidth;
    context.lineCap = 'round';
    context.lineJoin = 'round';
    context.globalCompositeOperation = 'source-over';
  }, [backgroundColor, penColor, penWidth, displayWidth, displayHeight]);

  useEffect(() => {
    initializeCanvas();

    // Si une valeur est fournie (signature existante), la charger
    if (value && value !== '') {
      const canvas = canvasRef.current;
      const context = canvas.getContext('2d');

      if (value.includes('svg+xml')) {
        // Charger une signature SVG
        const svgData = atob(value.split(',')[1]);
        const img = new Image();
        const svg = new Blob([svgData], {
          type: 'image/svg+xml;charset=utf-8',
        });
        const url = URL.createObjectURL(svg);

        img.onload = () => {
          context.clearRect(0, 0, canvas.width, canvas.height);
          context.fillStyle = backgroundColor;
          context.fillRect(0, 0, canvas.width, canvas.height);
          context.drawImage(img, 0, 0);
          setIsEmpty(false);
          URL.revokeObjectURL(url);
        };
        img.src = url;
      } else {
        // Charger une image classique
        const img = new Image();
        img.onload = () => {
          context.clearRect(0, 0, canvas.width, canvas.height);
          context.fillStyle = backgroundColor;
          context.fillRect(0, 0, canvas.width, canvas.height);
          context.drawImage(img, 0, 0);
          setIsEmpty(false);
        };
        img.src = value;
      }
    }
  }, [value, initializeCanvas, backgroundColor]);

  // Obtenir les coordonnées relatives au canvas
  const getCanvasPosition = (e) => {
    const canvas = canvasRef.current;
    const rect = canvas.getBoundingClientRect();
    const scaleX = canvas.style.width
      ? parseFloat(canvas.style.width) / rect.width
      : 1;
    const scaleY = canvas.style.height
      ? parseFloat(canvas.style.height) / rect.height
      : 1;

    return {
      x: (e.clientX - rect.left) * scaleX,
      y: (e.clientY - rect.top) * scaleY,
    };
  };

  // Obtenir les coordonnées pour les événements tactiles
  const getTouchPosition = (e) => {
    const canvas = canvasRef.current;
    const rect = canvas.getBoundingClientRect();
    const scaleX = canvas.style.width
      ? parseFloat(canvas.style.width) / rect.width
      : 1;
    const scaleY = canvas.style.height
      ? parseFloat(canvas.style.height) / rect.height
      : 1;

    return {
      x: (e.touches[0].clientX - rect.left) * scaleX,
      y: (e.touches[0].clientY - rect.top) * scaleY,
    };
  };

  // Commencer le dessin
  const startDrawing = useCallback(
    (e) => {
      if (disabled || readOnly) return;

      e.preventDefault();
      setIsDrawing(true);

      const pos = e.type.includes('touch')
        ? getTouchPosition(e)
        : getCanvasPosition(e);
      setLastPosition(pos);

      // Commencer un nouveau path SVG
      setCurrentPath(`M ${pos.x},${pos.y}`);
      setSmoothingPoints([pos]);
    },
    [disabled, readOnly]
  );

  // Dessiner
  const draw = useCallback(
    (e) => {
      if (!isDrawing || disabled || readOnly) return;

      e.preventDefault();
      const canvas = canvasRef.current;
      const context = canvas.getContext('2d');

      const currentPos = e.type.includes('touch')
        ? getTouchPosition(e)
        : getCanvasPosition(e);

      // Calculer la distance pour déterminer si on doit interpoler
      const distance = Math.sqrt(
        Math.pow(currentPos.x - lastPosition.x, 2) +
          Math.pow(currentPos.y - lastPosition.y, 2)
      );

      // Si la distance est grande, interpoler pour un tracé plus lisse
      if (distance > 2) {
        const midPoint = {
          x: (lastPosition.x + currentPos.x) / 2,
          y: (lastPosition.y + currentPos.y) / 2,
        };

        // Utiliser une courbe quadratique pour un tracé plus lisse
        context.beginPath();
        context.moveTo(lastPosition.x, lastPosition.y);
        context.quadraticCurveTo(
          lastPosition.x,
          lastPosition.y,
          midPoint.x,
          midPoint.y
        );
        context.stroke();

        setLastPosition(midPoint);
        setCurrentPath(
          (prev) =>
            prev +
            ` Q ${lastPosition.x},${lastPosition.y} ${midPoint.x},${midPoint.y}`
        );
      } else {
        // Tracé direct pour les mouvements lents
        context.beginPath();
        context.moveTo(lastPosition.x, lastPosition.y);
        context.lineTo(currentPos.x, currentPos.y);
        context.stroke();

        setLastPosition(currentPos);
        setCurrentPath((prev) => prev + ` L ${currentPos.x},${currentPos.y}`);
      }

      setIsEmpty(false);
    },
    [isDrawing, lastPosition, disabled]
  );

  // Arrêter le dessin
  const stopDrawing = useCallback(
    (e) => {
      if (!isDrawing) return;

      e.preventDefault();
      setIsDrawing(false);

      // Ajouter le path terminé aux paths SVG
      if (currentPath) {
        setSvgPaths((prev) => [...prev, currentPath]);
        setCurrentPath('');
      }

      // Notifier le parent du changement avec PNG pour garantir
      // la compatibilite de rendu cote backend/PDF.
      if (onChange) {
        const canvas = canvasRef.current;
        const pngData = canvas ? canvas.toDataURL('image/png') : '';
        onChange(pngData);
      }
    },
    [isDrawing, onChange, svgPaths, currentPath]
  );

  // Générer le SVG à partir des paths
  const generateSVG = (paths) => {
    const svgContent = `<svg width="${displayWidth}" height="${displayHeight}" xmlns="http://www.w3.org/2000/svg">
      <rect width="100%" height="100%" fill="${backgroundColor}"/>
      ${paths
        .map(
          (path) =>
            `<path d="${path}" stroke="${penColor}" stroke-width="${penWidth}" stroke-linecap="round" stroke-linejoin="round" fill="none"/>`
        )
        .join('\n      ')}
    </svg>`;

    return `data:image/svg+xml;base64,${btoa(svgContent)}`;
  };

  // Effacer la signature
  const clearSignature = () => {
    const canvas = canvasRef.current;
    const context = canvas.getContext('2d');

    // Effacer en tenant compte des dimensions d'affichage
    context.clearRect(0, 0, displayWidth, displayHeight);
    context.fillStyle = backgroundColor;
    context.fillRect(0, 0, displayWidth, displayHeight);
    setIsEmpty(true);
    setSvgPaths([]);
    setCurrentPath('');
    setSmoothingPoints([]);

    if (onChange) {
      onChange('');
    }
  };

  const hintText = readOnly
    ? isEmpty
      ? 'Aucune signature'
      : 'Signature'
    : isEmpty
      ? 'Signez dans la zone ci-dessus'
      : 'Signature capturée';

  return (
    <div className="signature-field">
      {label && (
        <label className="block text-sm font-medium text-gray-700 mb-2">
          {label}
          {required && <span className="text-red-500 ml-1">*</span>}
        </label>
      )}

      <div className="border border-gray-300 rounded-lg p-3 bg-gray-50">
        <canvas
          ref={canvasRef}
          className={`border border-gray-200 bg-white rounded touch-none ${
            readOnly ? 'cursor-default' : 'cursor-crosshair'
          }`}
          style={{
            maxWidth: '100%',
            height: 'auto',
            opacity: disabled || readOnly ? 0.7 : 1,
            cursor: disabled
              ? 'not-allowed'
              : readOnly
                ? 'default'
                : 'crosshair',
          }}
          onMouseDown={readOnly ? undefined : startDrawing}
          onMouseMove={readOnly ? undefined : draw}
          onMouseUp={readOnly ? undefined : stopDrawing}
          onMouseLeave={readOnly ? undefined : stopDrawing}
          onTouchStart={readOnly ? undefined : startDrawing}
          onTouchMove={readOnly ? undefined : draw}
          onTouchEnd={readOnly ? undefined : stopDrawing}
        />

        <div className="flex justify-between items-center mt-2">
          <div className="text-xs text-gray-500">{hintText}</div>

          {!readOnly && (
            <div className="flex gap-2">
              <button
                type="button"
                onClick={clearSignature}
                disabled={disabled || isEmpty}
                className="flex items-center gap-1 px-3 py-1 text-xs bg-red-100 text-red-600 rounded hover:bg-red-200 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <RotateCcw size={12} />
                Effacer
              </button>
            </div>
          )}
        </div>

        {required && isEmpty && (
          <div className="text-xs text-red-500 mt-1">
            La signature est obligatoire
          </div>
        )}
      </div>
    </div>
  );
};

export default SignatureField;
