import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getCurrentUser } from "@/lib/auth";

export const dynamic = "force-dynamic";

const NOISE_DOMAINS = new Set([
  "facebook.com", "twitter.com", "x.com", "instagram.com", "linkedin.com",
  "youtube.com", "tiktok.com", "pinterest.com", "snapchat.com", "reddit.com",
  "google.com", "bing.com", "yahoo.com", "duckduckgo.com", "baidu.com",
  "bit.ly", "tinyurl.com", "ow.ly", "t.co", "buff.ly", "rebrand.ly",
  "amazonaws.com", "cloudfront.net", "cloudflare.com", "jsdelivr.net",
  "googleapis.com", "gstatic.com", "googletagmanager.com", "doubleclick.net",
  "apple.com", "microsoft.com", "windows.com", "office.com",
  "whatsapp.com", "wa.me", "telegram.org", "t.me",
  "maps.google.com", "maps.apple.com",
  "paypal.com", "stripe.com", "square.com", "venmo.com",
  "yelp.com", "healthgrades.com", "vitals.com", "zocdoc.com",
  "intercom.io", "drift.com", "tawk.to", "tidio.com", "livechatinc.com",
]);

async function checkBrandAccess(brandId: string, userId: string) {
  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand) return null;
  if (!brand.organization.memberships.some((m) => m.userId === userId)) return null;
  return brand;
}

export async function GET(req: NextRequest) {
  const user = await getCurrentUser();
  if (!user?.id) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { searchParams } = new URL(req.url);
  const brandId = searchParams.get("brandId");
  if (!brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });

  const brand = await checkBrandAccess(brandId, user.id);
  if (!brand) return NextResponse.json({ error: "Forbidden" }, { status: 403 });

  const brandDomain = brand.domain.replace(/^www\./, "").replace(/https?:\/\//, "").split("/")[0];
  const converters = Array.isArray((brand as unknown as { externalConverters: unknown }).externalConverters)
    ? ((brand as unknown as { externalConverters: Array<{ domain: string }> }).externalConverters)
    : [];
  const registeredDomains = new Set(converters.map((c) => c.domain));

  const site = await prisma.trackedSite.findUnique({
    where: { brandId },
    select: { id: true },
  });
  if (!site) return NextResponse.json({ suggestions: [] });

  const since = new Date(Date.now() - 30 * 86_400_000);
  const clicks = await prisma.trackedEvent.findMany({
    where: { trackedSiteId: site.id, eventType: "outbound_click", timestamp: { gte: since } },
    select: { metadata: true },
    take: 10_000,
  });

  const domainCounts = new Map<string, number>();
  for (const c of clicks) {
    const meta = (c.metadata ?? {}) as Record<string, unknown>;
    const url = String(meta.link_url ?? meta.link_domain ?? "");
    let domain: string;
    try {
      domain = url.startsWith("http") ? new URL(url).hostname.replace(/^www\./, "") : url.replace(/^www\./, "");
    } catch { continue; }
    if (!domain || domain === brandDomain) continue;
    if (NOISE_DOMAINS.has(domain)) continue;
    if (domain.endsWith("." + brandDomain)) continue;
    domainCounts.set(domain, (domainCounts.get(domain) ?? 0) + 1);
  }

  const suggestions = Array.from(domainCounts.entries())
    .filter(([, count]) => count >= 10)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 15)
    .map(([domain, clickCount]) => ({ domain, clickCount, isRegistered: registeredDomains.has(domain) }));

  return NextResponse.json({ suggestions });
}
