"use client";

import { useState, useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Button } from "@/components/ui/button";
import { UploadCloud, FileText, X, CheckCircle, AlertCircle, Loader2 } from "lucide-react";

interface PaymentUploadProps {
  appointmentId: number;
  onUploadSuccess: (fileUrl: string, extractedData: any) => void;
}

type UploadState = "idle" | "dragging" | "uploading" | "success" | "error";

export function PaymentUpload({ appointmentId, onUploadSuccess }: PaymentUploadProps) {
  const [uploadState, setUploadState] = useState<UploadState>("idle");
  const [error, setError] = useState("");
  const [extractedData, setExtractedData] = useState<any>(null);
  const [fileUrl, setFileUrl] = useState("");
  const [file, setFile] = useState<File | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    setUploadState("dragging");
  };

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    setUploadState("idle");
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setUploadState("idle");

    const droppedFile = e.dataTransfer.files[0];
    if (droppedFile) {
      processFile(droppedFile);
    }
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = e.target.files?.[0];
    if (selectedFile) {
      processFile(selectedFile);
    }
  };

  const processFile = (file: File) => {
    const allowedTypes = ["application/pdf", "image/jpeg", "image/png"];
    const maxSize = 5 * 1024 * 1024; // 5MB

    if (!allowedTypes.includes(file.type)) {
      setError("Solo se permiten archivos PDF, JPG y PNG");
      setUploadState("error");
      return;
    }

    if (file.size > maxSize) {
      setError("El archivo excede el tamaño máximo de 5MB");
      setUploadState("error");
      return;
    }

    setFile(file);
    setError("");
    uploadFile(file);
  };

  const uploadFile = async (file: File) => {
    setUploadState("uploading");

    const formData = new FormData();
    formData.append("file", file);
    formData.append("appointmentId", appointmentId.toString());

    try {
      const response = await fetch("/api/payments/upload-proof", {
        method: "POST",
        body: formData,
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || "Error al subir el archivo");
      }

      setFileUrl(data.fileUrl);
      setExtractedData(data.extractedData);
      setUploadState("success");
      onUploadSuccess(data.fileUrl, data.extractedData);
    } catch (err: any) {
      setError(err.message || "Error al procesar el archivo");
      setUploadState("error");
    }
  };

  const handleRetry = () => {
    setError("");
    setUploadState("idle");
    setExtractedData(null);
    setFileUrl("");
  };

  const getFileIcon = () => {
    if (file?.type === "application/pdf") {
      return <FileText className="h-12 w-12 text-red-500" />;
    }
    return <FileText className="h-12 w-12 text-blue-500" />;
  };

  return (
    <div className="space-y-4">
      <AnimatePresence mode="wait">
        {(uploadState === "idle" || uploadState === "dragging") && (
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            onDragOver={handleDragOver}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
            className={`relative cursor-pointer rounded-lg border-2 border-dashed p-8 text-center transition-colors ${
              uploadState === "dragging"
                ? "border-accent bg-accent/5"
                : "border-gray-300 hover:border-accent hover:bg-gray-50"
            }`}
            onClick={() => inputRef.current?.click()}
          >
            <input
              ref={inputRef}
              type="file"
              className="hidden"
              accept=".pdf,.jpg,.jpeg,.png"
              onChange={handleFileSelect}
            />

            <UploadCloud className="mx-auto mb-4 h-12 w-12 text-gray-400" />
            <p className="mb-2 text-sm font-medium text-secondary">Arrastra tu comprobante aquí</p>
            <p className="text-xs text-gray-500">o haz clic para seleccionar</p>
            <p className="mt-2 text-xs text-gray-400">PDF, JPG o PNG (máx. 5MB)</p>
          </motion.div>
        )}

        {uploadState === "uploading" && (
          <motion.div
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            className="flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 p-8"
          >
            <Loader2 className="mb-4 h-12 w-12 animate-spin text-accent" />
            <p className="text-sm font-medium text-secondary">Procesando archivo...</p>
            <p className="mt-2 text-xs text-gray-500">Esto puede tomar unos segundos</p>
          </motion.div>
        )}

        {uploadState === "success" && (
          <motion.div
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            className="rounded-lg border-2 border-green-500 bg-green-50 p-6"
          >
            <div className="flex items-start gap-4">
              <CheckCircle className="h-8 w-8 flex-shrink-0 text-green-500" />
              <div className="flex-1">
                <h4 className="mb-2 font-semibold text-green-800">
                  Comprobante procesado exitosamente
                </h4>
                {file && (
                  <div className="mb-3 flex items-center gap-2 text-sm text-green-700">
                    {getFileIcon()}
                    <span>{file.name}</span>
                  </div>
                )}
                {extractedData && Object.keys(extractedData).length > 0 && (
                  <div className="rounded-md bg-white p-3 text-sm">
                    <p className="mb-2 font-medium text-gray-700">Datos extraídos por OCR:</p>
                    <dl className="space-y-1">
                      {extractedData.amount && (
                        <div className="flex justify-between">
                          <dt className="text-gray-500">Monto:</dt>
                          <dd className="font-medium">${extractedData.amount}</dd>
                        </div>
                      )}
                      {extractedData.date && (
                        <div className="flex justify-between">
                          <dt className="text-gray-500">Fecha:</dt>
                          <dd className="font-medium">
                            {new Date(extractedData.date).toLocaleDateString("es-MX")}
                          </dd>
                        </div>
                      )}
                      {extractedData.reference && (
                        <div className="flex justify-between">
                          <dt className="text-gray-500">Referencia:</dt>
                          <dd className="font-medium">{extractedData.reference}</dd>
                        </div>
                      )}
                      {extractedData.senderName && (
                        <div className="flex justify-between">
                          <dt className="text-gray-500">Remitente:</dt>
                          <dd className="font-medium">{extractedData.senderName}</dd>
                        </div>
                      )}
                      {extractedData.senderBank && (
                        <div className="flex justify-between">
                          <dt className="text-gray-500">Banco:</dt>
                          <dd className="font-medium">{extractedData.senderBank}</dd>
                        </div>
                      )}
                    </dl>
                  </div>
                )}
              </div>
            </div>
          </motion.div>
        )}

        {uploadState === "error" && (
          <motion.div
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            className="rounded-lg border-2 border-red-500 bg-red-50 p-6"
          >
            <div className="flex items-start gap-4">
              <AlertCircle className="h-8 w-8 flex-shrink-0 text-red-500" />
              <div className="flex-1">
                <h4 className="mb-2 font-semibold text-red-800">Error al procesar el archivo</h4>
                <p className="mb-4 text-sm text-red-700">{error}</p>
                <Button
                  onClick={handleRetry}
                  variant="outline"
                  size="sm"
                  className="border-red-500 text-red-700 hover:bg-red-100"
                >
                  Reintentar
                </Button>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
