import "server-only";

import type { Prisma } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { buildEscalationProgress } from "@/lib/legal/diagnosis";
import type {
  LegalCaseView,
  LegalDirectoryEntityView,
  LegalDirectoryFilters,
  LegalKpiSnapshot,
} from "@/lib/legal/types";

function toNumber(value: Prisma.Decimal | number | string | null | undefined) {
  if (value === null || value === undefined) {
    return null;
  }

  const numeric = typeof value === "number" ? value : Number(value);
  return Number.isFinite(numeric) ? Number(numeric) : null;
}

function mapCase(row: {
  id: string;
  contractId: string | null;
  caseType: "CONTRACT_BREACH" | "PAYMENT_RETENTION" | "UNJUST_SANCTION" | "CONTRACT_DISPUTE";
  severity: "LOW" | "MEDIUM" | "HIGH";
  counterparty: string;
  description: string;
  amountAtRisk: Prisma.Decimal | null;
  status: "OPEN" | "IN_PROGRESS" | "ESCALATED" | "RESOLVED" | "CLOSED";
  openedAt: Date;
  resolvedAt: Date | null;
  createdAt: Date;
  updatedAt: Date;
}): LegalCaseView {
  return {
    id: row.id,
    contractId: row.contractId,
    caseType: row.caseType,
    severity: row.severity,
    counterparty: row.counterparty,
    description: row.description,
    amountAtRisk: toNumber(row.amountAtRisk),
    status: row.status,
    openedAt: row.openedAt.toISOString(),
    resolvedAt: row.resolvedAt ? row.resolvedAt.toISOString() : null,
    createdAt: row.createdAt.toISOString(),
    updatedAt: row.updatedAt.toISOString(),
  };
}

export async function listLegalCasesForUser(userId: string) {
  const rows = await prisma.legalCase.findMany({
    where: { userId },
    orderBy: [{ updatedAt: "desc" }],
    take: 200,
  });

  return rows.map((row) => mapCase(row));
}

export function computeLegalKpis(cases: LegalCaseView[]): LegalKpiSnapshot {
  let amountAtRisk = 0;

  for (const item of cases) {
    if (item.amountAtRisk) {
      amountAtRisk += item.amountAtRisk;
    }
  }

  return {
    openCases: cases.filter((item) => item.status === "OPEN" || item.status === "IN_PROGRESS" || item.status === "ESCALATED").length,
    highSeverityCases: cases.filter((item) => item.severity === "HIGH" && item.status !== "CLOSED" && item.status !== "RESOLVED").length,
    amountAtRisk: Number(amountAtRisk.toFixed(2)),
    resolvedCases: cases.filter((item) => item.status === "RESOLVED" || item.status === "CLOSED").length,
  };
}

export async function getLegalKpisForUser(userId: string) {
  const cases = await listLegalCasesForUser(userId);
  return computeLegalKpis(cases);
}

export async function getEscalationForCase(userId: string, caseId: string) {
  const legalCase = await prisma.legalCase.findFirst({
    where: {
      id: caseId,
      userId,
    },
    select: {
      id: true,
      escalationLogs: {
        orderBy: [{ updatedAt: "desc" }],
        select: {
          routeStepKey: true,
          completedAt: true,
          notes: true,
        },
      },
    },
  });

  if (!legalCase) {
    return null;
  }

  return {
    caseId: legalCase.id,
    steps: buildEscalationProgress(legalCase.escalationLogs),
  };
}

export async function listLegalDirectory(filters: LegalDirectoryFilters = {}): Promise<LegalDirectoryEntityView[]> {
  const where: Prisma.LegalDirectoryEntityWhereInput = {
    isActive: true,
  };

  if (filters.jurisdictionLevel) {
    where.jurisdictionLevel = filters.jurisdictionLevel;
  }

  if (filters.stateCode) {
    where.stateCode = filters.stateCode.toUpperCase();
  }

  if (filters.q) {
    where.OR = [
      { name: { contains: filters.q, mode: "insensitive" } },
      { websiteUrl: { contains: filters.q, mode: "insensitive" } },
    ];
  }

  const rows = await prisma.legalDirectoryEntity.findMany({
    where,
    orderBy: [{ jurisdictionLevel: "asc" }, { name: "asc" }],
    take: 400,
  });

  return rows.map((row) => ({
    id: row.id,
    jurisdictionLevel: row.jurisdictionLevel,
    name: row.name,
    scopeTags: Array.isArray(row.scopeTagsJson) ? row.scopeTagsJson.filter((item): item is string => typeof item === "string") : [],
    websiteUrl: row.websiteUrl,
    phone: row.phone,
    email: row.email,
    stateCode: row.stateCode,
    municipalityCode: row.municipalityCode,
  }));
}
