// @File: src/pages/admin/cms/CmsTickets.tsx
// @Desc: Support tickets admin page. Lists chat_conversations (support
//        tickets), supports search, status/priority filter, inline status
//        update and CSV export. Reuses the `chat_conversations` entity.
import { useEffect, useMemo, useState } from "react";
import { TicketCheck, Search, Download, RefreshCw } from "lucide-react";
import { createClient } from "@metagptx/web-sdk";
import CmsLayout from "./CmsLayout";
import { PageHeader } from "./ui";
import LoadingSpinner from "@/components/LoadingSpinner";
import { toast } from "sonner";

const client = createClient();

interface TicketRow {
  id: number;
  subject: string | null;
  visitor_name: string | null;
  visitor_email: string | null;
  department_id: number | null;
  assigned_seat_id: number | null;
  status: string;
  priority: string;
  last_message_at: string | null;
  sla_due_at: string | null;
  linked_ticket_id: number | null;
  ai_summary: string | null;
  created_at: string | null;
}

const STATUS_OPTIONS = ["open", "pending", "in_progress", "resolved", "closed"];
const PRIORITY_OPTIONS = ["low", "normal", "high", "urgent"];

const STATUS_COLORS: Record<string, string> = {
  open: "bg-blue-100 text-blue-700",
  pending: "bg-amber-100 text-amber-700",
  in_progress: "bg-indigo-100 text-indigo-700",
  resolved: "bg-emerald-100 text-emerald-700",
  closed: "bg-slate-200 text-slate-700",
};

const PRIORITY_COLORS: Record<string, string> = {
  low: "bg-slate-100 text-slate-700",
  normal: "bg-slate-100 text-slate-700",
  high: "bg-orange-100 text-orange-700",
  urgent: "bg-rose-100 text-rose-700",
};

function toCsv(rows: TicketRow[]): string {
  const header = [
    "id",
    "subject",
    "visitor_name",
    "visitor_email",
    "status",
    "priority",
    "last_message_at",
    "sla_due_at",
    "created_at",
  ];
  const lines = [header.join(",")];
  for (const t of rows) {
    lines.push(
      [
        t.id,
        JSON.stringify(t.subject ?? ""),
        JSON.stringify(t.visitor_name ?? ""),
        JSON.stringify(t.visitor_email ?? ""),
        t.status,
        t.priority,
        t.last_message_at ?? "",
        t.sla_due_at ?? "",
        t.created_at ?? "",
      ].join(",")
    );
  }
  return lines.join("\n");
}

export default function CmsTickets() {
  const [tickets, setTickets] = useState<TicketRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [priorityFilter, setPriorityFilter] = useState<string>("all");
  const [savingId, setSavingId] = useState<number | null>(null);

  const load = async () => {
    setLoading(true);
    try {
      const res = await client.entities.chat_conversations.queryAll({
        query: {},
        sort: "-id",
        limit: 1000,
      });
      setTickets(((res?.data?.items || []) as TicketRow[]) || []);
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Failed to load tickets.";
      toast.error(msg);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
  }, []);

  const kpis = useMemo(() => {
    const open = tickets.filter((t) => t.status === "open").length;
    const inProgress = tickets.filter((t) => t.status === "in_progress").length;
    const pending = tickets.filter((t) => t.status === "pending").length;
    const resolved = tickets.filter(
      (t) => t.status === "resolved" || t.status === "closed"
    ).length;
    const urgent = tickets.filter((t) => t.priority === "urgent").length;
    return { open, inProgress, pending, resolved, urgent, total: tickets.length };
  }, [tickets]);

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return tickets.filter((t) => {
      if (statusFilter !== "all" && t.status !== statusFilter) return false;
      if (priorityFilter !== "all" && t.priority !== priorityFilter) return false;
      if (!q) return true;
      return (
        (t.subject || "").toLowerCase().includes(q) ||
        (t.visitor_email || "").toLowerCase().includes(q) ||
        (t.visitor_name || "").toLowerCase().includes(q) ||
        String(t.id).includes(q)
      );
    });
  }, [tickets, search, statusFilter, priorityFilter]);

  const updateTicket = async (t: TicketRow, patch: Partial<TicketRow>) => {
    setSavingId(t.id);
    try {
      await client.entities.chat_conversations.update({
        id: String(t.id),
        data: patch,
      });
      toast.success("Ticket updated.");
      setTickets((list) => list.map((x) => (x.id === t.id ? { ...x, ...patch } : x)));
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Update failed.";
      toast.error(msg);
    } finally {
      setSavingId(null);
    }
  };

  const exportCsv = () => {
    const csv = toCsv(filtered);
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `tickets-${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <CmsLayout>
      <PageHeader
        icon={<TicketCheck className="w-6 h-6" />}
        title="Support Tickets"
        description="All support conversations with status, priority and SLA. Update status inline or export to CSV."
      />

      {/* KPIs */}
      <div className="grid grid-cols-2 md:grid-cols-6 gap-3 mb-5">
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            Total
          </div>
          <div className="text-xl font-extrabold text-slate-900 mt-1">{kpis.total}</div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            Open
          </div>
          <div className="text-xl font-extrabold text-blue-600 mt-1">{kpis.open}</div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            In progress
          </div>
          <div className="text-xl font-extrabold text-indigo-600 mt-1">
            {kpis.inProgress}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            Pending
          </div>
          <div className="text-xl font-extrabold text-amber-600 mt-1">{kpis.pending}</div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            Resolved
          </div>
          <div className="text-xl font-extrabold text-emerald-600 mt-1">
            {kpis.resolved}
          </div>
        </div>
        <div className="bg-white border border-slate-200 rounded-2xl p-3">
          <div className="text-slate-500 text-[11px] uppercase font-bold tracking-wider">
            Urgent
          </div>
          <div className="text-xl font-extrabold text-rose-600 mt-1">{kpis.urgent}</div>
        </div>
      </div>

      {/* Controls */}
      <div className="mb-4 flex flex-col md:flex-row gap-3 md:items-center">
        <div className="relative max-w-md flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
          <input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search subject, email or ID…"
            className="w-full pl-9 pr-3 py-2 text-sm border border-slate-200 rounded-lg bg-white"
          />
        </div>
        <select
          value={statusFilter}
          onChange={(e) => setStatusFilter(e.target.value)}
          className="text-sm border border-slate-200 rounded-lg px-3 py-2 bg-white font-semibold"
        >
          <option value="all">All statuses</option>
          {STATUS_OPTIONS.map((s) => (
            <option key={s} value={s}>
              {s}
            </option>
          ))}
        </select>
        <select
          value={priorityFilter}
          onChange={(e) => setPriorityFilter(e.target.value)}
          className="text-sm border border-slate-200 rounded-lg px-3 py-2 bg-white font-semibold"
        >
          <option value="all">All priorities</option>
          {PRIORITY_OPTIONS.map((p) => (
            <option key={p} value={p}>
              {p}
            </option>
          ))}
        </select>
        <button
          onClick={load}
          className="inline-flex items-center gap-2 text-sm font-semibold px-3 py-2 rounded-lg border border-slate-200 bg-white hover:bg-slate-50"
        >
          <RefreshCw className="w-4 h-4" /> Refresh
        </button>
        <button
          onClick={exportCsv}
          className="inline-flex items-center gap-2 text-sm font-semibold px-3 py-2 rounded-lg border border-slate-200 bg-white hover:bg-slate-50"
        >
          <Download className="w-4 h-4" /> Export CSV
        </button>
      </div>

      {loading ? (
        <div className="py-16 flex justify-center">
          <LoadingSpinner />
        </div>
      ) : filtered.length === 0 ? (
        <div className="bg-white border border-slate-200 rounded-2xl p-10 text-center text-slate-500">
          No tickets match your filters.
        </div>
      ) : (
        <div className="bg-white border border-slate-200 rounded-2xl overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-slate-50 text-slate-600 text-xs uppercase tracking-wider">
                <tr>
                  <th className="text-left px-4 py-3">#</th>
                  <th className="text-left px-4 py-3">Subject</th>
                  <th className="text-left px-4 py-3">Customer</th>
                  <th className="text-left px-4 py-3">Priority</th>
                  <th className="text-left px-4 py-3">Status</th>
                  <th className="text-left px-4 py-3">Last msg</th>
                  <th className="text-left px-4 py-3">SLA</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {filtered.map((t) => (
                  <tr key={t.id} className="hover:bg-slate-50 align-top">
                    <td className="px-4 py-3 font-mono text-xs font-semibold text-slate-500">
                      #{t.id}
                    </td>
                    <td className="px-4 py-3">
                      <div className="font-semibold text-slate-900 max-w-sm truncate">
                        {t.subject || "(No subject)"}
                      </div>
                      {t.ai_summary && (
                        <div className="text-xs text-slate-500 max-w-sm truncate">
                          {t.ai_summary}
                        </div>
                      )}
                    </td>
                    <td className="px-4 py-3 text-slate-700">
                      <div className="font-medium">{t.visitor_name || "Visitor"}</div>
                      <div className="text-xs text-slate-500">
                        {t.visitor_email || "—"}
                      </div>
                    </td>
                    <td className="px-4 py-3">
                      <select
                        value={t.priority}
                        disabled={savingId === t.id}
                        onChange={(e) => updateTicket(t, { priority: e.target.value })}
                        className={`text-[10px] uppercase font-bold px-2 py-1 rounded-full border-0 ${
                          PRIORITY_COLORS[t.priority] || "bg-slate-100 text-slate-700"
                        }`}
                      >
                        {PRIORITY_OPTIONS.map((p) => (
                          <option key={p} value={p}>
                            {p}
                          </option>
                        ))}
                      </select>
                    </td>
                    <td className="px-4 py-3">
                      <select
                        value={t.status}
                        disabled={savingId === t.id}
                        onChange={(e) => updateTicket(t, { status: e.target.value })}
                        className={`text-[10px] uppercase font-bold px-2 py-1 rounded-full border-0 ${
                          STATUS_COLORS[t.status] || "bg-slate-100 text-slate-700"
                        }`}
                      >
                        {STATUS_OPTIONS.map((s) => (
                          <option key={s} value={s}>
                            {s}
                          </option>
                        ))}
                      </select>
                    </td>
                    <td className="px-4 py-3 text-slate-600 text-xs">
                      {t.last_message_at ? t.last_message_at.slice(0, 16).replace("T", " ") : "—"}
                    </td>
                    <td className="px-4 py-3 text-slate-600 text-xs">
                      {t.sla_due_at ? t.sla_due_at.slice(0, 16).replace("T", " ") : "—"}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </CmsLayout>
  );
}