// src/components/backlink/import-sources-dialog.tsx
"use client";

import { DownloadIcon, ImportIcon } from "lucide-react";
import { useRef, useState } from "react";
import { QuotaNotice } from "@/components/billing/quota-notice";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  commitImportAction,
  previewImportAction,
} from "@/lib/backlink/import-actions";
import type { PreviewResult } from "@/lib/backlink/import-types";
import type { QuotaExceeded } from "@/lib/billing/quotas";

export function ImportSourcesDialog({
  open,
  onOpenChange,
}: {
  open: boolean;
  onOpenChange: (o: boolean) => void;
}) {
  const [csv, setCsv] = useState<string | null>(null);
  const [preview, setPreview] = useState<PreviewResult | null>(null);
  const [pending, setPending] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [quota, setQuota] = useState<QuotaExceeded | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  function reset() {
    setCsv(null);
    setPreview(null);
    setPending(false);
    setQuota(null);
  }

  async function loadFile(file: File) {
    // Server Actions cap the payload at 1 MB; reject oversized files up front.
    if (file.size > 1_000_000) {
      setError("Fichier trop lourd (max 1 Mo).");
      return;
    }
    setError(null);
    const text = await file.text();
    setCsv(text);
    setPending(true);
    try {
      setPreview(await previewImportAction(text));
    } catch {
      setError("Import impossible (fichier invalide ou trop volumineux).");
    } finally {
      setPending(false);
    }
  }

  async function commit() {
    if (!csv) return;
    setQuota(null);
    setPending(true);
    try {
      const res = await commitImportAction(csv);
      if (res.quota) {
        setQuota(res.quota);
        return;
      }
      onOpenChange(false);
      reset();
    } finally {
      setPending(false);
    }
  }

  const importable = preview
    ? preview.counts.created + preview.counts.updated
    : 0;

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) reset();
        onOpenChange(o);
      }}
    >
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Importer des sources</DialogTitle>
          <DialogDescription>
            CSV au format du gabarit. Les doublons (même URL) sont mis à jour.
          </DialogDescription>
        </DialogHeader>

        {quota ? <QuotaNotice quota={quota} kind="import" /> : null}
        {error ? (
          <p className="text-destructive text-sm" role="alert">
            {error}
          </p>
        ) : null}

        {!preview ? (
          <div className="grid gap-2">
            <button
              type="button"
              onClick={() => inputRef.current?.click()}
              onDragOver={(e) => {
                e.preventDefault();
                setDragOver(true);
              }}
              onDragLeave={() => setDragOver(false)}
              onDrop={(e) => {
                e.preventDefault();
                setDragOver(false);
                const f = e.dataTransfer.files[0];
                if (f) loadFile(f);
              }}
              className={`flex h-40 w-full flex-col items-center justify-center gap-2 rounded-lg border border-dashed text-muted-foreground text-sm transition-colors ${
                dragOver ? "border-ring bg-muted/50" : "border-input"
              }`}
            >
              <ImportIcon className="size-6" />
              {pending
                ? "Analyse…"
                : "Dépose ton .csv ici, ou clique pour parcourir"}
              <input
                ref={inputRef}
                type="file"
                accept=".csv,text/csv"
                className="hidden"
                onChange={(e) => {
                  const f = e.target.files?.[0];
                  if (f) loadFile(f);
                }}
              />
            </button>
            <a
              href="/backlink/reservoir/template"
              download
              className="inline-flex items-center justify-center gap-1.5 text-primary text-sm underline underline-offset-4 hover:opacity-80"
            >
              <DownloadIcon className="size-4" aria-hidden />
              Télécharger le gabarit CSV
            </a>
          </div>
        ) : (
          <div className="grid gap-3">
            <div className="max-h-72 overflow-auto rounded-lg border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Statut</TableHead>
                    <TableHead>Plateforme</TableHead>
                    <TableHead>URL</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {preview.rows.map((r) => (
                    <TableRow key={r.id ?? r.url ?? r.error}>
                      <TableCell>
                        {r.status === "new" ? (
                          <Badge>nouvelle</Badge>
                        ) : r.status === "update" ? (
                          <Badge variant="secondary">mise à jour</Badge>
                        ) : (
                          <Badge variant="destructive">erreur</Badge>
                        )}
                      </TableCell>
                      <TableCell>{r.platform ?? r.error}</TableCell>
                      <TableCell className="text-muted-foreground text-xs">
                        {r.url}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
            <p className="text-muted-foreground text-sm">
              {preview.counts.created} nouvelle(s) · {preview.counts.updated}{" "}
              mise(s) à jour · {preview.counts.errors} erreur(s)
            </p>
            <div className="flex justify-end gap-2">
              <Button variant="outline" onClick={reset} disabled={pending}>
                Choisir un autre fichier
              </Button>
              <Button onClick={commit} disabled={pending || importable === 0}>
                {pending ? "Import…" : `Importer (${importable})`}
              </Button>
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
