/**
 * POST /api/admin/demo-brand/seed/sessions-events-conversions
 * ─────────────────────────────────────────────────────────────
 * Phase 1 seed: TrackedSession, TrackedEvent, SiteConversion, VisitorProfile
 *
 * Generates 120 days of realistic site-tag data with weekday/weekend
 * variation and a ~30% growth trend over the period.
 *
 * Target volumes:
 *   Sessions:     ~240K  (avg 2,000/day weekday, 1,200/day weekend)
 *   Events:       ~960K  (~4 events per session)
 *   Conversions:  ~14K   (~117/day weekday, ~60/day weekend)
 *   Visitor profiles: ~120K unique visitors
 *
 * Auth: x-admin-secret header
 * Body: { brandId: string }
 *
 * IMPORTANT: validates isDemo: true before seeding.
 */

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

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

const BATCH = 5000;

const PAGES = [
  "/", "/services/", "/services/cardiac-care/", "/services/electrophysiology/",
  "/services/preventive-cardiology/", "/services/cardiac-imaging/",
  "/about/", "/about/our-team/", "/locations/", "/locations/houston/",
  "/locations/sugar-land/", "/appointments/", "/contact/",
  "/blog/", "/blog/heart-health-tips/", "/blog/managing-atrial-fibrillation/",
  "/blog/cardiac-imaging-explained/", "/blog/prevention-tips/",
];

const LANDING_PAGES = ["/", "/services/cardiac-care/", "/appointments/", "/locations/houston/", "/services/"];

const CHANNELS: Array<{ channel: string; source: string; medium: string }> = [
  { channel: "Organic Search", source: "google", medium: "organic" },
  { channel: "Organic Search", source: "google", medium: "organic" },
  { channel: "Organic Search", source: "google", medium: "organic" },
  { channel: "Direct", source: "(direct)", medium: "(none)" },
  { channel: "Direct", source: "(direct)", medium: "(none)" },
  { channel: "Paid Search", source: "google", medium: "cpc" },
  { channel: "Referral", source: "healthgrades.com", medium: "referral" },
  { channel: "Referral", source: "zocdoc.com", medium: "referral" },
  { channel: "Social", source: "facebook", medium: "social" },
  { channel: "Email", source: "email", medium: "newsletter" },
];

const DEVICES = ["desktop", "desktop", "desktop", "mobile", "mobile", "tablet"];
const CITIES = ["Houston", "Houston", "Houston", "Sugar Land", "Katy", "The Woodlands", "Pearland", "Humble"];

const CONV_TYPES = ["form_submit", "phone_number_click", "form_submit", "phone_number_click", "form_submit"];
const CONV_PAGES = ["/appointments/", "/contact/", "/services/cardiac-care/", "/locations/houston/"];

// Pseudo-random helper — deterministic by seed, avoids Math.random() flat distribution
function seeded(n: number, salt: number): number {
  const x = Math.sin(n * 9301 + salt * 49297 + 233) * 100003;
  return Math.abs(x - Math.floor(x));
}

function pick<T>(arr: T[], day: number, idx: number, salt: number): T {
  return arr[Math.floor(seeded(day * 1000 + idx, salt) * arr.length)];
}

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 },
    include: { trackedSite: { select: { id: 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 });
  if (!brand.trackedSite) return NextResponse.json({ error: "No TrackedSite found — run create endpoint first" }, { status: 400 });

  const trackedSiteId = brand.trackedSite.id;
  const now = Date.now();

  let totalSessions = 0;
  let totalEvents = 0;
  let totalConversions = 0;
  let totalVisitors = 0;

  const visitorBatch: Array<{
    brandId: string; visitorId: string; firstSeenAt: Date; lastSeenAt: Date;
    totalSessions: number; totalPageViews: number; totalConversions: number;
    devices: object; ipAddresses: object; channelHistory: object;
    conversionHistory: object; topPages: object;
  }> = [];

  for (let dayBack = 119; dayBack >= 0; dayBack--) {
    const dayTs = now - dayBack * 86_400_000;
    const dayDate = new Date(dayTs);
    const dow = dayDate.getUTCDay(); // 0=Sun, 6=Sat
    const isWeekend = dow === 0 || dow === 6;

    // Growth factor: day 119 (oldest) = 0.7, day 0 (today) = 1.0
    const growthFactor = 0.7 + (119 - dayBack) / 119 * 0.3;
    const weekdayMult = isWeekend ? 0.55 : 1.0;

    const baseSessionsPerDay = 2000;
    const sessionsToday = Math.round(baseSessionsPerDay * growthFactor * weekdayMult);
    const conversionsToday = Math.round((isWeekend ? 55 : 115) * growthFactor);

    // Build session + event batches for this day
    const sessionRows: Array<{
      sessionId: string; startedAt: Date; lastSeenAt: Date; pageCount: number;
      entryPage: string; referrer: string | null;
      utmSource: string | null; utmMedium: string | null;
      device: string; city: string; country: string; trackedSiteId: string;
    }> = [];

    const eventRows: Array<{
      eventType: string; pageUrl: string; timestamp: Date;
      trackedSiteId: string; sessionId: string;
    }> = [];

    for (let si = 0; si < sessionsToday; si++) {
      // Spread sessions across business hours: 7am–9pm local time
      const hourOffset = Math.floor(seeded(dayBack * 10000 + si, 1) * 14 + 7) * 3600_000;
      const minOffset = Math.floor(seeded(dayBack * 10000 + si, 2) * 60) * 60_000;
      const sessionStart = new Date(dayTs + hourOffset + minOffset - 14 * 3600_000); // adjust for UTC offset

      const ch = pick(CHANNELS, dayBack, si, 3);
      const device = pick(DEVICES, dayBack, si, 4);
      const city = pick(CITIES, dayBack, si, 5);
      const entryPage = pick(LANDING_PAGES, dayBack, si, 6);
      const pageCount = Math.floor(seeded(dayBack * 10000 + si, 7) * 5) + 1;
      const sessionDuration = pageCount * 45_000 + Math.floor(seeded(dayBack * 10000 + si, 8) * 120_000);
      const sessionEnd = new Date(sessionStart.getTime() + sessionDuration);

      const sessionId = `demo_${brand.id.slice(-6)}_${dayBack}_${si}`;
      const visitorId = `v_${brand.id.slice(-6)}_${Math.floor(si / 1.8) + dayBack * 100}`;

      sessionRows.push({
        sessionId,
        startedAt: sessionStart,
        lastSeenAt: sessionEnd,
        pageCount,
        entryPage,
        referrer: ch.medium === "organic" ? `https://www.google.com/search?q=houston+cardiologist` : ch.medium === "referral" ? `https://${ch.source}/` : null,
        utmSource: ch.source === "(direct)" ? null : ch.source,
        utmMedium: ch.medium === "(none)" ? null : ch.medium,
        device,
        city,
        country: "US",
        trackedSiteId,
      });

      // Generate page_view events for this session
      for (let pi = 0; pi < pageCount; pi++) {
        const page = pi === 0 ? entryPage : pick(PAGES, dayBack, si * 20 + pi, 9);
        const pageTs = new Date(sessionStart.getTime() + pi * 45_000);
        eventRows.push({ eventType: "page_view", pageUrl: `https://${brand.domain}${page}`, timestamp: pageTs, trackedSiteId, sessionId });
      }

      // Visitor profile accumulation (one per unique visitorId, collected across days)
      if (visitorBatch.length < 120000 && si % 2 === 0) {
        visitorBatch.push({
          brandId: body.brandId,
          visitorId,
          firstSeenAt: sessionStart,
          lastSeenAt: sessionEnd,
          totalSessions: 1,
          totalPageViews: pageCount,
          totalConversions: 0,
          devices: [{ device, browser: "Chrome", os: "Windows" }],
          ipAddresses: [],
          channelHistory: [{ channel: ch.channel, source: ch.source, medium: ch.medium, date: sessionStart.toISOString() }],
          conversionHistory: [],
          topPages: [entryPage],
        });
        totalVisitors++;
      }
    }

    // Build conversion rows for this day
    const conversionRows: Array<{
      brandId: string; visitorId: string; sessionId: string;
      conversionType: string; pageUrl: string; timestamp: Date;
      firstTouchChannel: string; lastTouchChannel: string;
    }> = [];

    for (let ci = 0; ci < conversionsToday; ci++) {
      const convHour = Math.floor(seeded(dayBack * 1000 + ci, 11) * 12 + 8) * 3600_000;
      const convTs = new Date(dayTs + convHour - 14 * 3600_000);
      const ch = pick(CHANNELS, dayBack, ci, 12);
      const convPage = pick(CONV_PAGES, dayBack, ci, 13);
      const convType = pick(CONV_TYPES, dayBack, ci, 14);
      const convSessionIdx = Math.floor(seeded(dayBack * 1000 + ci, 15) * sessionsToday);
      const sessionId = `demo_${brand.id.slice(-6)}_${dayBack}_${convSessionIdx}`;
      const visitorId = `v_${brand.id.slice(-6)}_${Math.floor(convSessionIdx / 1.8) + dayBack * 100}`;

      conversionRows.push({
        brandId: body.brandId,
        visitorId,
        sessionId,
        conversionType: convType,
        pageUrl: `https://${brand.domain}${convPage}`,
        timestamp: convTs,
        firstTouchChannel: ch.channel,
        lastTouchChannel: ch.channel,
      });
    }

    // Insert this day's data in batches
    for (let i = 0; i < sessionRows.length; i += BATCH) {
      await prisma.trackedSession.createMany({ data: sessionRows.slice(i, i + BATCH), skipDuplicates: true });
    }
    for (let i = 0; i < eventRows.length; i += BATCH) {
      await prisma.trackedEvent.createMany({ data: eventRows.slice(i, i + BATCH), skipDuplicates: true });
    }
    for (let i = 0; i < conversionRows.length; i += BATCH) {
      await prisma.siteConversion.createMany({ data: conversionRows.slice(i, i + BATCH), skipDuplicates: true });
    }

    totalSessions += sessionRows.length;
    totalEvents += eventRows.length;
    totalConversions += conversionRows.length;
  }

  // Flush visitor profiles in 5K batches
  for (let i = 0; i < visitorBatch.length; i += BATCH) {
    await prisma.visitorProfile.createMany({ data: visitorBatch.slice(i, i + BATCH), skipDuplicates: true });
  }

  console.info(`[demo-brand/seed/phase1] brand=${body.brandId} sessions=${totalSessions} events=${totalEvents} conversions=${totalConversions} visitors=${totalVisitors}`);

  return NextResponse.json({
    ok: true,
    phase: "sessions-events-conversions",
    created: { sessions: totalSessions, events: totalEvents, conversions: totalConversions, visitorProfiles: totalVisitors },
  });
}
