import Link from "next/link";
import { notFound, redirect } from "next/navigation";
import { createAdminClient } from "@/lib/supabase/admin";
import { createClient } from "@/lib/supabase/server";
import AnalyticsCharts from "./AnalyticsCharts";

export const dynamic = "force-dynamic";
export const revalidate = 0;

interface BannerRow {
  id: string;
  slug: string;
  name: string;
  image_path: string;
  click_url: string | null;
  size: string;
  status: string;
}

interface Row {
  campaign_id: string;
  occurred_at: string;
  page_path: string | null;
  referrer: string | null;
  is_bot: boolean;
  viewport?: boolean;
}

async function requireAdmin() {
  const sb = await createClient();
  const { data: { user } } = await sb.auth.getUser();
  if (!user) return { ok: false as const };
  const { data: profile } = await sb
    .from("user_profiles")
    .select("role,is_active")
    .eq("id", user.id)
    .maybeSingle();
  if (!profile?.is_active) return { ok: false as const };
  if (!["administrator", "admin"].includes((profile as any).role)) return { ok: false as const };
  return { ok: true as const };
}

function dayBuckets(rows: Row[], days = 30): { date: string; count: number }[] {
  const today = new Date();
  today.setUTCHours(0, 0, 0, 0);
  const out: { date: string; count: number }[] = [];
  const map = new Map<string, number>();
  for (const r of rows) {
    const d = r.occurred_at.slice(0, 10);
    map.set(d, (map.get(d) || 0) + 1);
  }
  for (let i = days - 1; i >= 0; i--) {
    const d = new Date(today.getTime() - i * 86400000);
    const key = d.toISOString().slice(0, 10);
    out.push({ date: key, count: map.get(key) || 0 });
  }
  return out;
}

function topGroup(rows: Row[], key: keyof Row, limit = 8): { label: string; count: number }[] {
  const m = new Map<string, number>();
  for (const r of rows) {
    const v = (r[key] || "(none)") as string;
    m.set(v, (m.get(v) || 0) + 1);
  }
  return [...m.entries()]
    .sort((a, b) => b[1] - a[1])
    .slice(0, limit)
    .map(([label, count]) => ({ label, count }));
}

function referrerDomain(r: string | null): string {
  if (!r) return "(direct)";
  try {
    const u = new URL(r);
    return u.hostname || "(direct)";
  } catch {
    return "(invalid)";
  }
}

export default async function BannerAnalyticsPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const guard = await requireAdmin();
  if (!guard.ok) redirect("/admin");

  const { id } = await params;
  const admin = createAdminClient();

  const { data: banner } = await admin
    .from("banner_creatives")
    .select("id, slug, name, image_path, click_url, size, status")
    .eq("id", id)
    .maybeSingle();
  if (!banner) notFound();
  const b = banner as BannerRow;

  const sinceIso = new Date(Date.now() - 30 * 86400000).toISOString();

  const [imp, clk] = await Promise.all([
    admin
      .from("ad_impressions")
      .select("campaign_id, occurred_at, page_path, referrer, is_bot, viewport")
      .eq("campaign_id", id)
      .gte("occurred_at", sinceIso)
      .order("occurred_at", { ascending: false })
      .limit(50000),
    admin
      .from("ad_clicks")
      .select("campaign_id, occurred_at, page_url, referrer, is_bot")
      .eq("campaign_id", id)
      .gte("occurred_at", sinceIso)
      .order("occurred_at", { ascending: false })
      .limit(50000),
  ]);

  const impRows = (imp.data || []) as Row[];
  const clkRows = (clk.data || []).map((r: any) => ({
    campaign_id: r.campaign_id,
    occurred_at: r.occurred_at,
    page_path: r.page_url || null,
    referrer: r.referrer,
    is_bot: r.is_bot,
  })) as Row[];

  const impHuman = impRows.filter((r) => !r.is_bot);
  const clkHuman = clkRows.filter((r) => !r.is_bot);

  const impSeries = dayBuckets(impHuman, 30);
  const clkSeries = dayBuckets(clkHuman, 30);
  const impSeriesBot = dayBuckets(impRows, 30);
  const clkSeriesBot = dayBuckets(clkRows, 30);

  const topPages = topGroup(impHuman, "page_path");
  const topReferrers = topGroup(
    impHuman.map((r) => ({ ...r, referrer: referrerDomain(r.referrer) })),
    "referrer",
  );

  return (
    <main className="mx-auto max-w-6xl px-6 py-10 text-[#e5e7eb]">
      <Link href="/admin/banners" className="text-sm text-[#1D4ED8] hover:underline">
        ← Back to banners
      </Link>

      <header className="mt-4 mb-6 border-b border-[#222] pb-4">
        <div className="flex items-center gap-3">
          <img
            src={b.image_path}
            alt={b.name}
            style={{ height: 60, width: "auto" }}
            className="rounded border border-[#1f2937]"
          />
          <div>
            <h1 className="text-2xl font-bold tracking-tight">{b.name}</h1>
            <p className="text-sm text-[#9ca3af]">
              {b.size} · {b.status} ·{" "}
              {b.click_url && (
                <a className="text-[#1D4ED8] hover:underline" href={b.click_url} target="_blank" rel="noopener noreferrer">
                  {b.click_url.slice(0, 80)}{b.click_url.length > 80 ? "…" : ""}
                </a>
              )}
            </p>
          </div>
        </div>
      </header>

      <AnalyticsCharts
        impSeries={impSeries}
        clkSeries={clkSeries}
        impSeriesBot={impSeriesBot}
        clkSeriesBot={clkSeriesBot}
        topPages={topPages}
        topReferrers={topReferrers}
        totals={{
          impHuman: impHuman.length,
          impBot: impRows.length - impHuman.length,
          clkHuman: clkHuman.length,
          clkBot: clkRows.length - clkHuman.length,
        }}
      />
    </main>
  );
}
