"use client";

import { useRef, useState } from "react";
import { FileSpreadsheet, Upload } from "lucide-react";
import { Button, Dialog } from "@/components/ui/kit";
import { useToast } from "@/components/ui/toast";
import { api, ApiError, download } from "@/lib/api";

export function ExportDialog({ open, onClose }: { open: boolean; onClose: () => void }) {
  const toast = useToast();
  const [busy, setBusy] = useState<"data" | "blank" | null>(null);
  async function run(kind: "data" | "blank") {
    setBusy(kind);
    try {
      await download(kind === "blank" ? "/contacts/export?template=blank" : "/contacts/export", "contacts.xlsx");
      toast("success", kind === "blank" ? "Template downloaded" : "Contacts exported");
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setBusy(null);
    }
  }
  return (
    <Dialog open={open} onClose={onClose} title="Export contacts" size="md" footer={<Button onClick={onClose}>Close</Button>}>
      <div className="divide-y divide-line">
        <div className="flex flex-wrap items-center justify-between gap-4 pb-5">
          <div className="max-w-sm">
            <h3 className="font-medium">All contacts</h3>
            <p className="mt-0.5 text-sm text-muted">An Excel file of every active contact. Edit it and import it back to update them in bulk.</p>
          </div>
          <Button variant="primary" loading={busy === "data"} onClick={() => run("data")} icon={<FileSpreadsheet className="size-4" />}>
            Export contacts
          </Button>
        </div>
        <div className="flex flex-wrap items-center justify-between gap-4 pt-5">
          <div className="max-w-sm">
            <h3 className="font-medium">Blank template</h3>
            <p className="mt-0.5 text-sm text-muted">Column headers only, including your custom fields, with filling instructions on a second sheet.</p>
          </div>
          <Button loading={busy === "blank"} onClick={() => run("blank")}>
            Download template
          </Button>
        </div>
      </div>
    </Dialog>
  );
}

interface ImportResult {
  total_rows: number;
  created: number;
  updated: number;
  skipped: number;
  errors: { row: number; message: string }[];
  warnings: { row: number; message: string }[];
}

export function ImportDialog({ open, onClose, onImported }: { open: boolean; onClose: () => void; onImported: () => void }) {
  const toast = useToast();
  const inputRef = useRef<HTMLInputElement>(null);
  const [file, setFile] = useState<File | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [result, setResult] = useState<ImportResult | null>(null);
  const [dragging, setDragging] = useState(false);

  function close() {
    setFile(null);
    setResult(null);
    setError(null);
    onClose();
  }

  function pick(f: File | undefined) {
    setError(null);
    setResult(null);
    if (!f) return;
    if (!f.name.toLowerCase().endsWith(".xlsx")) return setError("Choose an .xlsx file. Download the template from Export contacts.");
    setFile(f);
  }

  async function run() {
    if (!file) return;
    setBusy(true);
    setError(null);
    const fd = new FormData();
    fd.append("file", file);
    try {
      const r = await api.post<ImportResult>("/contacts/import", fd);
      setResult(r);
      onImported();
      toast("success", `Import finished: ${r.created} added, ${r.updated} updated`);
    } catch (e) {
      setError(e instanceof ApiError ? (e.fields.file ?? e.message) : "Upload failed. Check your connection and try again.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <Dialog
      open={open}
      onClose={close}
      title="Import contacts"
      description="Add new contacts or update existing ones from an Excel file."
      size="lg"
      footer={
        result ? (
          <Button variant="primary" onClick={close}>
            Done
          </Button>
        ) : (
          <>
            <Button onClick={close}>Cancel</Button>
            <Button variant="primary" disabled={!file} loading={busy} onClick={run}>
              Import contacts
            </Button>
          </>
        )
      }
    >
      {result ? (
        <div className="space-y-5">
          <dl className="grid grid-cols-3 gap-3 text-center">
            {[
              ["Added", result.created, "text-teal"],
              ["Updated", result.updated, "text-ink"],
              ["Skipped", result.skipped, result.skipped ? "text-brick" : "text-muted"],
            ].map(([label, n, cls]) => (
              <div key={label as string} className="rounded-lg bg-paper py-4">
                <dd className={`tabular text-2xl font-semibold ${cls}`}>{n}</dd>
                <dt className="text-sm text-muted">{label}</dt>
              </div>
            ))}
          </dl>
          {[...result.errors.map((e) => ({ ...e, kind: "error" })), ...result.warnings.map((w) => ({ ...w, kind: "warning" }))].length > 0 && (
            <div>
              <h3 className="mb-2 text-sm font-semibold">Rows that need attention</h3>
              <div className="max-h-60 overflow-y-auto rounded-md border border-line">
                <table className="w-full text-sm">
                  <thead className="text-left text-muted">
                    <tr>
                      <th scope="col" className="sticky top-0 bg-paper px-3 py-2 font-medium">Row</th>
                      <th scope="col" className="sticky top-0 bg-paper px-3 py-2 font-medium">Issue</th>
                    </tr>
                  </thead>
                  <tbody>
                    {[...result.errors.map((e) => ({ ...e, kind: "error" })), ...result.warnings.map((w) => ({ ...w, kind: "warning" }))]
                      .sort((a, b) => a.row - b.row)
                      .map((r, i) => (
                        <tr key={i} className="border-t border-line">
                          <td className="tabular px-3 py-2 align-top">{r.row}</td>
                          <td className={`px-3 py-2 ${r.kind === "error" ? "text-brick" : "text-amber"}`}>{r.message}</td>
                        </tr>
                      ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </div>
      ) : (
        <div className="space-y-5">
          <ul className="space-y-2 rounded-lg bg-paper p-4 text-sm text-muted">
            <li>
              <span className="font-medium text-text">Phone number is the key.</span> Use the country code without 0 or +. If the number already exists, that contact is updated; blank cells keep their current value.
            </li>
            <li>
              <span className="font-medium text-text">Groups are added, never removed.</span> List existing group names separated by commas.
            </li>
            <li>Start from the template in Export contacts so the columns match.</li>
          </ul>

          <button
            type="button"
            onClick={() => inputRef.current?.click()}
            onDragOver={(e) => {
              e.preventDefault();
              setDragging(true);
            }}
            onDragLeave={() => setDragging(false)}
            onDrop={(e) => {
              e.preventDefault();
              setDragging(false);
              pick(e.dataTransfer.files[0]);
            }}
            className={`flex w-full flex-col items-center gap-2 rounded-lg border-2 border-dashed px-6 py-10 text-sm transition-colors ${dragging ? "border-teal bg-teal-soft" : "border-line hover:border-teal/50"}`}
          >
            <Upload className="size-6 text-teal" />
            {file ? (
              <span className="font-medium">{file.name}</span>
            ) : (
              <>
                <span className="font-medium">Choose an .xlsx file</span>
                <span className="text-muted">or drop it here (up to 5 MB)</span>
              </>
            )}
          </button>
          <input ref={inputRef} type="file" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" className="sr-only" onChange={(e) => pick(e.target.files?.[0])} />
          {error && (
            <p role="alert" className="rounded-md bg-brick-soft px-3 py-2 text-sm text-brick">
              {error}
            </p>
          )}
        </div>
      )}
    </Dialog>
  );
}
