"use client";

import Link from "next/link";
import { useEffect, useMemo, useRef, useState } from "react";
import { Spinner } from "@/components/common/Spinner";

type LeadStage = "NEW" | "HOT" | "WARM" | "CLOSED" | "LOST";
type LossReason = "PRICE" | "COMPETITION" | "TIMING" | "UNRESPONSIVE" | "NOT_FIT" | "OTHER";

type Conversation = {
  id: string;
  leadStage: LeadStage;
  leadValue: number | null;
  leadNote: string | null;
  lossReason: string | null;
  lossNote: string | null;
  aiScore: number | null;
  aiScoreReason: string | null;
  contextTitle: string | null;
  contextPath: string | null;
  contextImageUrl: string | null;
  otherParty: {
    type: "VISITOR" | "COMPANY";
    id: string;
    visitorName: string | null;
    visitorEmail: string | null;
  };
  lastMessagePreview: string | null;
  lastMessageAt: string | null;
  unreadByB: number;
  createdAt: string;
};

type Stats = {
  totalConversations: number;
  byStage: Record<LeadStage, number>;
  pipelineValue: number;
  wonValueThisMonth: number;
  averageDealSize: number;
  conversionRate: number;
};

const STAGE_META: Record<LeadStage, { label: string; tone: string; emoji: string }> = {
  NEW: { label: "Nov", tone: "zinc", emoji: "•" },
  HOT: { label: "Hot", tone: "rose", emoji: "🔥" },
  WARM: { label: "Warm", tone: "amber", emoji: "♨️" },
  CLOSED: { label: "Zatvoren", tone: "emerald", emoji: "✓" },
  LOST: { label: "Izgubljen", tone: "zinc", emoji: "✕" },
};

const LOSS_LABELS: Record<LossReason, string> = {
  PRICE: "Cena previsoka",
  COMPETITION: "Otišao konkurenciji",
  TIMING: "Nije pravi trenutak",
  UNRESPONSIVE: "Prestao da odgovara",
  NOT_FIT: "Nije odgovaralo",
  OTHER: "Drugo",
};

function fmtRsd(v: number | null) {
  if (v === null || v === undefined) return "—";
  return `${new Intl.NumberFormat("sr-RS").format(v)} RSD`;
}

function fmtDate(iso: string | null) {
  if (!iso) return "—";
  return new Date(iso).toLocaleDateString("sr-RS", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
  });
}

function timeAgo(iso: string | null) {
  if (!iso) return "—";
  const diff = Date.now() - new Date(iso).getTime();
  const m = Math.floor(diff / 60000);
  if (m < 1) return "upravo";
  if (m < 60) return `pre ${m} min`;
  const h = Math.floor(m / 60);
  if (h < 24) return `pre ${h}h`;
  const d = Math.floor(h / 24);
  if (d < 7) return `pre ${d} dana`;
  return fmtDate(iso);
}

function stageToneClass(stage: LeadStage, active: boolean): string {
  if (!active) return "border-zinc-700 bg-zinc-900 text-zinc-300 hover:border-zinc-500";
  switch (STAGE_META[stage].tone) {
    case "rose":
      return "border-rose-500 bg-rose-500 text-white";
    case "amber":
      return "border-amber-500 bg-amber-500 text-zinc-950";
    case "emerald":
      return "border-emerald-500 bg-emerald-500 text-zinc-950";
    default:
      return "border-zinc-600 bg-zinc-700 text-white";
  }
}

export function SalesCrmDashboard({
  initialData,
}: {
  initialData: { items: Conversation[]; total: number; stats: Stats };
}) {
  const [items, setItems] = useState<Conversation[]>(initialData.items);
  const [total, setTotal] = useState(initialData.total);
  const [stats, setStats] = useState<Stats>(initialData.stats);

  // Filteri
  const [activeStages, setActiveStages] = useState<Set<LeadStage>>(new Set());
  const [minValue, setMinValue] = useState<string>("");
  const [maxValue, setMaxValue] = useState<string>("");
  const [search, setSearch] = useState("");
  const [sort, setSort] = useState<"value_desc" | "value_asc" | "recent" | "oldest">("recent");
  const [loading, setLoading] = useState(false);
  const [view, setView] = useState<"table" | "kanban">("table");

  // Selekcija
  const [selected, setSelected] = useState<Set<string>>(new Set());

  // Modali
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editValue, setEditValue] = useState<string>("");
  const [editNote, setEditNote] = useState<string>("");
  const [lossModalId, setLossModalId] = useState<string | null>(null);
  const [lossReason, setLossReason] = useState<LossReason>("PRICE");
  const [lossNote, setLossNote] = useState<string>("");
  const [savingEdit, setSavingEdit] = useState(false);
  const [savingLoss, setSavingLoss] = useState(false);

  // Loss analitika
  const [lossAnalytics, setLossAnalytics] = useState<{
    byReason: Record<string, { count: number; totalValue: number; label: string }>;
    totalLost: number;
    totalLostValue: number;
  } | null>(null);
  const [showLossAnalytics, setShowLossAnalytics] = useState(false);

  // Drag & drop
  const [draggedId, setDraggedId] = useState<string | null>(null);

  const refetchTimeoutRef = useRef<number | null>(null);

  async function refetch() {
    setLoading(true);
    try {
      const params = new URLSearchParams();
      if (activeStages.size > 0) params.set("stages", Array.from(activeStages).join(","));
      if (minValue) params.set("minValue", minValue);
      if (maxValue) params.set("maxValue", maxValue);
      if (search.trim()) params.set("q", search.trim());
      params.set("sort", sort);
      params.set("pageSize", view === "kanban" ? "200" : "50");

      const res = await fetch(`/api/portal/sales-crm/conversations?${params.toString()}`);
      if (!res.ok) return;
      const data = await res.json();
      setItems(data.items);
      setTotal(data.total);
      setStats(data.stats);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    if (refetchTimeoutRef.current) window.clearTimeout(refetchTimeoutRef.current);
    refetchTimeoutRef.current = window.setTimeout(() => {
      void refetch();
    }, 200);
    return () => {
      if (refetchTimeoutRef.current) window.clearTimeout(refetchTimeoutRef.current);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeStages, minValue, maxValue, search, sort, view]);

  function toggleStage(stage: LeadStage) {
    const next = new Set(activeStages);
    if (next.has(stage)) next.delete(stage);
    else next.add(stage);
    setActiveStages(next);
  }

  function toggleSelect(id: string) {
    const next = new Set(selected);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setSelected(next);
  }

  function selectAll() {
    if (selected.size === items.length) setSelected(new Set());
    else setSelected(new Set(items.map((i) => i.id)));
  }

  async function changeStage(id: string, stage: LeadStage) {
    const conv = items.find((c) => c.id === id);
    if (stage === "LOST" && conv && conv.leadStage !== "LOST") {
      setLossModalId(id);
      setLossReason("PRICE");
      setLossNote("");
      return;
    }
    await persistStage(id, stage);
  }

  async function persistStage(
    id: string,
    stage: LeadStage,
    extra?: { lossReason?: LossReason; lossNote?: string },
  ) {
    setItems((prev) =>
      prev.map((c) =>
        c.id === id
          ? {
              ...c,
              leadStage: stage,
              ...(extra?.lossReason !== undefined ? { lossReason: extra.lossReason } : {}),
              ...(extra?.lossNote !== undefined ? { lossNote: extra.lossNote } : {}),
            }
          : c,
      ),
    );
    try {
      const res = await fetch(`/api/messages/conversations/${id}/lead`, {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ stage, ...(extra ?? {}) }),
      });
      if (!res.ok) throw new Error("update failed");
      await refetch();
    } catch {
      await refetch();
    }
  }

  async function confirmLoss() {
    if (!lossModalId) return;
    setSavingLoss(true);
    try {
      await persistStage(lossModalId, "LOST", {
        lossReason,
        lossNote: lossNote.trim() || undefined,
      });
      setLossModalId(null);
      setLossAnalytics(null); // invalidate cache
    } finally {
      setSavingLoss(false);
    }
  }

  async function bulkSetStage(stage: LeadStage) {
    if (selected.size === 0) return;
    if (!window.confirm(`Označi ${selected.size} razgovora kao ${STAGE_META[stage].label}?`)) return;
    const res = await fetch("/api/portal/sales-crm/bulk", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ conversationIds: Array.from(selected), stage }),
    });
    if (res.ok) {
      setSelected(new Set());
      await refetch();
    }
  }

  function openEdit(c: Conversation) {
    setEditingId(c.id);
    setEditValue(c.leadValue !== null ? String(c.leadValue) : "");
    setEditNote(c.leadNote ?? "");
  }

  async function saveEdit() {
    if (!editingId) return;
    const numValue = editValue.trim() === "" ? null : Number(editValue);
    if (numValue !== null && (Number.isNaN(numValue) || numValue < 0)) {
      alert("Iznos mora biti broj ≥ 0.");
      return;
    }
    setSavingEdit(true);
    try {
      const res = await fetch(`/api/messages/conversations/${editingId}/lead`, {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ leadValue: numValue, leadNote: editNote || null }),
      });
      if (res.ok) {
        setEditingId(null);
        await refetch();
      }
    } finally {
      setSavingEdit(false);
    }
  }

  async function loadLossAnalytics() {
    setShowLossAnalytics(true);
    if (lossAnalytics) return;
    try {
      const res = await fetch("/api/portal/sales-crm/loss-analytics");
      if (!res.ok) return;
      const data = await res.json();
      setLossAnalytics(data);
    } catch {
      /* noop */
    }
  }

  const csvHref = useMemo(() => {
    const params = new URLSearchParams();
    if (activeStages.size > 0) params.set("stages", Array.from(activeStages).join(","));
    if (minValue) params.set("minValue", minValue);
    if (maxValue) params.set("maxValue", maxValue);
    if (search.trim()) params.set("q", search.trim());
    return `/api/portal/sales-crm/export?${params.toString()}`;
  }, [activeStages, minValue, maxValue, search]);

  const funnel = useMemo(() => {
    const max = Math.max(
      stats.byStage.NEW,
      stats.byStage.HOT,
      stats.byStage.WARM,
      stats.byStage.CLOSED,
      stats.byStage.LOST,
      1,
    );
    return (["NEW", "HOT", "WARM", "CLOSED", "LOST"] as LeadStage[]).map((s) => ({
      stage: s,
      count: stats.byStage[s],
      pct: (stats.byStage[s] / max) * 100,
    }));
  }, [stats]);

  const kanbanColumns = useMemo(() => {
    const cols: Record<LeadStage, Conversation[]> = {
      NEW: [],
      HOT: [],
      WARM: [],
      CLOSED: [],
      LOST: [],
    };
    for (const c of items) cols[c.leadStage].push(c);
    return cols;
  }, [items]);

  function onDragStart(id: string) {
    return (e: React.DragEvent) => {
      setDraggedId(id);
      e.dataTransfer.effectAllowed = "move";
    };
  }
  function onDragOver(e: React.DragEvent) {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
  }
  async function onDrop(stage: LeadStage) {
    if (!draggedId) return;
    const dragged = items.find((c) => c.id === draggedId);
    setDraggedId(null);
    if (!dragged || dragged.leadStage === stage) return;
    await changeStage(dragged.id, stage);
  }

  return (
    <div className="space-y-6">
      {/* ─── Stats ─────────────────────────────────────────── */}
      <section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
        <div className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-4">
          <p className="text-xs uppercase tracking-wide text-zinc-500">Ukupno razgovora</p>
          <p className="mt-1 text-2xl font-semibold text-white">{stats.totalConversations}</p>
          <p className="mt-1 text-[0.7rem] text-zinc-500">
            🔥 {stats.byStage.HOT} hot · ♨️ {stats.byStage.WARM} warm
          </p>
        </div>
        <div className="rounded-2xl border border-orange-500/30 bg-orange-500/5 p-4">
          <p className="text-xs uppercase tracking-wide text-orange-300">Pipeline (HOT + WARM)</p>
          <p className="mt-1 text-2xl font-semibold text-white">{fmtRsd(stats.pipelineValue)}</p>
          <p className="mt-1 text-[0.7rem] text-orange-300/70">
            Aktivni lead-ovi sa procenjenom vrednošću
          </p>
        </div>
        <div className="rounded-2xl border border-emerald-500/30 bg-emerald-500/5 p-4">
          <p className="text-xs uppercase tracking-wide text-emerald-300">Zatvoreno ovog meseca</p>
          <p className="mt-1 text-2xl font-semibold text-white">{fmtRsd(stats.wonValueThisMonth)}</p>
          <p className="mt-1 text-[0.7rem] text-emerald-300/70">
            ✓ {stats.byStage.CLOSED} zatvorenih ukupno
          </p>
        </div>
        <button
          type="button"
          onClick={loadLossAnalytics}
          className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-4 text-left transition hover:border-rose-500/40"
        >
          <p className="text-xs uppercase tracking-wide text-zinc-500">Stopa konverzije</p>
          <p className="mt-1 text-2xl font-semibold text-white">
            {Math.round(stats.conversionRate * 100)}%
          </p>
          <p className="mt-1 text-[0.7rem] text-zinc-500">
            Prosečan deal: {fmtRsd(stats.averageDealSize)} · Klik za analitiku gubitaka →
          </p>
        </button>
      </section>

      {/* ─── Funnel ────────────────────────────────────────── */}
      <section className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-5">
        <h3 className="text-sm font-bold uppercase tracking-wide text-zinc-400">Funnel</h3>
        <div className="mt-4 space-y-2">
          {funnel.map((f) => {
            const meta = STAGE_META[f.stage];
            const barColor =
              meta.tone === "rose"
                ? "bg-rose-500"
                : meta.tone === "amber"
                  ? "bg-amber-500"
                  : meta.tone === "emerald"
                    ? "bg-emerald-500"
                    : "bg-zinc-600";
            return (
              <div key={f.stage} className="flex items-center gap-3">
                <span className="w-24 text-xs font-semibold text-zinc-300">
                  {meta.emoji} {meta.label}
                </span>
                <div className="relative flex-1 h-8 rounded-lg bg-zinc-900 overflow-hidden">
                  <div
                    className={`h-full ${barColor} transition-all duration-500`}
                    style={{ width: `${f.pct}%` }}
                  />
                  <span className="absolute inset-0 flex items-center px-3 text-xs font-bold text-white mix-blend-difference">
                    {f.count}
                  </span>
                </div>
              </div>
            );
          })}
        </div>
      </section>

      {/* ─── Filteri + view toggle + CSV ───────────────────── */}
      <section className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-5">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <div className="flex flex-wrap items-center gap-2">
            <span className="text-xs font-bold uppercase tracking-wide text-zinc-500">Stage:</span>
            {(["HOT", "WARM", "NEW", "CLOSED", "LOST"] as LeadStage[]).map((s) => {
              const active = activeStages.has(s);
              return (
                <button
                  key={s}
                  type="button"
                  onClick={() => toggleStage(s)}
                  className={`inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-bold transition ${stageToneClass(s, active)}`}
                >
                  {STAGE_META[s].emoji} {STAGE_META[s].label}{" "}
                  <span className="opacity-70">({stats.byStage[s]})</span>
                </button>
              );
            })}
            {activeStages.size > 0 && (
              <button
                type="button"
                onClick={() => setActiveStages(new Set())}
                className="text-xs font-bold text-zinc-400 hover:text-white"
              >
                Resetuj
              </button>
            )}
          </div>

          <div className="flex items-center gap-2">
            <div className="inline-flex rounded-lg border border-zinc-700 bg-zinc-900 p-0.5">
              <button
                type="button"
                onClick={() => setView("table")}
                className={`rounded px-3 py-1.5 text-xs font-bold transition ${view === "table" ? "bg-orange-500 text-zinc-950" : "text-zinc-400 hover:text-white"}`}
              >
                📋 Tabela
              </button>
              <button
                type="button"
                onClick={() => setView("kanban")}
                className={`rounded px-3 py-1.5 text-xs font-bold transition ${view === "kanban" ? "bg-orange-500 text-zinc-950" : "text-zinc-400 hover:text-white"}`}
              >
                🗂 Kanban
              </button>
            </div>
            <a
              href={csvHref}
              className="inline-flex items-center gap-1.5 rounded-lg border border-zinc-700 bg-zinc-900 px-3 py-1.5 text-xs font-bold text-zinc-300 transition hover:border-orange-400 hover:text-orange-400"
            >
              📥 Izvezi CSV
            </a>
          </div>
        </div>

        <div className="mt-4 grid gap-3 lg:grid-cols-[1fr_140px_140px_180px]">
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Pretraga (naslov razgovora, poruka, beleška)..."
            className="h-11 rounded-xl border border-zinc-700 bg-zinc-900 px-4 text-sm text-white placeholder:text-zinc-500"
          />
          <input
            type="number"
            min="0"
            value={minValue}
            onChange={(e) => setMinValue(e.target.value)}
            placeholder="Min RSD"
            className="h-11 rounded-xl border border-zinc-700 bg-zinc-900 px-4 text-sm text-white placeholder:text-zinc-500"
          />
          <input
            type="number"
            min="0"
            value={maxValue}
            onChange={(e) => setMaxValue(e.target.value)}
            placeholder="Max RSD"
            className="h-11 rounded-xl border border-zinc-700 bg-zinc-900 px-4 text-sm text-white placeholder:text-zinc-500"
          />
          <select
            value={sort}
            onChange={(e) => setSort(e.target.value as never)}
            className="h-11 rounded-xl border border-zinc-700 bg-zinc-900 px-4 text-sm text-white"
            disabled={view === "kanban"}
          >
            <option value="recent">Najnoviji</option>
            <option value="oldest">Najstariji</option>
            <option value="value_desc">Vrednost ↓</option>
            <option value="value_asc">Vrednost ↑</option>
          </select>
        </div>
      </section>

      {/* ─── Bulk actions bar ──────────────────────────────── */}
      {view === "table" && selected.size > 0 && (
        <section className="rounded-2xl border border-orange-500/40 bg-orange-500/10 p-4">
          <div className="flex flex-wrap items-center gap-3">
            <p className="font-bold text-white">{selected.size} razgovora selektovano</p>
            <div className="flex flex-wrap gap-2">
              {(["HOT", "WARM", "CLOSED", "LOST"] as LeadStage[]).map((s) => (
                <button
                  key={s}
                  type="button"
                  onClick={() => bulkSetStage(s)}
                  className={`rounded-full px-3 py-1.5 text-xs font-bold transition ${stageToneClass(s, true)}`}
                >
                  Označi kao {STAGE_META[s].emoji} {STAGE_META[s].label}
                </button>
              ))}
              <button
                type="button"
                onClick={() => setSelected(new Set())}
                className="text-xs font-bold text-zinc-400 hover:text-white"
              >
                Odselektuj
              </button>
            </div>
          </div>
        </section>
      )}

      {/* ─── TABELA ────────────────────────────────────────── */}
      {view === "table" && (
        <section className="rounded-2xl border border-zinc-800 bg-zinc-950/60">
          <div className="flex items-center justify-between border-b border-zinc-800 px-4 py-3">
            <p className="text-sm font-bold text-white">
              {total} {total === 1 ? "razgovor" : "razgovora"}
              {loading && <span className="ml-2 text-xs text-zinc-500">Učitavam...</span>}
            </p>
            <button
              type="button"
              onClick={selectAll}
              className="text-xs font-bold text-zinc-400 hover:text-white"
            >
              {selected.size === items.length && items.length > 0
                ? "Odselektuj sve"
                : "Selektuj sve"}
            </button>
          </div>

          {items.length === 0 ? (
            <p className="p-8 text-center text-sm text-zinc-500">
              {activeStages.size > 0 || minValue || maxValue || search
                ? "Nema rezultata za zadate filtere."
                : "Još uvek nemaš razgovora."}
            </p>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead className="text-[0.65rem] uppercase tracking-wide text-zinc-500">
                  <tr className="border-b border-zinc-800">
                    <th className="px-3 py-2 text-left w-8"></th>
                    <th className="px-3 py-2 text-left">Posetilac / kontekst</th>
                    <th className="px-3 py-2 text-left">AI</th>
                    <th className="px-3 py-2 text-left">Stage</th>
                    <th className="px-3 py-2 text-right">Vrednost</th>
                    <th className="px-3 py-2 text-left">Poslednja aktivnost</th>
                    <th className="px-3 py-2 text-left">Akcija</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-zinc-800">
                  {items.map((c) => {
                    const meta = STAGE_META[c.leadStage];
                    const isSel = selected.has(c.id);
                    return (
                      <tr key={c.id} className={isSel ? "bg-orange-500/5" : ""}>
                        <td className="px-3 py-3">
                          <input
                            type="checkbox"
                            checked={isSel}
                            onChange={() => toggleSelect(c.id)}
                            className="h-4 w-4 accent-orange-500"
                          />
                        </td>
                        <td className="px-3 py-3">
                          <Link href={`/portal/poruke?c=${c.id}`} className="block min-w-0">
                            <p className="truncate text-sm font-semibold text-white hover:text-orange-400">
                              {c.otherParty.visitorName ||
                                c.otherParty.visitorEmail ||
                                "Posetilac"}
                            </p>
                            <p className="mt-0.5 truncate text-xs text-zinc-500">
                              {c.contextTitle || c.lastMessagePreview || "Razgovor"}
                            </p>
                            {c.unreadByB > 0 && (
                              <span className="mt-1 inline-block rounded-full bg-rose-500/15 px-2 py-0.5 text-[0.6rem] font-bold text-rose-300">
                                {c.unreadByB} novih
                              </span>
                            )}
                          </Link>
                        </td>
                        <td className="px-3 py-3">
                          {c.aiScore !== null ? (
                            <span
                              title={c.aiScoreReason ?? "AI score"}
                              className={`inline-flex h-7 w-9 items-center justify-center rounded-md text-xs font-bold ${
                                c.aiScore >= 70
                                  ? "bg-rose-500/20 text-rose-300"
                                  : c.aiScore >= 40
                                    ? "bg-amber-500/20 text-amber-300"
                                    : "bg-zinc-700/40 text-zinc-400"
                              }`}
                            >
                              {c.aiScore}
                            </span>
                          ) : (
                            <span className="text-xs text-zinc-600">—</span>
                          )}
                        </td>
                        <td className="px-3 py-3">
                          <span
                            className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-bold ${stageToneClass(c.leadStage, true)}`}
                          >
                            {meta.emoji} {meta.label}
                          </span>
                          {c.leadStage === "LOST" && c.lossReason && (
                            <p className="mt-0.5 text-[0.65rem] text-zinc-500">
                              {LOSS_LABELS[c.lossReason as LossReason] ?? c.lossReason}
                            </p>
                          )}
                        </td>
                        <td className="px-3 py-3 text-right">
                          <p className="font-semibold text-white">{fmtRsd(c.leadValue)}</p>
                          {c.leadNote && (
                            <p
                              className="mt-0.5 line-clamp-1 max-w-[180px] ml-auto text-[0.7rem] text-zinc-500"
                              title={c.leadNote}
                            >
                              {c.leadNote}
                            </p>
                          )}
                        </td>
                        <td className="px-3 py-3 text-zinc-400">{timeAgo(c.lastMessageAt)}</td>
                        <td className="px-3 py-3">
                          <button
                            type="button"
                            onClick={() => openEdit(c)}
                            className="text-xs font-bold text-orange-400 hover:underline"
                          >
                            Uredi
                          </button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </section>
      )}

      {/* ─── KANBAN ────────────────────────────────────────── */}
      {view === "kanban" && (
        <section>
          <p className="mb-3 text-xs text-zinc-500">
            Prevuci karticu razgovora između kolona da promeniš stage. Lost razgovori traže razlog.
          </p>
          <div className="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-5">
            {(["NEW", "HOT", "WARM", "CLOSED", "LOST"] as LeadStage[]).map((stage) => {
              const meta = STAGE_META[stage];
              const colItems = kanbanColumns[stage];
              const colTotal = colItems.reduce((sum, c) => sum + (c.leadValue ?? 0), 0);

              return (
                <div
                  key={stage}
                  onDragOver={onDragOver}
                  onDrop={() => onDrop(stage)}
                  className={`rounded-2xl border-2 border-dashed p-3 min-h-[400px] transition ${
                    draggedId
                      ? "border-orange-500/40 bg-orange-500/5"
                      : "border-zinc-800 bg-zinc-950/40"
                  }`}
                >
                  <div className="flex items-center justify-between border-b border-zinc-800 pb-2">
                    <p className="text-sm font-bold text-white">
                      {meta.emoji} {meta.label}
                    </p>
                    <span className="rounded-full bg-zinc-800 px-2 py-0.5 text-[0.65rem] font-bold text-zinc-300">
                      {colItems.length}
                    </span>
                  </div>
                  {colTotal > 0 && (
                    <p className="mt-1 text-[0.65rem] uppercase tracking-wide text-zinc-500">
                      ∑ {fmtRsd(colTotal)}
                    </p>
                  )}

                  <div className="mt-3 space-y-2 max-h-[calc(100vh-380px)] overflow-y-auto pr-1">
                    {colItems.length === 0 ? (
                      <p className="py-6 text-center text-xs text-zinc-600">Prazno</p>
                    ) : (
                      colItems.map((c) => (
                        <div
                          key={c.id}
                          draggable
                          onDragStart={onDragStart(c.id)}
                          className="cursor-grab rounded-xl border border-zinc-700 bg-zinc-900 p-3 transition hover:border-orange-500/40 active:cursor-grabbing"
                        >
                          <div className="flex items-start justify-between gap-2">
                            <p className="line-clamp-1 text-xs font-bold text-white">
                              {c.otherParty.visitorName ||
                                c.otherParty.visitorEmail ||
                                "Posetilac"}
                            </p>
                            {c.aiScore !== null && (
                              <span
                                title={c.aiScoreReason ?? "AI score"}
                                className={`shrink-0 rounded px-1.5 py-0.5 text-[0.6rem] font-bold ${
                                  c.aiScore >= 70
                                    ? "bg-rose-500/20 text-rose-300"
                                    : c.aiScore >= 40
                                      ? "bg-amber-500/20 text-amber-300"
                                      : "bg-zinc-700 text-zinc-400"
                                }`}
                              >
                                AI {c.aiScore}
                              </span>
                            )}
                          </div>
                          {c.contextTitle && (
                            <p className="mt-1 line-clamp-2 text-[0.7rem] text-zinc-400">
                              {c.contextTitle}
                            </p>
                          )}
                          <div className="mt-2 flex items-center justify-between text-[0.65rem]">
                            <span className="font-bold text-white">{fmtRsd(c.leadValue)}</span>
                            <span className="text-zinc-500">{timeAgo(c.lastMessageAt)}</span>
                          </div>
                          {c.unreadByB > 0 && (
                            <span className="mt-2 inline-block rounded-full bg-rose-500/15 px-1.5 py-0.5 text-[0.6rem] font-bold text-rose-300">
                              {c.unreadByB} nepročitanih
                            </span>
                          )}
                          <div className="mt-2 flex gap-1">
                            <Link
                              href={`/portal/poruke?c=${c.id}`}
                              className="flex-1 rounded border border-zinc-700 px-2 py-1 text-center text-[0.65rem] font-bold text-zinc-300 hover:bg-zinc-800"
                            >
                              Otvori
                            </Link>
                            <button
                              type="button"
                              onClick={() => openEdit(c)}
                              className="rounded border border-zinc-700 px-2 py-1 text-[0.65rem] font-bold text-zinc-300 hover:bg-zinc-800"
                            >
                              ✏️
                            </button>
                          </div>
                        </div>
                      ))
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </section>
      )}

      {/* ─── Loss analytics modal ──────────────────────────── */}
      {showLossAnalytics && (
        <div
          className="fixed inset-0 z-[200] flex items-center justify-center bg-black/70 p-4"
          onClick={() => setShowLossAnalytics(false)}
        >
          <div
            className="w-full max-w-lg rounded-2xl border border-zinc-800 bg-zinc-950 p-6 shadow-2xl"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex items-start justify-between">
              <div>
                <h3 className="font-display text-lg font-bold text-white">
                  📊 Analitika gubitničkih razloga
                </h3>
                <p className="mt-1 text-sm text-zinc-400">
                  Razumi zašto najčešće gubiš lead-ove i koliko vrednosti pada na svaki razlog.
                </p>
              </div>
              <button
                type="button"
                onClick={() => setShowLossAnalytics(false)}
                className="text-zinc-500 hover:text-white"
              >
                ✕
              </button>
            </div>

            {!lossAnalytics ? (
              <p className="mt-6 text-center text-sm text-zinc-500">Učitavam...</p>
            ) : lossAnalytics.totalLost === 0 ? (
              <p className="mt-6 text-center text-sm text-zinc-500">
                Nemaš još izgubljenih lead-ova sa razlogom. Markiraj neke kao LOST sa razlogom da bi dobio uvid.
              </p>
            ) : (
              <div className="mt-5 space-y-3">
                <div className="rounded-xl border border-rose-500/30 bg-rose-500/5 p-3">
                  <p className="text-xs uppercase tracking-wide text-rose-300">Ukupno izgubljeno</p>
                  <p className="mt-1 text-xl font-bold text-white">
                    {lossAnalytics.totalLost} lead-ova · {fmtRsd(lossAnalytics.totalLostValue)}
                  </p>
                </div>

                <div className="space-y-2">
                  {Object.entries(lossAnalytics.byReason)
                    .sort((a, b) => b[1].count - a[1].count)
                    .map(([key, data]) => {
                      const pct = (data.count / lossAnalytics.totalLost) * 100;
                      return (
                        <div
                          key={key}
                          className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3"
                        >
                          <div className="flex items-center justify-between">
                            <p className="text-sm font-bold text-white">{data.label}</p>
                            <p className="text-xs text-zinc-400">
                              {data.count}× · {fmtRsd(data.totalValue)}
                            </p>
                          </div>
                          <div className="mt-2 h-2 rounded-full bg-zinc-900">
                            <div
                              className="h-full rounded-full bg-rose-500"
                              style={{ width: `${pct}%` }}
                            />
                          </div>
                        </div>
                      );
                    })}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* ─── Loss razlog modal ─────────────────────────────── */}
      {lossModalId && (
        <div
          className="fixed inset-0 z-[200] flex items-center justify-center bg-black/70 p-4"
          onClick={() => setLossModalId(null)}
        >
          <div
            className="w-full max-w-md rounded-2xl border border-zinc-800 bg-zinc-950 p-6 shadow-2xl"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="font-display text-lg font-bold text-white">
              Zašto je ovaj lead izgubljen?
            </h3>
            <p className="mt-1 text-sm text-zinc-400">
              Pomaže ti analitika — vidiš najčešće razloge gubitka i možeš ih sistemski rešiti.
            </p>

            <div className="mt-5 space-y-2">
              {(Object.keys(LOSS_LABELS) as LossReason[]).map((r) => (
                <label
                  key={r}
                  className={`flex cursor-pointer items-center gap-3 rounded-xl border p-3 transition ${
                    lossReason === r
                      ? "border-rose-500 bg-rose-500/10"
                      : "border-zinc-700 bg-zinc-900 hover:border-zinc-600"
                  }`}
                >
                  <input
                    type="radio"
                    name="lossReason"
                    value={r}
                    checked={lossReason === r}
                    onChange={() => setLossReason(r)}
                    className="h-4 w-4 accent-rose-500"
                  />
                  <span className="text-sm font-semibold text-white">{LOSS_LABELS[r]}</span>
                </label>
              ))}
            </div>

            <div className="mt-4">
              <label className="block text-xs font-bold uppercase tracking-wide text-zinc-500">
                Dodatna napomena (opciono)
              </label>
              <textarea
                rows={3}
                value={lossNote}
                onChange={(e) => setLossNote(e.target.value)}
                maxLength={500}
                placeholder='npr. „Tražio je 30% jeftinije, nismo mogli"'
                className="mt-1 w-full rounded-xl border border-zinc-700 bg-zinc-900 px-4 py-2.5 text-sm text-white"
              />
            </div>

            <div className="mt-5 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setLossModalId(null)}
                className="rounded-lg border border-zinc-700 px-4 py-2 text-sm font-bold text-zinc-300 hover:bg-zinc-900"
              >
                Otkaži
              </button>
              <button
                type="button"
                onClick={confirmLoss}
                disabled={savingLoss}
                className="inline-flex items-center justify-center gap-2 rounded-lg bg-rose-500 px-5 py-2 text-sm font-bold text-white hover:bg-rose-400 disabled:opacity-60"
              >
                {savingLoss ? <Spinner className="h-4 w-4" /> : null}
                {savingLoss ? "Čuvam…" : "Markiraj kao izgubljen"}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* ─── Edit value/note modal ─────────────────────────── */}
      {editingId && (
        <div
          className="fixed inset-0 z-[200] flex items-center justify-center bg-black/70 p-4"
          onClick={() => setEditingId(null)}
        >
          <div
            className="w-full max-w-md rounded-2xl border border-zinc-800 bg-zinc-950 p-6 shadow-2xl"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="font-display text-lg font-bold text-white">Uredi vrednost i belešku</h3>
            <div className="mt-4 space-y-3">
              <div>
                <label className="block text-xs font-bold uppercase tracking-wide text-zinc-500">
                  Procenjena vrednost (RSD)
                </label>
                <input
                  type="number"
                  min="0"
                  value={editValue}
                  onChange={(e) => setEditValue(e.target.value)}
                  placeholder="npr. 150000"
                  className="mt-1 w-full rounded-xl border border-zinc-700 bg-zinc-900 px-4 py-2.5 text-sm text-white"
                />
              </div>
              <div>
                <label className="block text-xs font-bold uppercase tracking-wide text-zinc-500">
                  Interna beleška
                </label>
                <textarea
                  rows={4}
                  value={editNote}
                  onChange={(e) => setEditNote(e.target.value)}
                  maxLength={1000}
                  placeholder='Npr. „Spreman da kupi 50 jedinica, čeka samo cenu"'
                  className="mt-1 w-full rounded-xl border border-zinc-700 bg-zinc-900 px-4 py-2.5 text-sm text-white"
                />
              </div>
            </div>
            <div className="mt-5 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setEditingId(null)}
                className="rounded-lg border border-zinc-700 px-4 py-2 text-sm font-bold text-zinc-300 hover:bg-zinc-900"
              >
                Otkaži
              </button>
              <button
                type="button"
                onClick={saveEdit}
                disabled={savingEdit}
                className="inline-flex items-center justify-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-bold text-zinc-950 hover:bg-orange-400 disabled:opacity-60"
              >
                {savingEdit ? <Spinner className="h-4 w-4" /> : null}
                {savingEdit ? "Čuvam…" : "Sačuvaj"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
