/**
 * POST /api/admin/demo-brand/seed/dashboard-gsc-ga4
 * ──────────────────────────────────────────────────
 * Phase 3 seed: GscQuery, GscPage, MetricSnapshot, DashboardData
 *
 * Generates 120 days of GSC organic search data + daily metric
 * snapshots with realistic growth trend and seasonality.
 *
 * Auth: x-admin-secret header
 * Body: { brandId: string }
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";

export const dynamic = "force-dynamic";
export const maxDuration = 300;

const BATCH = 5000;

const GSC_KEYWORDS = [
  { query: "houston cardiologist",               baseClicks: 42,  baseImpressions: 520,  basePosition: 3.2  },
  { query: "cardiologist near me",               baseClicks: 28,  baseImpressions: 980,  basePosition: 7.8  },
  { query: "heart specialist houston",           baseClicks: 31,  baseImpressions: 410,  basePosition: 4.1  },
  { query: "cardiac care houston",               baseClicks: 19,  baseImpressions: 280,  basePosition: 6.5  },
  { query: "atrial fibrillation treatment",      baseClicks: 14,  baseImpressions: 620,  basePosition: 11.2 },
  { query: "cardiologist sugar land tx",         baseClicks: 22,  baseImpressions: 230,  basePosition: 2.8  },
  { query: "heart failure specialist houston",   baseClicks: 11,  baseImpressions: 190,  basePosition: 8.4  },
  { query: "cardiac imaging houston",            baseClicks: 9,   baseImpressions: 145,  basePosition: 5.7  },
  { query: "best cardiologist houston",          baseClicks: 17,  baseImpressions: 340,  basePosition: 3.9  },
  { query: "preventive cardiology",              baseClicks: 8,   baseImpressions: 260,  basePosition: 12.1 },
  { query: "electrophysiology houston",          baseClicks: 13,  baseImpressions: 175,  basePosition: 4.6  },
  { query: "heart doctor houston texas",         baseClicks: 20,  baseImpressions: 390,  basePosition: 5.3  },
  { query: "pediatric cardiologist houston",     baseClicks: 7,   baseImpressions: 120,  basePosition: 9.2  },
  { query: "heart palpitations specialist",      baseClicks: 6,   baseImpressions: 210,  basePosition: 14.8 },
  { query: "coronary artery disease treatment",  baseClicks: 5,   baseImpressions: 180,  basePosition: 16.3 },
];

const GSC_PAGES = [
  { pageUrl: "/services/cardiac-care/",         baseClicks: 89,  baseImpressions: 1200, basePosition: 3.1  },
  { pageUrl: "/",                               baseClicks: 62,  baseImpressions: 890,  basePosition: 5.4  },
  { pageUrl: "/appointments/",                  baseClicks: 48,  baseImpressions: 640,  basePosition: 4.2  },
  { pageUrl: "/services/electrophysiology/",    baseClicks: 31,  baseImpressions: 480,  basePosition: 6.8  },
  { pageUrl: "/locations/houston/",             baseClicks: 41,  baseImpressions: 560,  basePosition: 3.7  },
  { pageUrl: "/blog/heart-health-tips/",        baseClicks: 24,  baseImpressions: 820,  basePosition: 8.3  },
  { pageUrl: "/about/our-team/",               baseClicks: 18,  baseImpressions: 280,  basePosition: 9.1  },
  { pageUrl: "/services/preventive-cardiology/", baseClicks: 22, baseImpressions: 310,  basePosition: 7.4  },
  { pageUrl: "/blog/managing-atrial-fibrillation/", baseClicks: 16, baseImpressions: 540, basePosition: 10.2 },
  { pageUrl: "/locations/sugar-land/",          baseClicks: 29,  baseImpressions: 390,  basePosition: 4.5  },
];

function seeded(n: number, salt: number): number {
  const x = Math.sin(n * 9301 + salt * 49297 + 233) * 100003;
  return Math.abs(x - Math.floor(x));
}

export async function POST(req: Request) {
  const secret = req.headers.get("x-admin-secret");
  if (!secret || secret !== process.env.ADMIN_SECRET) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const body = await req.json().catch(() => null) as { brandId?: string } | null;
  if (!body?.brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });

  const brand = await prisma.brand.findUnique({ where: { id: body.brandId }, select: { id: true, isDemo: true, domain: true } });
  if (!brand) return NextResponse.json({ error: "Brand not found" }, { status: 404 });
  if (!brand.isDemo) return NextResponse.json({ error: "Brand is not a demo brand — seed refused" }, { status: 403 });

  const now = Date.now();
  const gscQueryRows: Array<{ brandId: string; query: string; clicks: number; impressions: number; ctr: number; position: number; date: Date }> = [];
  const gscPageRows: Array<{ brandId: string; pageUrl: string; clicks: number; impressions: number; ctr: number; position: number; date: Date }> = [];
  const metricRows: Array<{ brandId: string; date: Date; source: string; sessions: number; users: number; pageviews: number; bounceRate: number; avgSessionSec: number; conversions: number; organicClicks: number; impressions: number; avgPosition: number; ctr: number; seoScore: number; crawlHealth: number; aiMentions: number; siteTagSessions: number; siteTagPageViews: number; siteTagConversions: number }> = [];

  for (let dayBack = 119; dayBack >= 0; dayBack--) {
    const dayTs = now - dayBack * 86_400_000;
    const dayDate = new Date(dayTs);
    const dow = dayDate.getUTCDay();
    const isWeekend = dow === 0 || dow === 6;
    const growth = 0.75 + (119 - dayBack) / 119 * 0.35; // 0.75 → 1.1
    const weekMult = isWeekend ? 0.45 : 1.0;
    const noise = (n: number, s: number) => 1 + (seeded(dayBack * 100 + n, s) - 0.5) * 0.15; // ±7.5%

    // GSC queries — one row per keyword per day
    for (let qi = 0; qi < GSC_KEYWORDS.length; qi++) {
      const kw = GSC_KEYWORDS[qi];
      const clicks = Math.max(0, Math.round(kw.baseClicks * growth * weekMult * noise(qi, 1)));
      const impressions = Math.max(1, Math.round(kw.baseImpressions * growth * weekMult * noise(qi, 2)));
      const position = Math.max(1, kw.basePosition + (seeded(dayBack * 100 + qi, 3) - 0.5) * 1.5);
      const ctr = impressions > 0 ? Math.min(0.35, clicks / impressions) : 0;
      gscQueryRows.push({ brandId: body.brandId, query: kw.query, clicks, impressions, ctr, position, date: dayDate });
    }

    // GSC pages — one row per page per day
    for (let pi = 0; pi < GSC_PAGES.length; pi++) {
      const pg = GSC_PAGES[pi];
      const clicks = Math.max(0, Math.round(pg.baseClicks * growth * weekMult * noise(pi, 4)));
      const impressions = Math.max(1, Math.round(pg.baseImpressions * growth * weekMult * noise(pi, 5)));
      const position = Math.max(1, pg.basePosition + (seeded(dayBack * 100 + pi, 6) - 0.5) * 1.2);
      const ctr = impressions > 0 ? Math.min(0.4, clicks / impressions) : 0;
      gscPageRows.push({ brandId: body.brandId, pageUrl: `https://${brand.domain}${pg.pageUrl}`, clicks, impressions, ctr, position, date: dayDate });
    }

    // Daily metric snapshot
    const sessions = Math.round(2000 * growth * weekMult * noise(0, 7));
    const users = Math.round(sessions * 0.78);
    const pageviews = Math.round(sessions * 3.8 * noise(1, 8));
    const conversions = Math.round((isWeekend ? 55 : 115) * growth * noise(2, 9));
    const organicClicks = gscQueryRows.slice(-GSC_KEYWORDS.length).reduce((s, r) => s + r.clicks, 0);
    const totalImpressions = gscQueryRows.slice(-GSC_KEYWORDS.length).reduce((s, r) => s + r.impressions, 0);
    const avgPos = 6.2 + (seeded(dayBack, 10) - 0.5) * 0.8;
    const totalCtr = totalImpressions > 0 ? organicClicks / totalImpressions : 0;
    const seoScore = Math.round(68 + (119 - dayBack) / 119 * 10 + (seeded(dayBack, 11) - 0.5) * 4);
    const crawlHealth = Math.round(75 + (119 - dayBack) / 119 * 8 + (seeded(dayBack, 12) - 0.5) * 5);
    const aiMentions = Math.round(2 + (119 - dayBack) / 119 * 6 + seeded(dayBack, 13) * 3);

    metricRows.push({
      brandId: body.brandId,
      date: dayDate,
      source: "seed",
      sessions,
      users,
      pageviews,
      bounceRate: 0.38 + seeded(dayBack, 14) * 0.12,
      avgSessionSec: 145 + Math.round(seeded(dayBack, 15) * 60),
      conversions,
      organicClicks,
      impressions: totalImpressions,
      avgPosition: avgPos,
      ctr: totalCtr,
      seoScore: Math.min(100, seoScore),
      crawlHealth: Math.min(100, crawlHealth),
      aiMentions,
      siteTagSessions: sessions,
      siteTagPageViews: pageviews,
      siteTagConversions: conversions,
    });
  }

  // Insert in batches
  let gscQueryCount = 0;
  for (let i = 0; i < gscQueryRows.length; i += BATCH) {
    await prisma.gscQuery.createMany({ data: gscQueryRows.slice(i, i + BATCH), skipDuplicates: true });
    gscQueryCount += Math.min(BATCH, gscQueryRows.length - i);
  }

  let gscPageCount = 0;
  for (let i = 0; i < gscPageRows.length; i += BATCH) {
    await prisma.gscPage.createMany({ data: gscPageRows.slice(i, i + BATCH), skipDuplicates: true });
    gscPageCount += Math.min(BATCH, gscPageRows.length - i);
  }

  let metricCount = 0;
  for (let i = 0; i < metricRows.length; i += BATCH) {
    await prisma.metricSnapshot.createMany({ data: metricRows.slice(i, i + BATCH), skipDuplicates: true });
    metricCount += Math.min(BATCH, metricRows.length - i);
  }

  // Upsert DashboardData with computed totals from the seed data
  await prisma.dashboardData.upsert({
    where: { brandId: body.brandId },
    update: {
      seoScore: 74,
      aiVisibility: 62,
      crawlHealth: 81,
      monthlyTraffic: Math.round(gscPageRows.slice(-10 * GSC_PAGES.length).reduce((s, r) => s + r.clicks, 0) * 3),
      alertCount: 3,
    },
    create: {
      brandId: body.brandId,
      seoScore: 74,
      aiVisibility: 62,
      crawlHealth: 81,
      monthlyTraffic: 24800,
      alertCount: 3,
    },
  });

  console.info(`[demo-brand/seed/phase3] brand=${body.brandId} gscQueries=${gscQueryCount} gscPages=${gscPageCount} metricSnapshots=${metricCount}`);

  return NextResponse.json({
    ok: true,
    phase: "dashboard-gsc-ga4",
    created: { gscQueries: gscQueryCount, gscPages: gscPageCount, metricSnapshots: metricCount },
  });
}
