import { useState, useRef, useCallback } from "react";
import { trpc } from "@/lib/trpc";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Activity,
  CheckCircle,
  XCircle,
  Loader2,
  RefreshCw,
  ChevronLeft,
  ChevronRight,
  Clock,
  FileText,
  Upload,
  FileSpreadsheet,
  AlertCircle,
} from "lucide-react";
import { format } from "date-fns";
import { fr } from "date-fns/locale";
import { cn } from "@/lib/utils";
import { toast } from "sonner";

interface ImportLog {
  id: number;
  fileType: "veille" | "aap";
  status: "success" | "error" | "partial";
  newRows: number | null;
  skippedRows: number | null;
  totalRows: number | null;
  errorMessage: string | null;
  startedAt: Date;
  completedAt: Date | null;
  source: string | null;
}

interface UploadResult {
  success: boolean;
  fileType: "veille" | "aap";
  fileName: string;
  totalRows: number;
  newRows: number;
  skippedRows: number;
  errors: string[];
  status: "success" | "partial" | "error";
  error?: string;
}

const STATUS_CONFIG = {
  success: { label: "Succès", color: "bg-emerald-100 text-emerald-800 border-emerald-200", icon: <CheckCircle size={12} /> },
  error: { label: "Erreur", color: "bg-red-100 text-red-800 border-red-200", icon: <XCircle size={12} /> },
  partial: { label: "Partiel", color: "bg-amber-100 text-amber-800 border-amber-200", icon: <Activity size={12} /> },
};

const FILE_CONFIG = {
  veille: { label: "Veille Stratégique", color: "bg-blue-100 text-blue-800 border-blue-200" },
  aap: { label: "Appels à Projets", color: "bg-violet-100 text-violet-800 border-violet-200" },
};

const PAGE_SIZE = 20;

// ─── Composant UploadZone ─────────────────────────────────────────────────────

function UploadZone({
  fileType,
  label,
  color,
  onSuccess,
}: {
  fileType: "veille" | "aap";
  label: string;
  color: string;
  onSuccess: () => void;
}) {
  const [isDragging, setIsDragging] = useState(false);
  const [isUploading, setIsUploading] = useState(false);
  const [lastResult, setLastResult] = useState<UploadResult | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleFile = useCallback(
    async (file: File) => {
      if (!file) return;
      if (!file.name.endsWith(".xlsx") && !file.name.endsWith(".xls")) {
        toast.error("Seuls les fichiers Excel (.xlsx, .xls) sont acceptés");
        return;
      }

      setIsUploading(true);
      setLastResult(null);

      try {
        const formData = new FormData();
        formData.append("file", file);
        formData.append("fileType", fileType);

        const res = await fetch("/api/upload-excel", {
          method: "POST",
          body: formData,
        });

        const data: UploadResult = await res.json();

        if (!res.ok || !data.success) {
          throw new Error(data.error || "Erreur lors de l'import");
        }

        setLastResult(data);
        onSuccess();

        if (data.newRows > 0) {
          toast.success(`Import réussi — ${data.newRows} nouvelle(s) entrée(s) ajoutée(s)`);
        } else {
          toast.info(`Import terminé — aucune nouvelle entrée (${data.skippedRows} déjà présentes)`);
        }
      } catch (e: unknown) {
        const msg = e instanceof Error ? e.message : String(e);
        toast.error(`Erreur : ${msg}`);
        setLastResult({ success: false, fileType, fileName: file.name, totalRows: 0, newRows: 0, skippedRows: 0, errors: [msg], status: "error", error: msg });
      } finally {
        setIsUploading(false);
      }
    },
    [fileType, onSuccess]
  );

  const onDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragging(false);
      const file = e.dataTransfer.files[0];
      if (file) handleFile(file);
    },
    [handleFile]
  );

  return (
    <div className="space-y-3">
      <div
        className={cn(
          "relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all duration-200",
          isDragging ? "border-primary bg-primary/5 scale-[1.01]" : "border-border hover:border-primary/50 hover:bg-muted/30",
          isUploading && "pointer-events-none opacity-60"
        )}
        onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={onDrop}
        onClick={() => inputRef.current?.click()}
      >
        <input
          ref={inputRef}
          type="file"
          accept=".xlsx,.xls"
          className="hidden"
          onChange={(e) => { const f = e.target.files?.[0]; if (f) handleFile(f); e.target.value = ""; }}
        />

        {isUploading ? (
          <div className="flex flex-col items-center gap-2">
            <Loader2 size={28} className="animate-spin text-primary" />
            <p className="text-sm text-muted-foreground">Import en cours…</p>
          </div>
        ) : (
          <div className="flex flex-col items-center gap-2">
            <div className={cn("w-10 h-10 rounded-lg flex items-center justify-center", color)}>
              <FileSpreadsheet size={20} />
            </div>
            <div>
              <p className="text-sm font-medium text-foreground">{label}</p>
              <p className="text-xs text-muted-foreground mt-0.5">
                Glissez-déposez ou <span className="text-primary underline">parcourez</span>
              </p>
              <p className="text-xs text-muted-foreground/60 mt-0.5">.xlsx ou .xls · max 50 MB</p>
            </div>
          </div>
        )}
      </div>

      {/* Résultat du dernier upload */}
      {lastResult && (
        <div className={cn(
          "rounded-lg border px-4 py-3 text-sm flex items-start gap-3",
          lastResult.status === "success" ? "bg-emerald-50 border-emerald-200 text-emerald-800" :
          lastResult.status === "partial" ? "bg-amber-50 border-amber-200 text-amber-800" :
          "bg-red-50 border-red-200 text-red-800"
        )}>
          {lastResult.status === "success" ? <CheckCircle size={16} className="mt-0.5 shrink-0" /> :
           lastResult.status === "partial" ? <AlertCircle size={16} className="mt-0.5 shrink-0" /> :
           <XCircle size={16} className="mt-0.5 shrink-0" />}
          <div>
            <p className="font-medium">{lastResult.fileName}</p>
            <p className="text-xs mt-0.5">
              {lastResult.newRows} nouvelle(s) · {lastResult.skippedRows} ignorée(s) · {lastResult.totalRows} total
            </p>
            {lastResult.errors.length > 0 && (
              <p className="text-xs mt-1 opacity-80">{lastResult.errors[0]}</p>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Page principale ──────────────────────────────────────────────────────────

export default function ImportLogs() {
  const [page, setPage] = useState(1);

  const logsQuery = trpc.import.logs.useQuery({ page, pageSize: PAGE_SIZE });
  const importMutation = trpc.import.run.useMutation({
    onSuccess: () => logsQuery.refetch(),
  });

  const logs = (logsQuery.data?.logs ?? []) as unknown as ImportLog[];
  const total = logsQuery.data?.total ?? 0;
  const totalPages = Math.ceil(total / PAGE_SIZE);

  const handleUploadSuccess = () => {
    logsQuery.refetch();
  };

  return (
    <div className="p-6 space-y-6 animate-fade-up">
      {/* En-tête */}
      <div className="flex items-start justify-between gap-4">
        <div>
          <div className="flex items-center gap-2 mb-1">
            <Activity size={22} className="text-primary" />
            <h1 className="text-2xl font-bold text-foreground">Logs d'import</h1>
          </div>
          <p className="text-muted-foreground text-sm">Historique des imports automatiques et manuels</p>
        </div>
        <Button
          onClick={() => importMutation.mutate({ type: "all" })}
          disabled={importMutation.isPending}
          variant="outline"
          className="gap-2"
        >
          {importMutation.isPending ? <Loader2 size={15} className="animate-spin" /> : <RefreshCw size={15} />}
          Import depuis chemin configuré
        </Button>
      </div>

      {/* Upload direct */}
      <Card className="border-primary/20 bg-gradient-to-br from-primary/3 to-transparent">
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <Upload size={18} className="text-primary" />
            Import direct depuis votre ordinateur
          </CardTitle>
          <p className="text-xs text-muted-foreground">
            Déposez vos fichiers Excel directement — les nouvelles entrées seront ajoutées immédiatement
          </p>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <UploadZone
              fileType="veille"
              label="Veille Stratégique"
              color="bg-blue-100 text-blue-700"
              onSuccess={handleUploadSuccess}
            />
            <UploadZone
              fileType="aap"
              label="Appels à Projets"
              color="bg-violet-100 text-violet-700"
              onSuccess={handleUploadSuccess}
            />
          </div>
        </CardContent>
      </Card>

      {/* Stats rapides */}
      {logsQuery.data?.stats && (
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
          {[
            { label: "Total imports", value: logsQuery.data.stats.total, icon: <FileText size={16} />, color: "text-primary" },
            { label: "Succès", value: logsQuery.data.stats.success, icon: <CheckCircle size={16} />, color: "text-emerald-600" },
            { label: "Erreurs", value: logsQuery.data.stats.errors, icon: <XCircle size={16} />, color: "text-red-500" },
            { label: "Nouvelles entrées", value: logsQuery.data.stats.totalNewRows, icon: <Activity size={16} />, color: "text-accent" },
          ].map((stat) => (
            <Card key={stat.label} className="border-border/50">
              <CardContent className="p-4">
                <div className={cn("flex items-center gap-2 mb-1", stat.color)}>
                  {stat.icon}
                  <span className="text-xs font-medium text-muted-foreground">{stat.label}</span>
                </div>
                <p className={cn("text-2xl font-bold", stat.color)}>{stat.value}</p>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      {/* Tableau des logs */}
      <Card>
        <CardContent className="p-0">
          {logsQuery.isLoading ? (
            <div className="flex items-center justify-center py-16">
              <Loader2 size={28} className="animate-spin text-primary" />
            </div>
          ) : logs.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-16 text-center">
              <Activity size={40} className="text-muted-foreground/30 mb-3" />
              <p className="text-muted-foreground">Aucun log d'import</p>
              <p className="text-xs text-muted-foreground/60 mt-1">Les imports apparaîtront ici</p>
            </div>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-border bg-muted/30">
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground">Date</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-36">Fichier</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-24">Statut</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-28">Nouvelles</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-24">Ignorées</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-24">Total</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-24">Durée</th>
                    <th className="text-left px-4 py-3 font-semibold text-muted-foreground">Source</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-border">
                  {logs.map((log) => {
                    const status = STATUS_CONFIG[log.status] || STATUS_CONFIG.error;
                    const fileConf = FILE_CONFIG[log.fileType] || FILE_CONFIG.veille;
                    return (
                      <tr key={log.id} className="hover:bg-muted/20 transition-colors">
                        <td className="px-4 py-3 text-xs text-muted-foreground whitespace-nowrap">
                          <div className="flex items-center gap-1">
                            <Clock size={11} />
                            {format(new Date(log.startedAt), "d MMM yyyy HH:mm", { locale: fr })}
                          </div>
                        </td>
                        <td className="px-4 py-3">
                          <Badge variant="outline" className={cn("text-xs", fileConf.color)}>
                            {fileConf.label}
                          </Badge>
                        </td>
                        <td className="px-4 py-3">
                          <Badge variant="outline" className={cn("text-xs gap-1", status.color)}>
                            {status.icon}
                            {status.label}
                          </Badge>
                        </td>
                        <td className="px-4 py-3">
                          <span className="font-semibold text-emerald-600">+{log.newRows ?? 0}</span>
                        </td>
                        <td className="px-4 py-3 text-muted-foreground">{log.skippedRows ?? 0}</td>
                        <td className="px-4 py-3 text-muted-foreground">{log.totalRows ?? 0}</td>
                        <td className="px-4 py-3 text-xs text-muted-foreground">
                          {log.startedAt && log.completedAt
                            ? `${((new Date(log.completedAt).getTime() - new Date(log.startedAt).getTime()) / 1000).toFixed(1)}s`
                            : "—"}
                        </td>
                        <td className="px-4 py-3 text-xs text-muted-foreground max-w-xs truncate">
                          {log.source
                            ? log.source.split(/[\\/]/).pop() || log.source
                            : "—"}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-center gap-2">
          <Button variant="outline" size="sm" onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page === 1}>
            <ChevronLeft size={14} />
          </Button>
          <span className="text-sm text-muted-foreground px-2">Page {page} / {totalPages}</span>
          <Button variant="outline" size="sm" onClick={() => setPage((p) => Math.min(totalPages, p + 1))} disabled={page === totalPages}>
            <ChevronRight size={14} />
          </Button>
        </div>
      )}
    </div>
  );
}
