"use client";

import { useEffect, useMemo, useState } from "react";
import {
  useTickets,
  useAvailability,
  useSdk,
  useFeatureFlags,
  type Ticket,
  type TicketState,
  type TicketPriority,
} from "@lynkd/messaging-inbox-sdk";
import { useUi } from "@/lib/ui-state";
import { Header } from "@/components/nav/Header";
import { Avatar, Chip } from "@/components/ui/primitives";
import { RichText } from "@/lib/rich-text";
import { clockTime, relativeTime } from "@/lib/format";
import clsx from "clsx";
import {
  LifeBuoy, AlertTriangle, Circle, Send, ArrowUpCircle, CheckCircle2,
  PhoneCall, Tag, Clock, Search, ChevronLeft,
} from "lucide-react";

const stateTone: Record<TicketState, Parameters<typeof Chip>[0]["tone"]> = {
  NEW: "info", OPEN: "accent", PENDING: "warning", RESOLVED: "success", CLOSED: "neutral",
};
const priTone: Record<TicketPriority, Parameters<typeof Chip>[0]["tone"]> = {
  LOW: "neutral", NORMAL: "info", HIGH: "warning", URGENT: "danger",
};

export function SupportView({ initialTicketId }: { initialTicketId?: string }) {
  const { tickets, loading, patch, reply } = useTickets("all");
  const { toast, openModal } = useUi();
  const [selected, setSelected] = useState<string | null>(initialTicketId ?? null);
  const [scope, setScope] = useState<TicketState | "ALL">("ALL");
  const [q, setQ] = useState("");

  useEffect(() => {
    if (initialTicketId) setSelected(initialTicketId);
  }, [initialTicketId]);
  // Desktop shows both panes, so default-select the first ticket. On mobile,
  // don't auto-reselect — that would defeat the "Back to list" button.
  useEffect(() => {
    if (!selected && tickets.length && typeof window !== "undefined" && window.matchMedia("(min-width: 768px)").matches) {
      setSelected(tickets[0].id);
    }
  }, [tickets, selected]);

  const filtered = useMemo(
    () => tickets.filter((t) =>
      (scope === "ALL" || t.state === scope) &&
      (!q || t.subject.toLowerCase().includes(q.toLowerCase()) || t.ref.toLowerCase().includes(q.toLowerCase()))),
    [tickets, scope, q],
  );

  const selectedTicket = tickets.find((t) => t.id === selected) ?? null;
  const open = tickets.filter((t) => t.state === "OPEN" || t.state === "NEW").length;
  const breached = tickets.filter((t) => t.slaBreached).length;
  const resolved7d = tickets.filter((t) => (t.state === "RESOLVED" || t.state === "CLOSED")).length;

  return (
    <div className="flex min-w-0 flex-1 flex-col">
      <Header eyebrow="Workspace" title="Support Center" subtitle="Tickets, escalations, callbacks and agent availability">
        <AvailabilityPill />
      </Header>

      <div className="grid grid-cols-2 gap-3 border-b border-border p-4 sm:grid-cols-4">
        <Stat label="Open tickets" value={open} icon={LifeBuoy} tone="accent" />
        <Stat label="SLA breached" value={breached} icon={AlertTriangle} tone="danger" />
        <Stat label="Resolved / closed" value={resolved7d} icon={CheckCircle2} tone="success" />
        <Stat label="Avg. first response" value="18m" icon={Clock} tone="info" />
      </div>

      <div className="flex min-h-0 flex-1">
        {/* list */}
        <div className={clsx("w-full shrink-0 flex-col border-r border-border md:flex md:w-[340px] lg:w-[380px]", selected ? "hidden md:flex" : "flex")}>
          <div className="flex items-center gap-2 border-b border-border px-3 py-2">
            <div className="flex flex-1 items-center gap-2 rounded-control border border-border bg-panel px-2.5 py-1.5">
              <Search size={14} className="text-muted" />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search tickets" className="w-full bg-transparent text-[13px] outline-none placeholder:text-dim" />
            </div>
          </div>
          <div className="flex gap-1 overflow-x-auto no-scrollbar border-b border-border px-3 py-2">
            {(["ALL", "NEW", "OPEN", "PENDING", "RESOLVED", "CLOSED"] as const).map((s) => (
              <button key={s} onClick={() => setScope(s)} className={clsx("whitespace-nowrap rounded-pill border px-2.5 py-1 text-[11.5px] font-semibold capitalize", scope === s ? "border-accent text-accent" : "border-border text-muted hover:text-ink")}>
                {s.toLowerCase()}
              </button>
            ))}
          </div>
          <div className="min-h-0 flex-1 overflow-y-auto">
            {loading && <div className="p-6 text-center text-muted">Loading…</div>}
            {filtered.map((t) => <TicketRow key={t.id} ticket={t} active={t.id === selected} onClick={() => setSelected(t.id)} />)}
            {!loading && filtered.length === 0 && <div className="p-6 text-center text-[13px] text-muted">No tickets match.</div>}
          </div>
        </div>

        {/* detail */}
        <div className={clsx("min-w-0 flex-1", selected ? "flex" : "hidden md:flex")}>
          {selectedTicket ? (
            <TicketDetail
              key={selectedTicket.id}
              ticket={selectedTicket}
              onBack={() => setSelected(null)}
              onSetState={(s) => patch(selectedTicket.id, s)}
              onReply={(b) => reply(selectedTicket.id, b)}
              onEscalate={() => { patch(selectedTicket.id, "OPEN"); toast(`${selectedTicket.ref} escalated to Tier 2`, "success"); }}
              onCallback={() => openModal("callback")}
            />
          ) : <EmptyDetail />}
        </div>
      </div>
    </div>
  );
}

function TicketRow({ ticket, active, onClick }: { ticket: Ticket; active: boolean; onClick: () => void }) {
  const { userById } = useSdk();
  const requester = userById(ticket.requesterId);
  return (
    <button onClick={onClick} className={clsx("flex w-full flex-col gap-1.5 border-b border-border px-3.5 py-3 text-left transition-colors", active ? "bg-accent-soft/50" : "hover:bg-hover")}>
      <div className="flex items-center gap-2">
        <span className="font-mono text-[11px] text-dim">{ticket.ref}</span>
        <Chip tone={priTone[ticket.priority]}>{ticket.priority}</Chip>
        {ticket.slaBreached && <Chip tone="danger">SLA</Chip>}
        <span className="ml-auto text-[11px] text-dim">{relativeTime(ticket.updatedTs)}</span>
      </div>
      <div className="truncate text-[14px] font-semibold">{ticket.subject}</div>
      <div className="flex items-center gap-2 text-[12px] text-muted">
        {requester && <Avatar user={requester} size={16} showPresence={false} rounded="5px" />}
        <span className="min-w-0 truncate">{requester?.name}</span>
        <Chip tone={stateTone[ticket.state]}>{ticket.state}</Chip>
      </div>
    </button>
  );
}

function TicketDetail({
  ticket, onBack, onSetState, onReply, onEscalate, onCallback,
}: {
  ticket: Ticket;
  onBack: () => void;
  onSetState: (s: TicketState) => void;
  onReply: (body: string) => void;
  onEscalate: () => void;
  onCallback: () => void;
}) {
  const { userById } = useSdk();
  const flags = useFeatureFlags();
  const [draft, setDraft] = useState("");
  const requester = userById(ticket.requesterId);
  const assignee = ticket.assigneeId ? userById(ticket.assigneeId) : undefined;

  const send = () => { if (draft.trim()) { onReply(draft.trim()); setDraft(""); } };

  return (
    <div className="flex h-full min-w-0 flex-col">
      <div className="shrink-0 border-b border-border p-4">
        <div className="flex items-center gap-2">
          <button onClick={onBack} className="focus-ring -ml-1 mr-1 grid h-7 w-7 place-items-center rounded-control text-muted hover:bg-hover md:hidden" aria-label="Back to list"><ChevronLeft size={18} /></button>
          <span className="font-mono text-[12px] text-dim">{ticket.ref}</span>
          <Chip tone={stateTone[ticket.state]}>{ticket.state}</Chip>
          <Chip tone={priTone[ticket.priority]}>{ticket.priority}</Chip>
          {ticket.slaBreached && <Chip tone="danger"><AlertTriangle size={11} /> SLA breached</Chip>}
        </div>
        <h2 className="mt-2 text-[18px] font-black">{ticket.subject}</h2>
        <div className="mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-[12px] text-muted">
          {requester && <span className="flex items-center gap-1.5"><Avatar user={requester} size={18} showPresence={false} rounded="5px" /> {requester.name}</span>}
          {assignee && <span>· Assigned to <b className="text-ink">{assignee.name}</b></span>}
          {ticket.category && <span className="flex items-center gap-1"><Tag size={12} /> {ticket.category}</span>}
          <span>· opened {relativeTime(ticket.createdTs)}</span>
        </div>
        <div className="mt-3 flex flex-wrap gap-2">
          {flags.supportEscalate && <ActionBtn icon={ArrowUpCircle} label="Escalate" onClick={onEscalate} />}
          <ActionBtn icon={CheckCircle2} label="Resolve" accent onClick={() => onSetState("RESOLVED")} />
          <ActionBtn icon={Circle} label="Pending" onClick={() => onSetState("PENDING")} />
          {flags.supportCallback && <ActionBtn icon={PhoneCall} label="Request callback" onClick={onCallback} />}
        </div>
      </div>

      <div className="min-h-0 flex-1 overflow-y-auto p-4">
        <div className="mx-auto max-w-2xl space-y-4">
          {ticket.messages?.map((m) => {
            const author = userById(m.authorId);
            const mine = m.authorId === "u_me";
            return (
              <div key={m.id} className={clsx("flex gap-3", mine && "flex-row-reverse")}>
                {author && <Avatar user={author} size={32} showPresence={false} />}
                <div className={clsx("max-w-[80%] rounded-card border border-border p-3", mine ? "bg-accent-soft" : "bg-panel")}>
                  <div className="mb-1 flex items-center gap-2 text-[12px]"><b>{author?.name}</b><span className="text-dim">{clockTime(m.ts)}</span></div>
                  <div className="text-[14px] leading-relaxed text-ink/90"><RichText text={m.body} /></div>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {ticket.state !== "CLOSED" && (
        <div className="shrink-0 border-t border-border p-3">
          <div className="flex items-end gap-2 rounded-card border border-border bg-panel p-2 focus-within:border-border-strong">
            <textarea
              value={draft}
              onChange={(e) => setDraft(e.target.value)}
              onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey && !(e.nativeEvent as any).isComposing) { e.preventDefault(); send(); } }}
              rows={2}
              placeholder={`Reply to ${requester?.name ?? "customer"}…`}
              className="max-h-32 flex-1 resize-none bg-transparent px-2 py-1.5 text-[14px] outline-none placeholder:text-dim"
            />
            <button onClick={send} disabled={!draft.trim()} className="focus-ring mb-1 mr-1 flex items-center gap-1.5 rounded-control bg-accent px-3 py-2 text-[13px] font-semibold text-accent-fg disabled:opacity-40">
              <Send size={14} /> Reply
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function AvailabilityPill() {
  const flags = useFeatureFlags();
  const { toast } = useUi();
  const agents = useAvailability();
  const [online, setOnline] = useState(true);
  if (!flags.supportAvailability) return null;
  const onlineCount = agents.filter((a) => a.online).length + (online ? 1 : 0);
  return (
    <button
      onClick={() => { setOnline((o) => { const n = !o; toast(n ? "You're online for support" : "You're offline", n ? "success" : "default"); return n; }); }}
      className="mr-1 flex items-center gap-2 rounded-control border border-border bg-panel px-3 py-1.5 text-[12.5px] font-semibold hover:bg-hover"
      title="Toggle your availability"
    >
      <span className={clsx("h-2.5 w-2.5 rounded-full", online ? "bg-success" : "bg-dim")} />
      {online ? "Online" : "Offline"}
      <span className="text-muted">· {onlineCount} agents</span>
    </button>
  );
}

function Stat({ label, value, icon: Icon, tone }: { label: string; value: React.ReactNode; icon: typeof LifeBuoy; tone: string }) {
  const toneBg: Record<string, string> = { accent: "var(--c-accent-soft)", danger: "rgba(242,85,90,0.12)", success: "rgba(62,207,142,0.12)", info: "rgba(91,157,255,0.12)" };
  const toneFg: Record<string, string> = { accent: "var(--c-accent)", danger: "var(--c-danger)", success: "var(--c-success)", info: "var(--c-info)" };
  return (
    <div className="flex items-center gap-3 rounded-card border border-border bg-panel p-3">
      <span className="grid h-10 w-10 place-items-center rounded-control" style={{ background: toneBg[tone], color: toneFg[tone] }}><Icon size={18} /></span>
      <div><div className="text-[20px] font-black leading-none">{value}</div><div className="mt-1 text-[11.5px] text-muted">{label}</div></div>
    </div>
  );
}

function ActionBtn({ icon: Icon, label, onClick, accent }: { icon: typeof Send; label: string; onClick: () => void; accent?: boolean }) {
  return (
    <button onClick={onClick} className={clsx("focus-ring flex items-center gap-1.5 rounded-control border px-3 py-1.5 text-[12.5px] font-semibold transition-colors", accent ? "border-accent bg-accent text-accent-fg" : "border-border hover:bg-hover")}>
      <Icon size={14} /> {label}
    </button>
  );
}

function EmptyDetail() {
  return (
    <div className="flex h-full w-full items-center justify-center text-muted">
      <div className="text-center"><LifeBuoy size={36} className="mx-auto mb-2 text-dim" /><div className="text-[14px]">Select a ticket to view the conversation</div></div>
    </div>
  );
}
