/**
 * POST /api/email-reports/schedules — create a new schedule
 * GET  /api/email-reports/schedules?brandId=X — list schedules
 */

import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { computeNextSendAt } from "@/lib/services/email-sender";

export const dynamic = "force-dynamic";

const VALID_FREQ = new Set(["daily", "weekly", "biweekly", "monthly"]);
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

async function authBrand(brandId: string, userId: string) {
  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand) return { error: "Brand not found" as const, status: 404 };
  if (!brand.organization.memberships.some((m) => m.userId === userId)) {
    return { error: "Access denied" as const, status: 403 };
  }
  return { brand };
}

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

  const body = await req.json().catch(() => null) as Record<string, unknown> | null;
  if (!body) return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });

  const brandId = String(body.brandId || "");
  const resolved = await authBrand(brandId, user.id);
  if ("error" in resolved) return NextResponse.json({ error: resolved.error }, { status: resolved.status });

  const frequency = String(body.frequency || "weekly");
  if (!VALID_FREQ.has(frequency)) return NextResponse.json({ error: "Invalid frequency" }, { status: 400 });

  const recipients = Array.isArray(body.recipients) ? (body.recipients as string[]).filter((e) => EMAIL_RE.test(e)) : [];
  if (recipients.length === 0) return NextResponse.json({ error: "At least one valid email required" }, { status: 400 });

  const name = String(body.name || `${frequency.charAt(0).toUpperCase() + frequency.slice(1)} Report`);
  const dayOfWeek = typeof body.dayOfWeek === "number" ? Math.max(0, Math.min(6, body.dayOfWeek)) : 1;
  const dayOfMonth = typeof body.dayOfMonth === "number" ? Math.max(1, Math.min(28, body.dayOfMonth)) : 1;
  const timeOfDay = typeof body.timeOfDay === "string" && /^\d{2}:\d{2}$/.test(body.timeOfDay) ? body.timeOfDay : "08:00";
  // site_tag included in the server-side default so a programmatic
  // schedule creation (cron-created / API-integration / legacy row
  // re-save) picks it up without requiring the client to send an
  // explicit sections array. Matches the modal's default selection.
  const sections = Array.isArray(body.sections) ? (body.sections as string[]) : ["gsc", "ga4", "site_tag", "audit", "rank", "conversions"];
  const nextSendAt = computeNextSendAt(frequency, timeOfDay, dayOfWeek, dayOfMonth);

  const schedule = await prisma.emailReportSchedule.create({
    data: {
      brandId,
      name,
      frequency,
      dayOfWeek: frequency === "weekly" || frequency === "biweekly" ? dayOfWeek : null,
      dayOfMonth: frequency === "monthly" ? dayOfMonth : null,
      timeOfDay,
      recipients,
      sections,
      includeAiAnalysis: body.includeAiAnalysis !== false,
      includeCompetitorScan: !!body.includeCompetitorScan,
      includeMarketInsights: !!body.includeMarketInsights,
      nextSendAt,
    },
  });

  return NextResponse.json({ schedule });
}

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

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

  const resolved = await authBrand(brandId, user.id);
  if ("error" in resolved) return NextResponse.json({ error: resolved.error }, { status: resolved.status });

  const schedules = await prisma.emailReportSchedule.findMany({
    where: { brandId },
    orderBy: { createdAt: "desc" },
    include: { _count: { select: { sentReports: true } } },
  });

  return NextResponse.json({ schedules });
}
