import { motion } from "framer-motion";
import { FileSpreadsheet, Loader2, X } from "lucide-react";
import { humanDateTime } from "../lib/metrics";
import { MODAL_TRANSITION } from "../lib/motion";
import { MiniMetric } from "./MetricTiles";
import { Modal } from "./Modal";
import type { ImportPreview, ImportPreviewRow, ImportProgress } from "../types";

type ImportPreviewModalProps = {
  busy: boolean;
  preview: ImportPreview | null;
  importProgress: ImportProgress | null;
  onClose: () => void;
  onConfirm: () => void;
};

export function ImportPreviewModal({
  busy,
  preview,
  importProgress,
  onClose,
  onConfirm,
}: ImportPreviewModalProps) {
  const validRows = preview?.rows.filter((row) => row.entry && !row.errors.length && !row.duplicate) ?? [];
  const invalidRows = preview?.rows.filter((row) => row.errors.length) ?? [];
  const duplicateRows = preview?.rows.filter((row) => row.duplicate) ?? [];

  return (
    <Modal open={Boolean(preview)} onClose={onClose} labelledBy="import-preview-title">
      {preview && (
        <motion.div
          className="modal-panel max-w-5xl"
          initial={{ opacity: 0, y: 18, scale: 0.98 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          exit={{ opacity: 0, y: 14, scale: 0.98 }}
          transition={MODAL_TRANSITION}
        >
          <div className="mb-5 flex items-start justify-between gap-4">
            <div>
              <p className="text-sm font-medium uppercase tracking-[0.18em] text-pink-100">
                {preview.fileName.toLowerCase().endsWith(".json") ? "JSON import" : "Excel import"}
              </p>
              <h2 id="import-preview-title" className="mt-1 text-3xl font-semibold tracking-tight text-white">
                Preview rows
              </h2>
              <p className="mt-2 text-sm text-slate-400">{preview.fileName}</p>
            </div>
            <button className="icon-button" type="button" onClick={onClose} aria-label="Close import preview">
              <X size={18} aria-hidden="true" />
            </button>
          </div>

          <div className="mb-4 grid gap-3 sm:grid-cols-3">
            <MiniMetric label="Ready" value={`${validRows.length}`} accent="#39d5ff" />
            <MiniMetric label="Duplicates" value={`${duplicateRows.length}`} accent="#ffd84d" />
            <MiniMetric label="Invalid" value={`${invalidRows.length}`} accent="#ff3448" />
          </div>

          <div className="hidden max-h-[48vh] overflow-auto rounded-lg border border-white/10 sm:block">
            <table className="w-full min-w-[760px] border-collapse text-left text-sm">
              <thead className="sticky top-0 bg-[#0d142c] text-xs uppercase tracking-[0.14em] text-slate-400">
                <tr>
                  <th className="px-3 py-3">Row</th>
                  <th className="px-3 py-3">Status</th>
                  <th className="px-3 py-3">Date</th>
                  <th className="px-3 py-3">Flavour</th>
                  <th className="px-3 py-3">Size</th>
                  <th className="px-3 py-3">Cans</th>
                  <th className="px-3 py-3">Message</th>
                </tr>
              </thead>
              <tbody>
                {preview.rows.map((row) => (
                  <tr key={row.rowNumber} className="border-t border-white/10">
                    <td className="px-3 py-3 text-slate-400">{row.rowNumber}</td>
                    <td className="px-3 py-3">
                      <ImportStatusBadge invalid={row.errors.length > 0} duplicate={row.duplicate} />
                    </td>
                    <td className="px-3 py-3 text-slate-300">{row.entry ? humanDateTime(row.entry.dateTime) : "-"}</td>
                    <td className="px-3 py-3 text-white">{row.entry?.flavour ?? "-"}</td>
                    <td className="px-3 py-3 text-slate-300">{row.entry ? `${row.entry.sizeMl}ml` : "-"}</td>
                    <td className="px-3 py-3 text-slate-300">{row.entry?.cans ?? "-"}</td>
                    <td className="px-3 py-3 text-slate-400">{rowMessage(row)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          <div className="grid max-h-[48vh] gap-2 overflow-auto sm:hidden">
            {preview.rows.map((row) => (
              <article key={row.rowNumber} className="rounded-lg border border-white/10 p-3">
                <div className="flex items-center justify-between gap-2">
                  <span className="text-xs text-slate-400">Row {row.rowNumber}</span>
                  <ImportStatusBadge invalid={row.errors.length > 0} duplicate={row.duplicate} />
                </div>
                <p className="mt-2 text-sm text-white">{row.entry?.flavour ?? "No entry parsed"}</p>
                {row.entry ? (
                  <p className="mt-1 text-xs text-slate-400">
                    {humanDateTime(row.entry.dateTime)} · {row.entry.sizeMl}ml · {row.entry.cans} can{row.entry.cans === 1 ? "" : "s"}
                  </p>
                ) : null}
                <p className="mt-1 text-xs text-slate-400">{rowMessage(row)}</p>
              </article>
            ))}
          </div>

          <div className="mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-end">
            {busy && importProgress ? (
              <p className="text-center text-sm text-slate-400 sm:mr-auto" role="status" aria-live="polite">
                Importing {importProgress.done} of {importProgress.total}…
              </p>
            ) : null}
            <button className="secondary-button justify-center" type="button" onClick={onClose}>
              Cancel
            </button>
            <button className="excel-button justify-center" type="button" disabled={!validRows.length || busy} onClick={onConfirm}>
              {busy ? <Loader2 className="animate-spin" size={17} aria-hidden="true" /> : <FileSpreadsheet size={17} aria-hidden="true" />}
              Import {validRows.length} row{validRows.length === 1 ? "" : "s"}
            </button>
          </div>
        </motion.div>
      )}
    </Modal>
  );
}

function ImportStatusBadge({ invalid, duplicate }: { invalid: boolean; duplicate: boolean }) {
  return (
    <span className={`rounded px-2 py-1 text-xs font-semibold ${invalid ? "bg-red-500/15 text-red-100" : duplicate ? "bg-amber-300/15 text-amber-100" : "bg-cyan-300/15 text-cyan-100"}`}>
      {invalid ? "Invalid" : duplicate ? "Duplicate" : "Ready"}
    </span>
  );
}

function rowMessage(row: ImportPreviewRow) {
  return row.errors.join(" ") || row.duplicateReason || "Looks good.";
}
