// @File: src/pages/admin/cms/CmsVisitorJourney.tsx
// @Desc: Per-session visitor journey timeline. Accepts ?session=<id>.
import { FormEvent, useCallback, useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import {
  CheckCircle2,
  FileText,
  LogIn,
  MousePointerClick,
  Route,
  ShoppingCart,
  Search,
  Loader2,
  Activity,
} from "lucide-react";
import CmsLayout from "./CmsLayout";
import { Badge, PageHeader, SectionCard, TextInput } from "./ui";
import { vmGetJourney, vmListSessions, type VmJourney, type VmSessionItem } from "@/lib/adminApi";

function eventIcon(type: string) {
  if (type === "pageview") return <FileText className="w-4 h-4 text-sky-600" />;
  if (type === "click") return <MousePointerClick className="w-4 h-4 text-violet-600" />;
  if (type === "form_submit") return <CheckCircle2 className="w-4 h-4 text-amber-600" />;
  if (type === "signup") return <LogIn className="w-4 h-4 text-emerald-600" />;
  if (type === "order") return <ShoppingCart className="w-4 h-4 text-rose-600" />;
  return <Activity className="w-4 h-4 text-slate-500" />;
}

function formatDT(iso: string): string {
  try {
    return new Date(iso).toLocaleString();
  } catch {
    return iso;
  }
}

export default function CmsVisitorJourney() {
  const [params, setParams] = useSearchParams();
  const sessionParam = params.get("session") || "";
  const [input, setInput] = useState(sessionParam);
  const [journey, setJourney] = useState<VmJourney | null>(null);
  const [recent, setRecent] = useState<VmSessionItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const loadJourney = useCallback(async (sid: string) => {
    if (!sid) return;
    setLoading(true);
    setError(null);
    try {
      const j = await vmGetJourney(sid);
      setJourney(j);
    } catch (err) {
      setJourney(null);
      setError(err instanceof Error ? err.message : "Failed to load journey");
    } finally {
      setLoading(false);
    }
  }, []);

  const loadRecent = useCallback(async () => {
    try {
      const list = await vmListSessions({ page: 1, pageSize: 20 });
      setRecent(list.items);
    } catch {
      /* ignore */
    }
  }, []);

  useEffect(() => {
    void loadRecent();
  }, [loadRecent]);

  useEffect(() => {
    if (sessionParam) {
      setInput(sessionParam);
      void loadJourney(sessionParam);
    }
  }, [sessionParam, loadJourney]);

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    const trimmed = input.trim();
    if (!trimmed) return;
    setParams({ session: trimmed });
  };

  const selectSession = (sid: string) => {
    setInput(sid);
    setParams({ session: sid });
  };

  return (
    <CmsLayout>
      <PageHeader
        title="Visitor Journey"
        description="Pick a session to see the full timeline of pages, clicks and conversions."
        icon={<Route className="w-6 h-6" />}
      />

      <SectionCard title="Look up a session">
        <form onSubmit={handleSubmit} className="flex items-center gap-2">
          <div className="relative flex-1">
            <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
            <TextInput
              value={input}
              onChange={(e) => setInput(e.target.value)}
              placeholder="Paste a session id…"
              className="pl-9"
            />
          </div>
          <button
            type="submit"
            className="px-4 py-2 rounded-lg bg-[#0b6e3e] text-white text-sm font-bold hover:bg-[#0a8048] transition"
          >
            Load
          </button>
        </form>
        {error && (
          <div className="mt-3 p-3 rounded-lg bg-red-50 border border-red-200 text-sm text-red-700">
            {error}
          </div>
        )}
      </SectionCard>

      {journey && (
        <SectionCard
          title={`Session ${journey.session.session_id.slice(0, 12)}…`}
          description={`${journey.session.pageview_count} pageviews · stage: ${journey.session.conversion_stage}`}
        >
          <div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-xs">
            <InfoBox label="Location" value={`${journey.session.country || "—"} ${journey.session.city ? "· " + journey.session.city : ""}`} />
            <InfoBox label="Device" value={`${journey.session.device || "—"} · ${journey.session.browser || "—"}`} />
            <InfoBox label="OS" value={journey.session.os || "—"} />
            <InfoBox label="IP" value={journey.session.ip_address || "—"} mono />
            <InfoBox label="Landing" value={journey.session.landing_page || "—"} mono />
            <InfoBox label="Referrer" value={journey.session.referrer || "direct"} mono />
            <InfoBox label="UTM" value={journey.session.utm_campaign || "—"} />
            <InfoBox
              label="Started"
              value={formatDT(journey.session.started_at)}
            />
          </div>

          <div className="mt-6 relative">
            <div className="absolute left-4 top-2 bottom-2 w-px bg-slate-200" aria-hidden />
            <ul className="space-y-4">
              {journey.events.length === 0 && (
                <li className="pl-12 text-slate-400 text-sm">No events recorded.</li>
              )}
              {journey.events.map((ev) => (
                <li key={ev.id} className="relative pl-12">
                  <div className="absolute left-0 top-0 w-8 h-8 rounded-full bg-white border-2 border-slate-200 flex items-center justify-center">
                    {eventIcon(ev.event_type)}
                  </div>
                  <div className="bg-white border border-slate-200 rounded-xl p-3">
                    <div className="flex items-center gap-2 flex-wrap">
                      <Badge tone="slate">{ev.event_type}</Badge>
                      {ev.label && <span className="text-sm font-semibold text-slate-800">{ev.label}</span>}
                      <span className="text-[11px] text-slate-400 ml-auto">
                        {formatDT(ev.created_at)}
                      </span>
                    </div>
                    {ev.page && (
                      <div className="text-xs text-slate-500 mt-1 font-mono">{ev.page}</div>
                    )}
                    {ev.metadata && Object.keys(ev.metadata).length > 0 && (
                      <pre className="text-[11px] bg-slate-50 rounded p-2 mt-2 overflow-x-auto">
                        {JSON.stringify(ev.metadata, null, 2)}
                      </pre>
                    )}
                  </div>
                </li>
              ))}
            </ul>
          </div>
        </SectionCard>
      )}

      <SectionCard title="Recent sessions" description="Click any row to load its journey.">
        {loading && <div className="text-slate-400 text-sm">Loading…</div>}
        <div className="overflow-x-auto -mx-5 md:-mx-6">
          <table className="w-full text-sm">
            <thead className="bg-slate-50 text-left text-[11px] uppercase tracking-wider text-slate-500">
              <tr>
                <th className="px-4 py-3">Session</th>
                <th className="px-4 py-3">Location</th>
                <th className="px-4 py-3">Device</th>
                <th className="px-4 py-3">Pages</th>
                <th className="px-4 py-3">Stage</th>
                <th className="px-4 py-3">Started</th>
              </tr>
            </thead>
            <tbody>
              {recent.map((r) => (
                <tr
                  key={r.session_id}
                  onClick={() => selectSession(r.session_id)}
                  className="border-t border-slate-100 hover:bg-emerald-50/40 cursor-pointer"
                >
                  <td className="px-4 py-3 font-mono text-[11px] text-slate-600">
                    {r.session_id.slice(0, 14)}…
                  </td>
                  <td className="px-4 py-3">{r.country || "—"}</td>
                  <td className="px-4 py-3">{r.device || "—"} · {r.browser || "—"}</td>
                  <td className="px-4 py-3">{r.pageview_count}</td>
                  <td className="px-4 py-3">
                    <Badge
                      tone={
                        r.conversion_stage === "order"
                          ? "green"
                          : r.conversion_stage === "signup"
                            ? "blue"
                            : r.conversion_stage === "lead"
                              ? "yellow"
                              : "slate"
                      }
                    >
                      {r.conversion_stage}
                    </Badge>
                  </td>
                  <td className="px-4 py-3 text-[12px] text-slate-500">{formatDT(r.started_at)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </SectionCard>
    </CmsLayout>
  );
}

function InfoBox({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
  return (
    <div className="bg-slate-50 rounded-lg p-3">
      <div className="text-[10px] uppercase tracking-wider font-semibold text-slate-500">
        {label}
      </div>
      <div className={`mt-1 text-slate-800 truncate ${mono ? "font-mono text-[11px]" : ""}`}>
        {value}
      </div>
    </div>
  );
}