/**
 * GET  /api/paid-media/attribution?brandId=X[&range=28d]
 * POST /api/paid-media/attribution?brandId=X — triggers rebuild
 */
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getCurrentUser } from "@/lib/auth";
import { buildAttributionPaths } from "@/lib/services/attribution";
import { getAssistedConversions } from "@/lib/services/paid-media-metrics";
import { planHasFeature, resolveEffectivePlan } from "@/lib/plan-config";
import type { PlanId } from "@/lib/plan-config";

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

async function verifyAccess(req: Request) {
  const user = await getCurrentUser();
  if (!user) return { error: "Unauthorized", status: 401 } as const;
  const brandId = new URL(req.url).searchParams.get("brandId");
  if (!brandId) return { error: "brandId required", status: 400 } as const;
  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand || !brand.organization.memberships.some((m) => m.userId === user.id))
    return { error: "Access denied", status: 403 } as const;
  const effectivePlan = resolveEffectivePlan({ plan: (brand.plan as PlanId) ?? "trial", planExpiresAt: brand.planExpiresAt });
  if (!planHasFeature({ plan: effectivePlan }, "paid_media")) {
    return { error: "Paid Media requires an Agency plan or higher", requiredPlan: "agency", status: 403 } as const;
  }
  return { brandId } as const;
}

export async function GET(req: Request) {
  const auth = await verifyAccess(req);
  if ("error" in auth) return NextResponse.json({ error: auth.error }, { status: auth.status });
  const { brandId } = auth;
  const days = parseInt(new URL(req.url).searchParams.get("range") ?? "28d") || 28;
  const since = new Date(Date.now() - days * 86_400_000);

  const [paths, assisted] = await Promise.all([
    prisma.attributionPath.findMany({
      where: { brandId, createdAt: { gte: since } },
      orderBy: { createdAt: "desc" },
      take: 500,
    }),
    getAssistedConversions(brandId, since),
  ]);

  const firstTouchSummary: Record<string, { conversions: number; revenue: number }> = {};
  const lastTouchSummary: Record<string, { conversions: number; revenue: number }> = {};
  const convertingSummary: Record<string, { conversions: number; revenue: number }> = {};
  for (const p of paths) {
    const rev = p.conversionValue ?? 0;
    for (const [map, ch] of [
      [firstTouchSummary, p.firstTouchChannel ?? "Direct"],
      [lastTouchSummary, p.lastTouchChannel ?? "Direct"],
      [convertingSummary, p.convertingChannel ?? "Direct"],
    ] as const) {
      if (!map[ch]) (map as Record<string, { conversions: number; revenue: number }>)[ch] = { conversions: 0, revenue: 0 };
      (map as Record<string, { conversions: number; revenue: number }>)[ch].conversions++;
      (map as Record<string, { conversions: number; revenue: number }>)[ch].revenue += rev;
    }
  }

  const avgTouchpoints = paths.length > 0
    ? Math.round((paths.reduce((s: number, p) => s + p.touchpointCount, 0) / paths.length) * 10) / 10
    : 0;
  const avgDaysToConvert = paths.length > 0
    ? Math.round((paths.reduce((s: number, p) => s + p.daysBetweenFirstAndConversion, 0) / paths.length) * 10) / 10
    : 0;

  return NextResponse.json({
    totalPaths: paths.length,
    avgTouchpoints,
    avgDaysToConvert,
    assisted,
    firstTouchSummary,
    lastTouchSummary,
    convertingSummary,
    paths: paths.slice(0, 50).map((p) => ({
      conversionId: p.conversionId,
      visitorId: p.visitorId,
      conversionType: p.conversionType,
      conversionValue: p.conversionValue,
      touchpoints: p.touchpoints,
      touchpointCount: p.touchpointCount,
      firstTouchChannel: p.firstTouchChannel,
      lastTouchChannel: p.lastTouchChannel,
      convertingChannel: p.convertingChannel,
      daysBetweenFirstAndConversion: p.daysBetweenFirstAndConversion,
      createdAt: p.createdAt,
    })),
  });
}

export async function POST(req: Request) {
  const auth = await verifyAccess(req);
  if ("error" in auth) return NextResponse.json({ error: auth.error }, { status: auth.status });
  const result = await buildAttributionPaths(auth.brandId);
  return NextResponse.json(result);
}
