"use client";

import clsx from "clsx";
import Link from "next/link";
import { useState } from "react";
import { ArrowLeft } from "lucide-react";
import { Badge, Button, Dialog, Skeleton } from "@/components/ui/kit";
import { useToast } from "@/components/ui/toast";
import { api, qs } from "@/lib/api";
import { formatDateTime, formatPhone } from "@/lib/format";
import { useApi } from "@/lib/use-api";
import type { FlowRun, FlowRunStatus } from "@/lib/types";

export const RUN_STATUS: Record<FlowRunStatus, { label: string; tone: "teal" | "amber" | "brick" | "neutral" }> = {
  running: { label: "Running", tone: "teal" },
  waiting: { label: "Waiting", tone: "amber" },
  completed: { label: "Completed", tone: "teal" },
  handed_off: { label: "Handed off", tone: "neutral" },
  failed: { label: "Failed", tone: "brick" },
  cancelled: { label: "Stopped", tone: "neutral" },
  expired: { label: "Expired", tone: "neutral" },
};
const WAITING: Record<string, string> = { reply: "for a reply", delay: "for a delay", retry: "to retry a send" };
const FILTERS = [
  ["", "All"],
  ["active", "In progress"],
  ["completed", "Completed"],
  ["handed_off", "Handed off"],
  ["failed", "Failed"],
] as const;

function RunDetail({ id, canManage, onBack, onChanged }: { id: number; canManage: boolean; onBack: () => void; onChanged: () => void }) {
  const toast = useToast();
  const { data, reload } = useApi<{ data: FlowRun }>(`/flow-runs/${id}`);
  const [busy, setBusy] = useState(false);
  const r = data?.data;
  async function stop() {
    setBusy(true);
    try {
      await api.post(`/flow-runs/${id}/cancel`);
      toast("success", "Run stopped");
      reload();
      onChanged();
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setBusy(false);
    }
  }
  if (!r) return <Skeleton className="h-48 w-full" />;
  const active = r.status === "running" || r.status === "waiting";
  return (
    <div>
      <button onClick={onBack} className="mb-3 inline-flex items-center gap-1 text-[13px] text-muted hover:text-teal">
        <ArrowLeft className="size-4" /> All runs
      </button>
      <div className="mb-4 flex flex-wrap items-start justify-between gap-3">
        <div>
          <p className="font-semibold">{r.contact.name || formatPhone(r.contact.phone)}</p>
          <p className="text-[13px] text-muted">
            Version {r.version}, started {formatDateTime(r.started_at)}
          </p>
          <p className="mt-1 flex items-center gap-2 text-sm">
            <Badge tone={RUN_STATUS[r.status].tone}>{RUN_STATUS[r.status].label}</Badge>
            {r.status === "waiting" && r.waiting_for && <span className="text-muted">{WAITING[r.waiting_for]}</span>}
            {!active && r.end_reason && <span className="text-muted">{r.end_reason}</span>}
          </p>
        </div>
        <div className="flex gap-2">
          <Link href={`/inbox?c=${r.conversation_id}`} className="rounded-md border border-line px-3 py-1.5 text-[13px] font-medium hover:border-teal/40">
            Open chat
          </Link>
          {canManage && active && (
            <Button size="sm" variant="danger" loading={busy} onClick={stop}>
              Stop run
            </Button>
          )}
        </div>
      </div>
      <ol className="relative space-y-3 border-l-2 border-line pl-5">
        {r.steps?.map((s) => (
          <li key={s.id} className="relative">
            <span className={clsx("absolute -left-[27px] top-1 size-3 rounded-full ring-4 ring-white", s.outcome === "failed" ? "bg-brick" : s.outcome === "retry" || s.outcome === "waiting" ? "bg-amber" : "bg-teal")} />
            <p className="text-sm">
              <span className="font-medium">{s.node_label}</span> <span className="text-muted">{s.detail}</span>
            </p>
            <p className="tabular text-xs text-muted">{formatDateTime(s.created_at)}</p>
          </li>
        ))}
        {r.steps?.length === 0 && <li className="text-sm text-muted">No steps recorded.</li>}
      </ol>
    </div>
  );
}

/** Run history for one flow: who went through it, where they are, and every step taken. */
export function RunsDialog({ flowId, canManage, onClose }: { flowId: number; canManage: boolean; onClose: () => void }) {
  const [status, setStatus] = useState("");
  const [page, setPage] = useState(1);
  const [selected, setSelected] = useState<number | null>(null);
  const { data, reload } = useApi<{ data: FlowRun[]; meta: { total: number; last_page: number; counts: Record<string, number> } }>(`/bot-flows/${flowId}/runs${qs({ status, page })}`);
  const rows = data?.data ?? [];
  return (
    <Dialog open onClose={onClose} size="lg" title="Runs" description="Each time someone goes through this flow. Runs keep the version they started on.">
      {selected ? (
        <RunDetail id={selected} canManage={canManage} onBack={() => setSelected(null)} onChanged={reload} />
      ) : (
        <>
          <div className="mb-3 flex gap-1 overflow-x-auto" role="tablist" aria-label="Filter runs">
            {FILTERS.map(([v, l]) => (
              <button key={v} role="tab" aria-selected={status === v} onClick={() => (setStatus(v), setPage(1))} className={clsx("shrink-0 rounded-full px-3 py-1 text-[13px]", status === v ? "bg-ink text-white" : "text-muted hover:bg-paper")}>
                {l}
              </button>
            ))}
          </div>
          {!data ? (
            <Skeleton className="h-40 w-full" />
          ) : rows.length === 0 ? (
            <p className="py-8 text-center text-sm text-muted">No runs yet. Switch the flow on and send its start message from WhatsApp.</p>
          ) : (
            <ul className="divide-y divide-line">
              {rows.map((r) => (
                <li key={r.id}>
                  <button onClick={() => setSelected(r.id)} className="flex w-full items-center gap-3 py-2.5 text-left hover:bg-paper/60">
                    <div className="min-w-0 flex-1">
                      <p className="truncate text-sm font-medium">{r.contact.name || formatPhone(r.contact.phone)}</p>
                      <p className="truncate text-xs text-muted">
                        {formatDateTime(r.started_at)}
                        {r.end_reason && r.status !== "waiting" ? `, ${r.end_reason}` : r.waiting_for ? `, waiting ${WAITING[r.waiting_for]}` : ""}
                      </p>
                    </div>
                    <Badge tone={RUN_STATUS[r.status].tone}>{RUN_STATUS[r.status].label}</Badge>
                  </button>
                </li>
              ))}
            </ul>
          )}
          {data && data.meta.last_page > 1 && (
            <div className="mt-3 flex justify-end gap-2">
              <Button size="sm" disabled={page <= 1} onClick={() => setPage(page - 1)}>
                Previous
              </Button>
              <Button size="sm" disabled={page >= data.meta.last_page} onClick={() => setPage(page + 1)}>
                Next
              </Button>
            </div>
          )}
        </>
      )}
    </Dialog>
  );
}
