import type { LegalCaseSeverity, LegalCaseType } from "@prisma/client";
import type {
  DiagnosisAnswers,
  DiagnosisRecommendation,
  EscalationRouteStep,
  EscalationStepProgress,
  LegalTemplateKey,
} from "@/lib/legal/types";

export const ESCALATION_ROUTE_CATALOG: EscalationRouteStep[] = [
  {
    key: "formal_requirement",
    title: "Requerimiento formal",
    estimatedWindow: "3 a 7 dias habiles",
    checklist: [
      "Integrar contrato, anexos y evidencia de incumplimiento.",
      "Emitir requerimiento con monto/obligacion precisa.",
      "Registrar acuse o constancia de notificacion.",
    ],
    requiresLawyer: false,
    dependsOn: null,
  },
  {
    key: "administrative_conciliation",
    title: "Conciliacion administrativa",
    estimatedWindow: "1 a 3 semanas",
    checklist: [
      "Solicitar mesa de conciliacion ante autoridad competente.",
      "Preparar posicion de negociacion y alternativas.",
      "Documentar minutas y compromisos por escrito.",
    ],
    requiresLawyer: false,
    dependsOn: "formal_requirement",
  },
  {
    key: "oic_complaint",
    title: "Queja ante OIC",
    estimatedWindow: "2 a 6 semanas",
    checklist: [
      "Preparar relato cronologico y pruebas.",
      "Identificar servidor publico o unidad responsable.",
      "Presentar queja con firma y anexos.",
    ],
    requiresLawyer: true,
    dependsOn: "administrative_conciliation",
  },
  {
    key: "sfp_or_state_challenge",
    title: "Inconformidad ante SFP u organo estatal",
    estimatedWindow: "3 a 8 semanas",
    checklist: [
      "Confirmar causal de inconformidad aplicable.",
      "Integrar expediente con evidencia validada.",
      "Presentar escrito y dar seguimiento a prevenciones.",
    ],
    requiresLawyer: true,
    dependsOn: "oic_complaint",
  },
  {
    key: "jurisdictional_path",
    title: "Via jurisdiccional",
    estimatedWindow: "3 a 12 meses",
    checklist: [
      "Definir tribunal/instancia competente.",
      "Preparar demanda y pruebas tecnicas/periciales.",
      "Controlar terminos procesales con agenda legal.",
    ],
    requiresLawyer: true,
    dependsOn: "sfp_or_state_challenge",
  },
];

function normalizeString(value: unknown) {
  return typeof value === "string" ? value.trim().toLowerCase() : "";
}

function toCaseType(value: DiagnosisAnswers["breachType"]): LegalCaseType {
  if (value === "payment_retention") {
    return "PAYMENT_RETENTION";
  }

  if (value === "unjust_sanction") {
    return "UNJUST_SANCTION";
  }

  if (value === "contract_dispute") {
    return "CONTRACT_DISPUTE";
  }

  return "CONTRACT_BREACH";
}

function inferSeverity(answers: DiagnosisAnswers): LegalCaseSeverity {
  let score = 0;

  if (answers.urgency === "high") {
    score += 2;
  }

  if (answers.amountAtRisk && answers.amountAtRisk >= 500_000) {
    score += 2;
  } else if (answers.amountAtRisk && answers.amountAtRisk >= 100_000) {
    score += 1;
  }

  if (answers.processStage === "trial" || answers.processStage === "ongoing_claim") {
    score += 2;
  }

  if (answers.evidenceLevel === "none") {
    score += 1;
  }

  if (score >= 4) {
    return "HIGH";
  }

  if (score >= 2) {
    return "MEDIUM";
  }

  return "LOW";
}

function inferTemplates(caseType: LegalCaseType): LegalTemplateKey[] {
  if (caseType === "PAYMENT_RETENTION") {
    return ["payment_release_request", "general_delivery_record"];
  }

  if (caseType === "UNJUST_SANCTION") {
    return ["sanctions_challenge_resource", "breach_disagreement_letter"];
  }

  if (caseType === "CONTRACT_DISPUTE") {
    return ["breach_disagreement_letter", "general_delivery_record"];
  }

  return ["breach_disagreement_letter", "general_delivery_record"];
}

function inferRoute(answers: DiagnosisAnswers, severity: LegalCaseSeverity): EscalationRouteStep[] {
  const baseSteps = [...ESCALATION_ROUTE_CATALOG];

  if (severity === "LOW" && answers.processStage !== "trial") {
    return baseSteps.slice(0, 2);
  }

  if (severity === "MEDIUM") {
    return baseSteps.slice(0, 4);
  }

  return baseSteps;
}

export function parseDiagnosisAnswers(raw: Record<string, unknown>): DiagnosisAnswers {
  const breachTypeRaw = normalizeString(raw.breachType);
  const processStageRaw = normalizeString(raw.processStage);
  const evidenceLevelRaw = normalizeString(raw.evidenceLevel);
  const urgencyRaw = normalizeString(raw.urgency);
  const objectiveRaw = normalizeString(raw.objective);

  const amountAtRiskCandidate = raw.amountAtRisk;
  const amountAtRisk =
    typeof amountAtRiskCandidate === "number"
      ? Number.isFinite(amountAtRiskCandidate)
        ? amountAtRiskCandidate
        : null
      : typeof amountAtRiskCandidate === "string"
        ? Number.parseFloat(amountAtRiskCandidate.replace(/[^\d.,-]/g, "").replace(/,/g, "."))
        : null;

  return {
    breachType:
      breachTypeRaw === "payment_retention" || breachTypeRaw === "unjust_sanction" || breachTypeRaw === "contract_dispute" || breachTypeRaw === "contract_breach"
        ? breachTypeRaw
        : null,
    processStage:
      processStageRaw === "none" ||
      processStageRaw === "informal_notice" ||
      processStageRaw === "formal_notice" ||
      processStageRaw === "ongoing_claim" ||
      processStageRaw === "trial"
        ? processStageRaw
        : null,
    evidenceLevel:
      evidenceLevelRaw === "none" || evidenceLevelRaw === "basic" || evidenceLevelRaw === "solid" || evidenceLevelRaw === "robust"
        ? evidenceLevelRaw
        : null,
    urgency: urgencyRaw === "low" || urgencyRaw === "medium" || urgencyRaw === "high" ? urgencyRaw : null,
    objective: objectiveRaw === "payment" || objectiveRaw === "correction" || objectiveRaw === "challenge" || objectiveRaw === "mediation" ? objectiveRaw : null,
    amountAtRisk: amountAtRisk && Number.isFinite(amountAtRisk) ? Number(amountAtRisk.toFixed(2)) : null,
  };
}

export function evaluateDiagnosis(answers: DiagnosisAnswers): DiagnosisRecommendation {
  const suggestedCaseType = toCaseType(answers.breachType);
  const suggestedSeverity = inferSeverity(answers);
  const suggestedRoute = inferRoute(answers, suggestedSeverity);
  const recommendedTemplates = inferTemplates(suggestedCaseType);

  const notes = ["Clasificacion automatica con enfoque conservador."];

  if (!answers.evidenceLevel || answers.evidenceLevel === "none") {
    notes.push("Falta evidencia suficiente: requiere validacion legal.");
  }

  if (suggestedSeverity === "HIGH") {
    notes.push("Caso de alta severidad: escalar con asesoria juridica.");
  }

  return {
    suggestedSeverity,
    suggestedCaseType,
    suggestedRoute,
    recommendedTemplates,
    notes,
  };
}

export function buildEscalationProgress(logs: Array<{ routeStepKey: string; completedAt: Date | null; notes: string }>): EscalationStepProgress[] {
  const logMap = new Map(logs.map((item) => [item.routeStepKey, item]));

  return ESCALATION_ROUTE_CATALOG.map((step) => {
    const current = logMap.get(step.key);
    const dependsOn = step.dependsOn ? logMap.get(step.dependsOn) : null;

    return {
      ...step,
      completedAt: current?.completedAt ? current.completedAt.toISOString() : null,
      notes: current?.notes ?? "",
      isBlocked: Boolean(step.dependsOn && !dependsOn?.completedAt),
    };
  });
}
