import { NextResponse } from "next/server";
import { DepartmentKey, MarketingInitiativeType } from "@prisma/client";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { canManageMarketing, mapMarketingInitiative } from "@/lib/marketing/persistence";
import { marketingLocations } from "@/lib/marketing/mock";

type CreateInitiativeBody = {
  name?: string;
  type?: string;
  isGlobal?: boolean;
  metricSelection?: {
    score?: boolean;
    tickets?: boolean;
    revenue?: boolean;
  };
  locationIds?: string[];
  dueDate?: string;
};

const ALLOWED_TYPES = new Set<MarketingInitiativeType>([
  MarketingInitiativeType.evento,
  MarketingInitiativeType.campania,
  MarketingInitiativeType.cambio,
  MarketingInitiativeType.implementacion,
  MarketingInitiativeType.otro,
]);

function parseDate(value: string | undefined): Date | null {
  if (!value) {
    return null;
  }

  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    return null;
  }

  return parsed;
}

export async function POST(request: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canManageMarketing(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owners or marketing leaders can create initiatives." }, { status: 403 });
  }

  const body = (await request.json()) as CreateInitiativeBody;
  const name = body.name?.trim() || "Nueva iniciativa";
  const type = (body.type as MarketingInitiativeType | undefined) ?? MarketingInitiativeType.otro;
  const isGlobal = Boolean(body.isGlobal);
  const metricSelection = {
    score: body.metricSelection?.score ?? true,
    tickets: body.metricSelection?.tickets ?? false,
    revenue: body.metricSelection?.revenue ?? false,
  };
  const dueDate = parseDate(body.dueDate) ?? new Date(Date.now() + 14 * 24 * 60 * 60 * 1000);

  if (!ALLOWED_TYPES.has(type)) {
    return NextResponse.json({ error: "Invalid initiative type." }, { status: 400 });
  }

  if (!metricSelection.score && !metricSelection.tickets && !metricSelection.revenue) {
    return NextResponse.json({ error: "At least one KPI target must be enabled." }, { status: 400 });
  }

  const locationSet = new Set(marketingLocations.map((location) => location.id));
  const requestedLocationIds = (body.locationIds ?? []).filter((value) => locationSet.has(value));
  const locationIds = isGlobal ? [] : requestedLocationIds.length > 0 ? requestedLocationIds : [marketingLocations[0].id];

  const initiative = await prisma.marketingInitiative.create({
    data: {
      department: DepartmentKey.marketing,
      name,
      type,
      status: "planning",
      isGlobal,
      trackScore: metricSelection.score,
      trackTickets: metricSelection.tickets,
      trackRevenue: metricSelection.revenue,
      ownerId: session.user.id,
      dueDate,
      updatedById: session.user.id,
      updatedByName: session.user.name ?? session.user.email,
      attributionChannel: null,
      attributionPageId: null,
      attributionCampaign: null,
      attributionStart: null,
      attributionEnd: null,
      autoActual: null,
      autoTicketsActual: null,
      autoRevenueActual: null,
      autoUpdatedAt: null,
      ...(locationIds.length > 0
        ? {
            locations: {
              createMany: {
                data: locationIds.map((locationId) => ({ locationId })),
              },
            },
          }
        : {}),
      edits: {
        create: {
          editedById: session.user.id,
          editedByName: session.user.name ?? session.user.email ?? "Usuario",
          summary: "Creación de iniciativa",
        },
      },
    },
    include: {
      contributors: true,
      locations: true,
      evidenceLinks: true,
      tasks: {
        include: { evidenceLinks: true },
      },
      milestones: {
        include: {
          checkpoints: {
            orderBy: { createdAt: "asc" },
          },
        },
        orderBy: [{ sortOrder: "asc" }, { dueDate: "asc" }],
      },
    },
  });

  return NextResponse.json({
    ok: true,
    initiative: mapMarketingInitiative(initiative),
  });
}
