import "server-only";

import { prisma } from "@/lib/prisma";
import type { ComplianceAlertView } from "@/lib/compliance/types";
import { buildM7Dataset, computeM3Counters } from "@/lib/compliance/m7";
import { getDueNormativeVerifications, listRegulationChangeAlerts } from "@/lib/compliance/regulations";

export async function getM7DatasetForUser(userId: string, now = new Date()) {
  const [proposals, preferences, totalOpenLicitations] = await Promise.all([
    prisma.proposal.findMany({
      where: {
        userId,
      },
      select: {
        id: true,
        title: true,
        status: true,
        sourceLicitationId: true,
        workflowDraft: true,
        updatedAt: true,
      },
      orderBy: [{ updatedAt: "desc" }],
      take: 200,
    }),
    prisma.licitationUserPreference.findMany({
      where: {
        userId,
      },
      select: {
        status: true,
      },
    }),
    prisma.licitation.count({
      where: {
        OR: [{ isOpen: true }, { closingDate: { gte: now } }],
        municipality: {
          isActive: true,
        },
      },
    }),
  ]);

  const activeLinked = new Set(
    proposals
      .filter((item) => item.status !== "ARCHIVED" && item.sourceLicitationId)
      .map((item) => item.sourceLicitationId as string),
  ).size;

  const m3 = computeM3Counters({
    totalOpenLicitations,
    preferences,
    activeLinked,
  });

  const [dueVerifications, regulationAlerts, overdueDeliverables, disputedPayments, highSeverityCases] = await Promise.all([
    getDueNormativeVerifications(now, 7),
    listRegulationChangeAlerts(now, 30),
    prisma.contractDeliverable.findMany({
      where: {
        contract: {
          userId,
        },
        status: {
          in: ["PENDING", "OVERDUE"],
        },
        dueDate: {
          lt: now,
        },
      },
      select: {
        id: true,
        title: true,
        dueDate: true,
        contract: {
          select: {
            id: true,
            title: true,
          },
        },
      },
      orderBy: [{ dueDate: "asc" }],
      take: 50,
    }),
    prisma.contractPayment.findMany({
      where: {
        contract: {
          userId,
        },
        status: "DISPUTED",
      },
      select: {
        id: true,
        concept: true,
        paymentDate: true,
        amount: true,
        contract: {
          select: {
            id: true,
            title: true,
          },
        },
      },
      orderBy: [{ paymentDate: "desc" }],
      take: 50,
    }),
    prisma.legalCase.findMany({
      where: {
        userId,
        severity: "HIGH",
        status: {
          in: ["OPEN", "IN_PROGRESS", "ESCALATED"],
        },
      },
      select: {
        id: true,
        caseType: true,
        counterparty: true,
        openedAt: true,
      },
      orderBy: [{ openedAt: "desc" }],
      take: 50,
    }),
  ]);

  const crossModuleAlerts: ComplianceAlertView[] = [
    ...overdueDeliverables.map((item) => ({
      id: `contract-deliverable-overdue-${item.id}`,
      proposalId: null,
      licitationId: item.contract.id,
      title: `Entregable vencido: ${item.contract.title}`,
      description: item.title,
      severity: "high" as const,
      kind: "contract_deliverable_overdue" as const,
      dueAt: item.dueDate ? item.dueDate.toISOString() : null,
      createdAt: now.toISOString(),
    })),
    ...disputedPayments.map((item) => ({
      id: `contract-payment-disputed-${item.id}`,
      proposalId: null,
      licitationId: item.contract.id,
      title: `Pago en disputa: ${item.contract.title}`,
      description: `${item.concept} (${Number(item.amount).toLocaleString("es-MX")} MXN)`,
      severity: "high" as const,
      kind: "contract_payment_disputed" as const,
      dueAt: item.paymentDate.toISOString(),
      createdAt: now.toISOString(),
    })),
    ...highSeverityCases.map((item) => ({
      id: `legal-high-severity-${item.id}`,
      proposalId: null,
      licitationId: null,
      title: `Caso legal alta severidad: ${item.caseType}`,
      description: `Contraparte: ${item.counterparty}`,
      severity: "high" as const,
      kind: "legal_case_high_severity" as const,
      dueAt: item.openedAt.toISOString(),
      createdAt: now.toISOString(),
    })),
  ];

  return buildM7Dataset({
    proposals,
    m3,
    dueVerifications,
    externalAlerts: [...regulationAlerts, ...crossModuleAlerts],
    now,
  });
}
