"use client";

import { useState } from "react";
import { parseCsv } from "@/lib/csv";
import { buttonClass, Card } from "@/components/ui";

type TargetField = "email" | "full_name" | "phone" | "total_orders" | "total_spent_cents";

const TARGET_FIELDS: { key: TargetField; label: string; required?: boolean }[] = [
  { key: "email", label: "Email", required: true },
  { key: "full_name", label: "Full name" },
  { key: "phone", label: "Phone" },
  { key: "total_orders", label: "Total orders" },
  { key: "total_spent_cents", label: "Total spent (KES)" },
];

type Preset = "hustlesasa" | "custom";

// Substrings matched against each CSV header (lowercased) to guess a mapping.
// The HustleSasa preset checks its own likely header names first, then both
// presets fall back to the same generic hints — we don't have a real HustleSasa
// export on hand, so this preset is a best-effort guess, not a verified spec.
// The mapping selects below are always editable, so a wrong guess is a two-click fix.
const HUSTLESASA_HINTS: Record<TargetField, string[]> = {
  email: ["email address", "email"],
  full_name: ["customer name", "full name", "name"],
  phone: ["phone number", "phone", "msisdn"],
  total_orders: ["number of orders", "orders", "tickets bought"],
  total_spent_cents: ["total spent", "amount spent", "total amount", "amount"],
};

const GENERIC_HINTS: Record<TargetField, string[]> = {
  email: ["email"],
  full_name: ["name"],
  phone: ["phone", "msisdn"],
  total_orders: ["orders"],
  total_spent_cents: ["spent", "amount", "total"],
};

function guessMapping(headers: string[], preset: Preset): Record<TargetField, string> {
  const hints = preset === "hustlesasa" ? HUSTLESASA_HINTS : GENERIC_HINTS;
  const lower = headers.map((h) => h.toLowerCase());
  const mapping = {} as Record<TargetField, string>;

  for (const { key } of TARGET_FIELDS) {
    const match = hints[key].find((hint) => lower.some((h) => h.includes(hint)));
    const idx = match ? lower.findIndex((h) => h.includes(match)) : -1;
    mapping[key] = idx >= 0 ? headers[idx] : "";
  }
  return mapping;
}

export default function ImportCustomersForm() {
  const [preset, setPreset] = useState<Preset>("hustlesasa");
  const [headers, setHeaders] = useState<string[]>([]);
  const [dataRows, setDataRows] = useState<string[][]>([]);
  const [mapping, setMapping] = useState<Record<TargetField, string>>({
    email: "",
    full_name: "",
    phone: "",
    total_orders: "",
    total_spent_cents: "",
  });
  const [fileName, setFileName] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [result, setResult] = useState<{ created: number; updated: number; skippedInvalid: number; total: number } | null>(null);

  async function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setError(null);
    setResult(null);
    setFileName(file.name);

    const text = await file.text();
    const rows = parseCsv(text);
    if (rows.length < 1) {
      setError("That file doesn't look like a CSV (no rows found).");
      return;
    }
    const [header, ...rest] = rows;
    setHeaders(header);
    setDataRows(rest);
    setMapping(guessMapping(header, preset));
  }

  function handlePresetChange(next: Preset) {
    setPreset(next);
    if (headers.length) setMapping(guessMapping(headers, next));
  }

  function updateMapping(field: TargetField, header: string) {
    setMapping((m) => ({ ...m, [field]: header }));
  }

  async function handleImport() {
    if (!mapping.email) {
      setError("Map an Email column before importing.");
      return;
    }
    setLoading(true);
    setError(null);

    const emailIdx = headers.indexOf(mapping.email);
    const nameIdx = headers.indexOf(mapping.full_name);
    const phoneIdx = headers.indexOf(mapping.phone);
    const ordersIdx = headers.indexOf(mapping.total_orders);
    const spentIdx = headers.indexOf(mapping.total_spent_cents);

    const rows = dataRows.map((r) => {
      const spent = spentIdx >= 0 ? parseFloat(r[spentIdx]) : NaN;
      const orders = ordersIdx >= 0 ? parseInt(r[ordersIdx], 10) : NaN;
      return {
        email: r[emailIdx] ?? "",
        full_name: nameIdx >= 0 ? r[nameIdx] : undefined,
        phone: phoneIdx >= 0 ? r[phoneIdx] : undefined,
        total_orders: Number.isFinite(orders) ? orders : undefined,
        total_spent_cents: Number.isFinite(spent) ? Math.round(spent * 100) : undefined,
      };
    });

    try {
      const res = await fetch("/api/customers/import", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ rows }),
      });
      if (!res.ok) throw new Error((await res.json().catch(() => null))?.error ?? "Import failed");
      setResult(await res.json());
    } catch (e) {
      setError(e instanceof Error ? e.message : "Import failed");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="space-y-6">
      <Card className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-1 text-be-text">Export preset</label>
          <select
            className="input"
            value={preset}
            onChange={(e) => handlePresetChange(e.target.value as Preset)}
          >
            <option value="hustlesasa">HustleSasa export</option>
            <option value="custom">Custom columns</option>
          </select>
        </div>

        <div>
          <label className="block text-sm font-medium mb-1 text-be-text">CSV file</label>
          <input type="file" accept=".csv,text/csv" onChange={handleFile} className="input" />
          {fileName && (
            <p className="mt-1 text-xs text-be-muted">
              {fileName} — {dataRows.length} row{dataRows.length === 1 ? "" : "s"} detected
            </p>
          )}
        </div>
      </Card>

      {headers.length > 0 && (
        <Card className="space-y-4">
          <p className="text-sm font-medium text-be-text">Map columns</p>
          <div className="grid gap-3 sm:grid-cols-2">
            {TARGET_FIELDS.map(({ key, label, required }) => (
              <div key={key}>
                <label className="block text-sm mb-1 text-be-muted">
                  {label}
                  {required && " *"}
                </label>
                <select
                  className="input"
                  value={mapping[key]}
                  onChange={(e) => updateMapping(key, e.target.value)}
                >
                  <option value="">— Don&apos;t import —</option>
                  {headers.map((h) => (
                    <option key={h} value={h}>
                      {h}
                    </option>
                  ))}
                </select>
              </div>
            ))}
          </div>

          {dataRows.length > 0 && (
            <div className="overflow-x-auto rounded-lg border border-be-border">
              <table className="be-table text-xs">
                <thead>
                  <tr>
                    {TARGET_FIELDS.map(({ key, label }) => (
                      <th key={key}>{label}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {dataRows.slice(0, 5).map((r, i) => (
                    <tr key={i}>
                      {TARGET_FIELDS.map(({ key }) => {
                        const idx = headers.indexOf(mapping[key]);
                        return <td key={key}>{idx >= 0 ? r[idx] : "—"}</td>;
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}

          {error && <p className="text-sm text-red-600">{error}</p>}

          <button
            type="button"
            disabled={loading}
            onClick={handleImport}
            className={buttonClass("primary")}
          >
            {loading ? "Importing…" : `Import ${dataRows.length} customer${dataRows.length === 1 ? "" : "s"}`}
          </button>
        </Card>
      )}

      {result && (
        <Card className="space-y-1 text-sm">
          <p className="font-medium text-be-text">Import complete</p>
          <p className="text-be-muted">
            {result.created} created, {result.updated} updated (deduped by email),{" "}
            {result.skippedInvalid} skipped (invalid/missing email) — {result.total} rows total.
          </p>
        </Card>
      )}
    </div>
  );
}
