"use client";

import { useState, useMemo, useEffect } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { LuCheck } from "react-icons/lu";
import imageCompression from "browser-image-compression";

// Importa los componentes de los 4 pasos
import Step1SelectMethod from "./components/Step1UploadBox";
import Step2ReviewSelection from "./components/Step2FileSelection";
import Step3Processing from "./components/Step3Processing";
import Step4Success from "./components/Step4ReviewAndSave";
import { useFieldsConfig } from "./components/FieldsConfigContext";
import FieldsConfigModal from "./components/FieldsConfigModal";

// Tipos de datos
export interface ManagedFile {
  id: string;
  file: File;
  status: "pending" | "processing" | "completed" | "error" | "saving" | "saved";
  progress: number;
  extractedData?: Record<string, string | number | boolean | null>;
  errorMessage?: string;
  savedId?: string;
}

// Stepper UI Component
const Stepper = ({ currentStep }: { currentStep: number }) => {
  const stepsInfo = [
    { number: 1, title: "Selección", icon: "📤" },
    { number: 2, title: "Confirmación", icon: "✅" },
    { number: 3, title: "Procesamiento", icon: "⚙️" },
    { number: 4, title: "Resultados", icon: "🎉" },
  ];

  return (
    <div className="flex items-center justify-center w-full max-w-3xl mx-auto mb-8 px-4">
      {stepsInfo.map(({ number, title, icon }, index) => (
        <div key={number} className="flex items-center flex-1 last:flex-none">
          <div className="flex flex-col items-center">
            <div
              className={`h-10 w-10 md:h-12 md:w-12 rounded-full flex items-center justify-center font-bold text-sm md:text-base transition-all duration-300 shadow-md ${
                currentStep >= number
                  ? "bg-gradient-to-br from-primary to-primary-hover text-primary-foreground scale-110"
                  : "bg-background text-text-subtle border-2 border-border-subtle"
              }`}
              aria-current={currentStep >= number ? "step" : undefined}
            >
              {currentStep > number ? (
                <LuCheck size={18} className="md:w-[20px] md:h-[20px]" />
              ) : (
                <span>{icon}</span>
              )}
            </div>
            <span
              className={`text-xs md:text-sm font-medium mt-2 text-center hidden sm:block transition-colors ${
                currentStep >= number ? "text-primary font-semibold" : "text-text-subtle"
              }`}
            >
              {title}
            </span>
          </div>
          {index < stepsInfo.length - 1 && (
            <div className="flex-1 h-1 bg-border-subtle mx-2 md:mx-4 relative rounded-full overflow-hidden">
              <div
                className={`absolute top-0 left-0 h-full transition-all duration-500 rounded-full ${
                  currentStep > number ? "bg-gradient-to-r from-primary to-primary-hover w-full" : "w-0"
                }`}
              />
            </div>
          )}
        </div>
      ))}
    </div>
  );
};

// Función para convertir archivo a Base64 y comprimir
const fileToBase64 = async (file: File): Promise<string> => {
  if (file.type.startsWith("image/")) {
    const options = { maxSizeMB: 1, maxWidthOrHeight: 1920, useWebWorker: true };
    const compressedFile = await imageCompression(file, options);
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(compressedFile);
      reader.onload = () => resolve((reader.result as string)?.split(",")[1] || "");
      reader.onerror = (error) => reject(error);
    });
  }
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve((reader.result as string)?.split(",")[1] || "");
    reader.onerror = (error) => reject(error);
  });
};

export default function ScannerPage() {
  const { data: session, status } = useSession();
  const router = useRouter();
  const [files, setFiles] = useState<ManagedFile[]>([]);
  const [isProcessing, setIsProcessing] = useState(false);
  const { showModal, fields, setFields, saveFields, closeModal, resetFields } = useFieldsConfig();

  // Estados para categorías
  const [categories, setCategories] = useState<Array<{ id: string; name: string; icon: string | null; color: string | null }>>([]);
  const [selectedCategory, setSelectedCategory] = useState<string>("");

  // Cargar categorías al montar
  useEffect(() => {
    const loadCategories = async () => {
      try {
        const res = await fetch("/api/categories");
        const data = await res.json();
        if (data.success) {
          setCategories(data.categories);
        }
      } catch (error) {
        console.error("Error al cargar categorías:", error);
      }
    };

    if (session) {
      loadCategories();
    }
  }, [session]);

  const currentStep = useMemo(() => {
    if (files.length === 0) return 1;
    if (files.some((f) => f.status === "pending")) return 2;
    if (files.some((f) => ["processing", "saving"].includes(f.status))) return 3;
    if (files.some((f) => ["completed", "saved", "error"].includes(f.status))) return 4;
    return 1;
  }, [files]);

  const updateFileState = (id: string, updates: Partial<ManagedFile>) => {
    setFiles((prev) => prev.map((f) => (f.id === id ? { ...f, ...updates } : f)));
  };

  const handleFilesSelected = (selectedFiles: FileList | null) => {
    if (selectedFiles) {
      const newFiles: ManagedFile[] = Array.from(selectedFiles).map((file) => ({
        id: `${file.name}-${file.lastModified}-${Date.now()}`,
        file,
        status: "pending",
        progress: 0,
      }));
      setFiles((prev) => [...prev, ...newFiles]);
    }
  };

  const removeFile = (id: string) => setFiles((prev) => prev.filter((f) => f.id !== id));

  const resetProcess = () => setFiles([]);

  const handleDataChange = (id: string, key: string, value: string) => {
    setFiles((prev) =>
      prev.map((f) =>
        f.id === id && f.extractedData
          ? { ...f, extractedData: { ...f.extractedData, [key]: value } }
          : f
      )
    );
  };

  const handleSaveData = async (id: string) => {
    const fileToSave = files.find((f) => f.id === id);
    if (!fileToSave || !fileToSave.extractedData) return;

    try {
      updateFileState(id, { status: "saving" });

      if (!session?.user?.id) throw new Error("Usuario no autenticado.");

      const base64File = await fileToBase64(fileToSave.file);

      const savePayload = {
        fileName: fileToSave.file.name,
        fileData: base64File,
        mimeType: fileToSave.file.type,
        extractedData: fileToSave.extractedData,
        ownerId: session.user.id,
        categoryId: selectedCategory,
      };

      const saveResponse = await fetch("/api/documents", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(savePayload),
      });

      if (!saveResponse.ok) {
        const errorResult = await saveResponse.json();
        throw new Error(errorResult.error || `Error ${saveResponse.status} al guardar.`);
      }

      const saveResult = await saveResponse.json();

      updateFileState(id, {
        status: "saved",
        savedId: saveResult.documentId,
      });
      
      // Disparar evento para actualizar dashboard
      window.dispatchEvent(new CustomEvent('document-saved'));
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      updateFileState(id, { status: "error", errorMessage });
    }
  };

  const handleSaveAll = async () => {
    const filesToSave = files.filter((f) => f.status === "completed");

    for (const fileToSave of filesToSave) {
      await handleSaveData(fileToSave.id);
    }
    
    // Disparar evento para actualizar dashboard después de guardar todos
    if (filesToSave.length > 0) {
      setTimeout(() => {
        window.dispatchEvent(new CustomEvent('document-saved'));
      }, 500);
    }
  };

  const processFiles = async () => {
    setIsProcessing(true);
    const filesToProcess = files.filter((f) => f.status === "pending");

    for (const managedFile of filesToProcess) {
      try {
        updateFileState(managedFile.id, { status: "processing", progress: 25 });
        const base64File = await fileToBase64(managedFile.file);

        updateFileState(managedFile.id, { progress: 50 });
        const response = await fetch("/api/upload", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            imageParts: [{ data: base64File, mimeType: managedFile.file.type }],
            customFields: fields
          }),
        });
        const result = await response.json();

        if (!response.ok) throw new Error(result.error || "Error del servidor de extracción.");

        updateFileState(managedFile.id, {
          status: 'completed',
          progress: 100,
          extractedData: result
        });

      } catch (err: unknown) {
        const errorMessage = err instanceof Error ? err.message : String(err);
        updateFileState(managedFile.id, { status: "error", progress: 100, errorMessage });
      }

      // Pausa de 4.1 segundos para respetar el límite de 15 peticiones por minuto.
      await new Promise(resolve => setTimeout(resolve, 4100));
    }
    setIsProcessing(false);
  };

  if (status === "loading") return <div className="text-center p-12">Cargando...</div>;
  if (status === "unauthenticated") {
    router.push("/login");
    return null;
  }

  return (
    <>
      {showModal && (
        <FieldsConfigModal
          fields={fields}
          setFields={setFields}
          onSave={saveFields}
          onClose={closeModal}
          onReset={resetFields}
        />
      )}

      {/* Header */}
      <div className="mb-8 animate-fade-in">
        <h1 className="text-2xl md:text-3xl font-bold text-text">Escanear Documento</h1>
        <p className="text-text-muted text-sm mt-2">
          Extrae datos automáticamente de tus archivos en segundos usando IA
        </p>
      </div>

      <Stepper currentStep={currentStep} />

      <div className="bg-background rounded-2xl shadow-sm border border-border-subtle p-5 md:p-8 animate-scale-in">
        {currentStep === 1 && (
          <Step1SelectMethod
            onFilesSelected={handleFilesSelected}
            categories={categories}
            selectedCategory={selectedCategory}
            onCategoryChange={setSelectedCategory}
          />
        )}
        {currentStep === 2 && (
          <Step2ReviewSelection
            files={files.filter(f => f.status === 'pending')}
            onRemoveFile={removeFile}
            onProcessFiles={processFiles}
            isProcessing={isProcessing}
            onAddMore={handleFilesSelected}
            onBack={resetProcess}
          />
        )}
        {currentStep === 3 && <Step3Processing files={files.filter(f => f.status === 'processing' || f.status === 'saving')} />}
        {currentStep === 4 && <Step4Success files={files.filter(f => f.status === 'completed' || f.status === 'saved' || f.status === 'error')} onReset={resetProcess} onDataChange={handleDataChange} onSaveData={handleSaveData} onSaveAll={handleSaveAll} selectedCategory={selectedCategory} categories={categories} />}

        {/* Footer */}
        {currentStep === 1 && (
          <div className="mt-6 pt-5 border-t border-border-subtle flex items-center justify-between">
            <button className="text-sm text-text-subtle hover:text-primary flex items-center gap-1.5 transition-colors">
              <span className="text-lg">❓</span>
              ¿Necesitas ayuda?
            </button>
            <button
              disabled={!selectedCategory || files.length === 0}
              className="px-6 py-2.5 bg-primary text-primary-foreground rounded-lg font-medium hover:bg-primary-hover transition-colors disabled:bg-background-alt disabled:text-text-subtle disabled:cursor-not-allowed"
            >
              Continuar
            </button>
          </div>
        )}
      </div>
    </>
  );
} 