"use client";

import { useEffect, useMemo, useState } from "react";

type TrafficReport = {
  views: number;
  uniques: number;
  signups: number;
  paid: number;
  series: { day: string; views: number; uniques: number }[];
  pages: { path: string; views: number }[];
  referrers: { source: string; views: number }[];
};

function ymd(d: Date) {
  return d.toISOString().slice(0, 10);
}

function presetRange(key: string) {
  const to = new Date();
  const from = new Date();
  if (key === "today") {
    /* same day */
  } else if (key === "7") from.setUTCDate(from.getUTCDate() - 6);
  else if (key === "30") from.setUTCDate(from.getUTCDate() - 29);
  else if (key === "90") from.setUTCDate(from.getUTCDate() - 89);
  else from.setUTCDate(from.getUTCDate() - 29);
  return { from: ymd(from), to: ymd(to) };
}

function LineChart({
  points,
  color = "#0e2f24",
}: {
  points: { label: string; value: number }[];
  color?: string;
}) {
  const w = 640;
  const h = 220;
  const pad = { l: 36, r: 12, t: 16, b: 28 };
  const max = Math.max(1, ...points.map((p) => p.value));
  const innerW = w - pad.l - pad.r;
  const innerH = h - pad.t - pad.b;
  const coords = points.map((p, i) => {
    const x = pad.l + (points.length <= 1 ? innerW / 2 : (i / (points.length - 1)) * innerW);
    const y = pad.t + innerH - (p.value / max) * innerH;
    return { x, y, ...p };
  });
  const line = coords.map((c, i) => `${i === 0 ? "M" : "L"}${c.x},${c.y}`).join(" ");
  const area = coords.length
    ? `${line} L${coords[coords.length - 1].x},${pad.t + innerH} L${coords[0].x},${pad.t + innerH} Z`
    : "";
  const tickEvery = Math.max(1, Math.ceil(points.length / 7));

  return (
    <svg viewBox={`0 0 ${w} ${h}`} className="h-auto w-full">
      {[0, 0.5, 1].map((t) => {
        const y = pad.t + innerH * (1 - t);
        return (
          <g key={t}>
            <line x1={pad.l} x2={w - pad.r} y1={y} y2={y} stroke="#e7dcc6" />
            <text x={4} y={y + 4} fontSize="10" fill="#5c5348">
              {Math.round(max * t)}
            </text>
          </g>
        );
      })}
      <path d={area} fill={color} opacity="0.12" />
      <path d={line} fill="none" stroke={color} strokeWidth="2.5" strokeLinejoin="round" />
      {coords.map((c, i) =>
        i % tickEvery === 0 || i === coords.length - 1 ? (
          <text key={c.label} x={c.x} y={h - 8} fontSize="9" textAnchor="middle" fill="#5c5348">
            {c.label.slice(5)}
          </text>
        ) : null
      )}
    </svg>
  );
}

function BarList({
  rows,
  labelKey,
  sort,
}: {
  rows: { label: string; value: number }[];
  labelKey?: string;
  sort: "desc" | "asc";
}) {
  const ordered = [...rows].sort((a, b) => (sort === "desc" ? b.value - a.value : a.value - b.value));
  const max = Math.max(1, ...ordered.map((r) => r.value));
  if (!ordered.length) {
    return <p className="text-sm text-forest/50">No traffic in this range yet.</p>;
  }
  return (
    <ul className="space-y-2">
      {ordered.map((r) => (
        <li key={`${labelKey}-${r.label}`}>
          <div className="flex items-center justify-between text-sm">
            <span className="truncate pr-3 text-forest">{r.label}</span>
            <strong>{r.value}</strong>
          </div>
          <div className="mt-1 h-2 overflow-hidden rounded-full bg-paper-2">
            <div className="h-full rounded-full bg-gold" style={{ width: `${(r.value / max) * 100}%` }} />
          </div>
        </li>
      ))}
    </ul>
  );
}

export function TrafficCharts() {
  const initial = presetRange("30");
  const [preset, setPreset] = useState("30");
  const [from, setFrom] = useState(initial.from);
  const [to, setTo] = useState(initial.to);
  const [sort, setSort] = useState<"desc" | "asc">("desc");
  const [data, setData] = useState<TrafficReport | null>(null);
  const [error, setError] = useState("");

  useEffect(() => {
    setError("");
    fetch(`/api/admin/traffic?from=${from}&to=${to}`)
      .then(async (r) => {
        const json = await r.json();
        if (!r.ok) throw new Error(json.error || "Could not load traffic");
        setData(json);
      })
      .catch((err) => setError(err.message));
  }, [from, to]);

  function applyPreset(key: string) {
    setPreset(key);
    if (key === "custom") return;
    const range = presetRange(key);
    setFrom(range.from);
    setTo(range.to);
  }

  const lineViews = useMemo(
    () => (data?.series || []).map((s) => ({ label: s.day, value: s.views })),
    [data]
  );
  const lineUniques = useMemo(
    () => (data?.series || []).map((s) => ({ label: s.day, value: s.uniques })),
    [data]
  );

  return (
    <section className="mt-10">
      <div className="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
        <div>
          <h2 className="font-display text-2xl text-forest">Visits &amp; traffic</h2>
          <p className="text-sm text-forest/60">Page views and unique visitors. Filter by date.</p>
        </div>
        <div className="flex flex-wrap items-end gap-2">
          {[
            ["today", "Today"],
            ["7", "7 days"],
            ["30", "30 days"],
            ["90", "90 days"],
            ["custom", "Custom"],
          ].map(([key, label]) => (
            <button
              key={key}
              type="button"
              onClick={() => applyPreset(key)}
              className={`rounded-full px-3 py-1.5 text-xs font-semibold ${
                preset === key ? "bg-forest text-gold-2" : "border border-forest/15 text-forest"
              }`}
            >
              {label}
            </button>
          ))}
          <label className="text-xs text-forest/70">
            From
            <input
              type="date"
              value={from}
              onChange={(e) => {
                setPreset("custom");
                setFrom(e.target.value);
              }}
              className="ml-1 rounded-lg border border-forest/15 bg-white px-2 py-1"
            />
          </label>
          <label className="text-xs text-forest/70">
            To
            <input
              type="date"
              value={to}
              onChange={(e) => {
                setPreset("custom");
                setTo(e.target.value);
              }}
              className="ml-1 rounded-lg border border-forest/15 bg-white px-2 py-1"
            />
          </label>
          <label className="text-xs text-forest/70">
            Sort pages
            <select
              value={sort}
              onChange={(e) => setSort(e.target.value as "desc" | "asc")}
              className="ml-1 rounded-lg border border-forest/15 bg-white px-2 py-1"
            >
              <option value="desc">Most visits</option>
              <option value="asc">Least visits</option>
            </select>
          </label>
        </div>
      </div>

      {error ? <p className="mt-4 text-sm text-terra">{error}</p> : null}

      <div className="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {[
          ["Page views", data ? String(data.views) : "—"],
          ["Unique visitors", data ? String(data.uniques) : "—"],
          ["Signups", data ? String(data.signups) : "—"],
          ["Successful payments", data ? String(data.paid) : "—"],
        ].map(([k, v]) => (
          <div key={k} className="rounded-3xl bg-cream p-5">
            <p className="text-xs uppercase tracking-widest text-forest/50">{k}</p>
            <p className="font-display mt-2 text-3xl text-forest">{v}</p>
          </div>
        ))}
      </div>

      <div className="mt-6 grid gap-6 lg:grid-cols-2">
        <div className="rounded-3xl bg-cream p-5">
          <p className="text-sm font-medium text-forest">Page views by day</p>
          <div className="mt-3">
            <LineChart points={lineViews} color="#0e2f24" />
          </div>
        </div>
        <div className="rounded-3xl bg-cream p-5">
          <p className="text-sm font-medium text-forest">Unique visitors by day</p>
          <div className="mt-3">
            <LineChart points={lineUniques} color="#c45c26" />
          </div>
        </div>
      </div>

      <div className="mt-6 grid gap-6 lg:grid-cols-2">
        <div className="rounded-3xl bg-cream p-5">
          <p className="text-sm font-medium text-forest">Top pages</p>
          <div className="mt-4">
            <BarList
              sort={sort}
              rows={(data?.pages || []).map((p) => ({ label: p.path, value: p.views }))}
            />
          </div>
        </div>
        <div className="rounded-3xl bg-cream p-5">
          <p className="text-sm font-medium text-forest">Traffic sources</p>
          <div className="mt-4">
            <BarList
              sort={sort}
              labelKey="ref"
              rows={(data?.referrers || []).map((r) => ({ label: r.source, value: r.views }))}
            />
          </div>
        </div>
      </div>
    </section>
  );
}
