"use client";

import Link from "next/link";
import { useMemo, useState } from "react";
import type {
  ContractCreateInput,
  ContractDeliverableView,
  ContractKpiSnapshot,
  ContractPaymentView,
  ContractRecordView,
} from "@/lib/contracts/types";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Dialog } from "@/components/ui/dialog";
import { Tabs } from "@/components/ui/tabs";

type ContractsManagementViewProps = {
  initialContracts: ContractRecordView[];
  initialKpis: ContractKpiSnapshot;
  proposalPdfOptions: Array<{
    proposalId: string;
    proposalTitle: string;
    documentId: string;
    fileName: string;
    createdAt: string;
  }>;
};

type ApiPayload = {
  ok?: boolean;
  error?: string;
  contracts?: ContractRecordView[];
  contract?: ContractRecordView | null;
  document?: {
    id: string;
    contractId: string;
    fileName: string;
    filePath: string;
    mimeType: string;
    sizeBytes: number;
    checksumSha256: string | null;
    kind: ContractRecordView["documents"][number]["kind"];
    createdAt: string;
  };
  kpis?: ContractKpiSnapshot;
  extraction?: {
    warnings?: Array<{ code: string; message: string }>;
    fields?: {
      title?: string | null;
      counterpartyEntity?: string | null;
      contractNumber?: string | null;
      contractType?: string | null;
      totalAmount?: number | null;
    };
  };
};

function formatDate(value: string | null) {
  if (!value) {
    return "Sin fecha";
  }

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

  return parsed.toLocaleDateString("es-MX", {
    year: "numeric",
    month: "short",
    day: "2-digit",
  });
}

function formatCurrency(amount: number, currency = "MXN") {
  return new Intl.NumberFormat("es-MX", {
    style: "currency",
    currency,
    maximumFractionDigits: 2,
  }).format(amount);
}

function formatDateTime(value: string) {
  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    return "Sin fecha";
  }

  return parsed.toLocaleString("es-MX", {
    year: "numeric",
    month: "short",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function formatFileSize(bytes: number) {
  if (!Number.isFinite(bytes) || bytes <= 0) {
    return "N/D";
  }

  if (bytes < 1024) {
    return `${bytes} B`;
  }

  if (bytes < 1024 * 1024) {
    return `${(bytes / 1024).toFixed(1)} KB`;
  }

  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function contractDocumentKindLabel(kind: ContractRecordView["documents"][number]["kind"]) {
  if (kind === "SIGNED_CONTRACT") {
    return "Contrato firmado";
  }

  if (kind === "ADDENDUM") {
    return "Convenio / adenda";
  }

  if (kind === "DELIVERABLE_EVIDENCE") {
    return "Evidencia de entregable";
  }

  if (kind === "PAYMENT_EVIDENCE") {
    return "Evidencia de pago";
  }

  return "Otro";
}

function statusTone(status: ContractRecordView["status"]) {
  if (status === "ACTIVE") {
    return "border-[#bce5d1] bg-[#ebf9f1] text-[#1e8b63]";
  }

  if (status === "COMPLETED") {
    return "border-[#c7d8f5] bg-[#ecf3ff] text-[#2c59a8]";
  }

  if (status === "PAUSED") {
    return "border-[#f0dfb8] bg-[#fff9ea] text-[#946807]";
  }

  return "border-[#e6c9cf] bg-[#fff2f4] text-[#b04a58]";
}

export function ContractsManagementView({ initialContracts, initialKpis, proposalPdfOptions }: ContractsManagementViewProps) {
  const [contracts, setContracts] = useState<ContractRecordView[]>(initialContracts);
  const [kpis, setKpis] = useState<ContractKpiSnapshot>(initialKpis);
  const [isBusy, setIsBusy] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [extractionSummary, setExtractionSummary] = useState<string | null>(null);

  const [uploadContractId, setUploadContractId] = useState("");
  const [uploadFile, setUploadFile] = useState<File | null>(null);
  const [proposalSourceId, setProposalSourceId] = useState(proposalPdfOptions[0]?.proposalId ?? "");
  const [evidenceContractId, setEvidenceContractId] = useState("");
  const [evidenceKind, setEvidenceKind] = useState<ContractRecordView["documents"][number]["kind"]>("SIGNED_CONTRACT");
  const [evidenceFile, setEvidenceFile] = useState<File | null>(null);

  const [newContract, setNewContract] = useState<ContractCreateInput>({
    sourceProposalId: null,
    title: "",
    counterpartyEntity: "",
    contractNumber: null,
    contractType: "General",
    startDate: null,
    endDate: null,
    totalAmount: null,
    currency: "MXN",
    status: "ACTIVE",
    description: "",
  });

  const [newDeliverable, setNewDeliverable] = useState({
    contractId: "",
    title: "",
    dueDate: "",
    amountLinked: "",
    notes: "",
  });

  const [newPayment, setNewPayment] = useState({
    contractId: "",
    amount: "",
    paymentDate: "",
    invoiceNumber: "",
    concept: "",
    status: "REGISTERED",
  });

  const deliverables = useMemo(() => {
    const rows: Array<ContractDeliverableView & { contractTitle: string; contractId: string }> = [];

    for (const contract of contracts) {
      for (const item of contract.deliverables) {
        rows.push({
          ...item,
          contractTitle: contract.title,
          contractId: contract.id,
        });
      }
    }

    return rows.sort((a, b) => {
      const left = a.dueDate ? new Date(a.dueDate).getTime() : Number.POSITIVE_INFINITY;
      const right = b.dueDate ? new Date(b.dueDate).getTime() : Number.POSITIVE_INFINITY;
      return left - right;
    });
  }, [contracts]);

  const payments = useMemo(() => {
    const rows: Array<ContractPaymentView & { contractTitle: string; currency: string }> = [];

    for (const contract of contracts) {
      for (const item of contract.payments) {
        rows.push({
          ...item,
          contractTitle: contract.title,
          currency: contract.currency,
        });
      }
    }

    return rows.sort((a, b) => new Date(b.paymentDate).getTime() - new Date(a.paymentDate).getTime());
  }, [contracts]);

  const selectedProposalPdfOption = useMemo(
    () => proposalPdfOptions.find((item) => item.proposalId === proposalSourceId) ?? null,
    [proposalPdfOptions, proposalSourceId],
  );

  const hasContractsWithoutProposalTrace = useMemo(
    () => contracts.some((item) => !item.sourceProposalId),
    [contracts],
  );

  async function reloadData() {
    const [contractsResponse, kpisResponse] = await Promise.all([fetch("/api/contracts"), fetch("/api/contracts/kpis")]);

    const contractsPayload = (await contractsResponse.json().catch(() => ({}))) as ApiPayload;
    const kpisPayload = (await kpisResponse.json().catch(() => ({}))) as ApiPayload;

    if (contractsResponse.ok && contractsPayload.ok && contractsPayload.contracts) {
      setContracts(contractsPayload.contracts);
    }

    if (kpisResponse.ok && kpisPayload.ok && kpisPayload.kpis) {
      setKpis(kpisPayload.kpis);
    }
  }

  async function createContract() {
    setErrorMessage(null);
    setMessage(null);
    setIsBusy(true);

    try {
      const response = await fetch("/api/contracts", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          ...newContract,
          totalAmount: newContract.totalAmount === null ? null : Number(newContract.totalAmount),
        }),
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;

      if (!response.ok || !payload.ok) {
        setErrorMessage(payload.error ?? "No fue posible crear el contrato.");
        return;
      }

      setMessage("Contrato creado correctamente.");
      setNewContract({
        sourceProposalId: null,
        title: "",
        counterpartyEntity: "",
        contractNumber: null,
        contractType: "General",
        startDate: null,
        endDate: null,
        totalAmount: null,
        currency: "MXN",
        status: "ACTIVE",
        description: "",
      });
      await reloadData();
    } catch {
      setErrorMessage("No fue posible crear el contrato.");
    } finally {
      setIsBusy(false);
    }
  }

  async function updateContractStatus(contractId: string, status: ContractRecordView["status"]) {
    setErrorMessage(null);
    setMessage(null);

    const response = await fetch(`/api/contracts/${encodeURIComponent(contractId)}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ status }),
    });

    const payload = (await response.json().catch(() => ({}))) as ApiPayload;

    if (!response.ok || !payload.ok) {
      setErrorMessage(payload.error ?? "No fue posible actualizar el estado.");
      return;
    }

    setMessage("Estado de contrato actualizado.");
    await reloadData();
  }

  async function performExtraction(formData: FormData, successMessage: string) {
    setErrorMessage(null);
    setMessage(null);
    setExtractionSummary(null);
    setIsBusy(true);

    try {
      const response = await fetch("/api/contracts/extract", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;

      if (!response.ok || !payload.ok) {
        setErrorMessage(payload.error ?? "No fue posible analizar el contrato.");
        return false;
      }

      const extraction = payload.extraction;
      const fields = extraction?.fields;
      const warningText = extraction?.warnings?.map((item) => item.message).join(" | ") ?? "";
      setExtractionSummary(
        [
          fields?.title ? `Titulo: ${fields.title}` : "",
          fields?.counterpartyEntity ? `Entidad: ${fields.counterpartyEntity}` : "",
          fields?.contractNumber ? `Numero: ${fields.contractNumber}` : "",
          fields?.contractType ? `Tipo: ${fields.contractType}` : "",
          fields?.totalAmount ? `Monto: ${fields.totalAmount}` : "",
          warningText ? `Notas: ${warningText}` : "",
        ]
          .filter(Boolean)
          .join(" • "),
      );

      setMessage(successMessage);
      await reloadData();
      return true;
    } catch {
      setErrorMessage("No fue posible analizar el contrato.");
      return false;
    } finally {
      setIsBusy(false);
    }
  }

  async function submitExtraction() {
    const currentFile = uploadFile;
    if (!currentFile) {
      setErrorMessage("Selecciona un PDF para extraer.");
      return;
    }

    const formData = new FormData();
    formData.append("file", currentFile);

    if (uploadContractId) {
      formData.append("contractId", uploadContractId);
    }

    const ok = await performExtraction(formData, "Contrato analizado y guardado.");
    if (ok) {
      setUploadFile(null);
      setUploadContractId("");
    }
  }

  async function submitExtractionFromProposal() {
    if (!proposalSourceId) {
      setErrorMessage("Selecciona una propuesta con PDF para continuar.");
      return;
    }

    const formData = new FormData();
    formData.append("sourceProposalId", proposalSourceId);

    if (uploadContractId) {
      formData.append("contractId", uploadContractId);
    }

    const ok = await performExtraction(formData, "Contrato analizado usando PDF de propuesta (M5).");
    if (ok) {
      setUploadFile(null);
    }
  }

  async function uploadContractEvidence() {
    if (!evidenceContractId) {
      setErrorMessage("Selecciona un contrato para adjuntar evidencia.");
      return;
    }

    if (!evidenceFile) {
      setErrorMessage("Selecciona un archivo PDF para adjuntar evidencia.");
      return;
    }

    setIsBusy(true);
    setErrorMessage(null);
    setMessage(null);

    try {
      const formData = new FormData();
      formData.append("contractId", evidenceContractId);
      formData.append("kind", evidenceKind);
      formData.append("file", evidenceFile);

      const response = await fetch("/api/contracts/upload", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;
      if (!response.ok || !payload.ok || !payload.document) {
        setErrorMessage(payload.error ?? "No fue posible adjuntar el documento al contrato.");
        return;
      }

      setMessage("Documento adjuntado al contrato.");
      setEvidenceFile(null);
      await reloadData();
    } catch {
      setErrorMessage("No fue posible adjuntar el documento al contrato.");
    } finally {
      setIsBusy(false);
    }
  }

  async function deleteContractDocument(contractId: string, documentId: string) {
    if (!window.confirm("Se eliminara este documento del contrato. Deseas continuar?")) {
      return;
    }

    setErrorMessage(null);
    setMessage(null);
    setIsBusy(true);

    try {
      const response = await fetch(`/api/contracts/${encodeURIComponent(contractId)}/documents/${encodeURIComponent(documentId)}`, {
        method: "DELETE",
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;
      if (!response.ok || !payload.ok) {
        setErrorMessage(payload.error ?? "No fue posible eliminar el documento.");
        return;
      }

      setMessage("Documento eliminado.");
      await reloadData();
    } catch {
      setErrorMessage("No fue posible eliminar el documento.");
    } finally {
      setIsBusy(false);
    }
  }

  async function createDeliverable() {
    if (!newDeliverable.contractId) {
      setErrorMessage("Selecciona un contrato para el entregable.");
      return;
    }

    setErrorMessage(null);
    setMessage(null);
    setIsBusy(true);

    try {
      const response = await fetch(`/api/contracts/${encodeURIComponent(newDeliverable.contractId)}/deliverables`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          title: newDeliverable.title,
          dueDate: newDeliverable.dueDate ? new Date(newDeliverable.dueDate).toISOString() : null,
          amountLinked: newDeliverable.amountLinked ? Number(newDeliverable.amountLinked) : null,
          notes: newDeliverable.notes,
        }),
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;

      if (!response.ok || !payload.ok) {
        setErrorMessage(payload.error ?? "No fue posible crear el entregable.");
        return;
      }

      setMessage("Entregable registrado.");
      setNewDeliverable({
        contractId: "",
        title: "",
        dueDate: "",
        amountLinked: "",
        notes: "",
      });
      await reloadData();
    } catch {
      setErrorMessage("No fue posible crear el entregable.");
    } finally {
      setIsBusy(false);
    }
  }

  async function updateDeliverableStatus(deliverableId: string, status: ContractDeliverableView["status"]) {
    setErrorMessage(null);

    const response = await fetch(`/api/deliverables/${encodeURIComponent(deliverableId)}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ status }),
    });

    const payload = (await response.json().catch(() => ({}))) as ApiPayload;

    if (!response.ok || !payload.ok) {
      setErrorMessage(payload.error ?? "No fue posible actualizar el entregable.");
      return;
    }

    setMessage("Entregable actualizado.");
    await reloadData();
  }

  async function createPayment() {
    if (!newPayment.contractId) {
      setErrorMessage("Selecciona un contrato para el pago.");
      return;
    }

    setErrorMessage(null);
    setMessage(null);
    setIsBusy(true);

    try {
      const response = await fetch(`/api/contracts/${encodeURIComponent(newPayment.contractId)}/payments`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          amount: Number(newPayment.amount),
          paymentDate: new Date(newPayment.paymentDate).toISOString(),
          invoiceNumber: newPayment.invoiceNumber || null,
          concept: newPayment.concept,
          status: newPayment.status,
        }),
      });

      const payload = (await response.json().catch(() => ({}))) as ApiPayload;

      if (!response.ok || !payload.ok) {
        setErrorMessage(payload.error ?? "No fue posible registrar el pago.");
        return;
      }

      setMessage("Pago registrado.");
      setNewPayment({
        contractId: "",
        amount: "",
        paymentDate: "",
        invoiceNumber: "",
        concept: "",
        status: "REGISTERED",
      });
      await reloadData();
    } catch {
      setErrorMessage("No fue posible registrar el pago.");
    } finally {
      setIsBusy(false);
    }
  }

  return (
    <div className="space-y-4">
      <section className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
        <Card>
          <CardContent className="py-4">
            <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#60718f]">Contratos activos</p>
            <p className="mt-2 text-4xl font-semibold text-[#15294d]">{kpis.activeContracts}</p>
          </CardContent>
        </Card>

        <Card>
          <CardContent className="py-4">
            <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#60718f]">Total cobrado</p>
            <p className="mt-2 text-4xl font-semibold text-[#15294d]">{formatCurrency(kpis.totalCollected)}</p>
          </CardContent>
        </Card>

        <Card>
          <CardContent className="py-4">
            <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#60718f]">Entregables pendientes</p>
            <p className="mt-2 text-4xl font-semibold text-[#15294d]">{kpis.pendingDeliverables}</p>
          </CardContent>
        </Card>

        <Card>
          <CardContent className="py-4">
            <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#60718f]">Entregables vencidos</p>
            <p className="mt-2 text-4xl font-semibold text-[#15294d]">{kpis.overdueDeliverables}</p>
          </CardContent>
        </Card>
      </section>

      {errorMessage ? <p className="rounded-xl border border-[#efc4c4] bg-[#fff1f1] px-3 py-2 text-sm text-[#ad3f3f]">{errorMessage}</p> : null}
      {message ? <p className="rounded-xl border border-[#bde5ce] bg-[#ecf9f1] px-3 py-2 text-sm text-[#1f7f4f]">{message}</p> : null}
      {extractionSummary ? <p className="rounded-xl border border-[#ced9ec] bg-[#f3f7ff] px-3 py-2 text-sm text-[#2b4a7b]">{extractionSummary}</p> : null}
      {proposalPdfOptions.length === 0 ? (
        <p className="rounded-xl border border-[#f0deb0] bg-[#fff8e9] px-3 py-2 text-sm text-[#8d6308]">
          Advertencia de continuidad: no hay propuestas M5 con PDF para reutilizar en M8.
        </p>
      ) : null}
      {hasContractsWithoutProposalTrace ? (
        <p className="rounded-xl border border-[#f0deb0] bg-[#fff8e9] px-3 py-2 text-sm text-[#8d6308]">
          Advertencia de continuidad: hay contratos sin `sourceProposalId`, la trazabilidad M5-&gt;M8 puede estar incompleta.
        </p>
      ) : null}

      <Tabs
        defaultTab="upload"
        items={[
          {
            id: "upload",
            label: "Subir Contrato",
            content: (
              <Card>
                <CardContent className="space-y-4 py-5">
                  <p className="text-sm text-[#5c6d8a]">Sube contrato PDF para extraer campos, entregables, pagos y clausulas de riesgo.</p>

                  <label className="space-y-1 text-sm font-semibold text-[#314764]">
                    Contrato existente (opcional)
                    <select
                      value={uploadContractId}
                      onChange={(event) => setUploadContractId(event.target.value)}
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] bg-white px-3"
                    >
                      <option value="">Crear nuevo contrato desde extraccion</option>
                      {contracts.map((item) => (
                        <option key={item.id} value={item.id}>
                          {item.title}
                        </option>
                      ))}
                    </select>
                  </label>

                  <label className="space-y-1 text-sm font-semibold text-[#314764]">
                    Archivo PDF
                    <input
                      type="file"
                      accept="application/pdf"
                      onChange={(event) => setUploadFile(event.target.files?.[0] ?? null)}
                      className="block w-full rounded-lg border border-[#cfd8e7] bg-white px-3 py-2 text-sm"
                    />
                  </label>

                  <Button onClick={submitExtraction} disabled={isBusy || !uploadFile}>
                    {isBusy ? "Analizando..." : "Analizar y guardar"}
                  </Button>

                  <div className="h-px bg-[#dfe7f3]" />

                  <div className="space-y-2 rounded-xl border border-[#d6e2f3] bg-[#f4f8ff] p-3">
                    <p className="text-sm font-semibold text-[#2d4d7d]">Continuidad M5 a M8 (sin reupload)</p>
                    <p className="text-xs text-[#4a638c]">Usa el PDF mas reciente de una propuesta de Modulo 5 como fuente de extraccion.</p>

                    <label className="space-y-1 text-sm font-semibold text-[#314764]">
                      Propuesta fuente (M5)
                      <select
                        value={proposalSourceId}
                        onChange={(event) => setProposalSourceId(event.target.value)}
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] bg-white px-3"
                      >
                        {proposalPdfOptions.length === 0 ? <option value="">No hay propuestas con PDF disponible</option> : null}
                        {proposalPdfOptions.map((option) => (
                          <option key={option.proposalId} value={option.proposalId}>
                            {option.proposalTitle} - {option.fileName} ({formatDateTime(option.createdAt)})
                          </option>
                        ))}
                      </select>
                    </label>

                    <Button variant="secondary" onClick={submitExtractionFromProposal} disabled={isBusy || !proposalSourceId}>
                      {isBusy ? "Analizando..." : "Usar PDF de propuesta de M5"}
                    </Button>
                    {selectedProposalPdfOption ? (
                      <p className="rounded-lg border border-[#cfdbef] bg-white px-2 py-1 text-xs text-[#3f5d8a]">
                        <span className="font-semibold">Por que este archivo:</span> se usa el PDF mas reciente de la propuesta seleccionada ({selectedProposalPdfOption.fileName}).
                      </p>
                    ) : null}
                  </div>

                  <div className="h-px bg-[#dfe7f3]" />

                  <div className="space-y-2 rounded-xl border border-[#e0d9fb] bg-[#f8f5ff] p-3">
                    <p className="text-sm font-semibold text-[#4f3f9a]">Adjuntar documento al contrato (sin IA)</p>
                    <p className="text-xs text-[#6a62a3]">Usa este flujo para subir evidencia contractual directamente usando `/api/contracts/upload`.</p>

                    <label className="space-y-1 text-sm font-semibold text-[#314764]">
                      Contrato destino
                      <select
                        value={evidenceContractId}
                        onChange={(event) => setEvidenceContractId(event.target.value)}
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] bg-white px-3"
                      >
                        <option value="">Selecciona contrato</option>
                        {contracts.map((item) => (
                          <option key={item.id} value={item.id}>
                            {item.title}
                          </option>
                        ))}
                      </select>
                    </label>

                    <label className="space-y-1 text-sm font-semibold text-[#314764]">
                      Tipo de documento
                      <select
                        value={evidenceKind}
                        onChange={(event) => setEvidenceKind(event.target.value as ContractRecordView["documents"][number]["kind"])}
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] bg-white px-3"
                      >
                        <option value="SIGNED_CONTRACT">Contrato firmado</option>
                        <option value="ADDENDUM">Convenio / adenda</option>
                        <option value="DELIVERABLE_EVIDENCE">Evidencia de entregable</option>
                        <option value="PAYMENT_EVIDENCE">Evidencia de pago</option>
                        <option value="OTHER">Otro</option>
                      </select>
                    </label>

                    <label className="space-y-1 text-sm font-semibold text-[#314764]">
                      Archivo PDF de evidencia
                      <input
                        type="file"
                        accept="application/pdf"
                        onChange={(event) => setEvidenceFile(event.target.files?.[0] ?? null)}
                        className="block w-full rounded-lg border border-[#cfd8e7] bg-white px-3 py-2 text-sm"
                      />
                    </label>

                    <Button variant="secondary" onClick={uploadContractEvidence} disabled={isBusy || !evidenceContractId || !evidenceFile}>
                      {isBusy ? "Subiendo..." : "Subir evidencia al contrato"}
                    </Button>
                  </div>
                </CardContent>
              </Card>
            ),
          },
          {
            id: "contracts",
            label: "Contratos",
            content: (
              <div className="space-y-3">
                <div className="flex flex-wrap gap-2">
                  <Dialog triggerLabel="Nuevo Contrato" title="Nuevo Contrato" description="Captura manual del contrato">
                    <div className="space-y-2">
                      <input
                        value={newContract.title}
                        onChange={(event) => setNewContract((prev) => ({ ...prev, title: event.target.value }))}
                        placeholder="Titulo"
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                      />
                      <input
                        value={newContract.counterpartyEntity}
                        onChange={(event) => setNewContract((prev) => ({ ...prev, counterpartyEntity: event.target.value }))}
                        placeholder="Entidad contratante"
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                      />
                      <input
                        value={newContract.contractNumber ?? ""}
                        onChange={(event) => setNewContract((prev) => ({ ...prev, contractNumber: event.target.value || null }))}
                        placeholder="Numero de contrato"
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                      />
                      <input
                        value={newContract.contractType}
                        onChange={(event) => setNewContract((prev) => ({ ...prev, contractType: event.target.value }))}
                        placeholder="Tipo"
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                      />
                      <input
                        value={newContract.totalAmount ?? ""}
                        onChange={(event) => setNewContract((prev) => ({ ...prev, totalAmount: event.target.value ? Number(event.target.value) : null }))}
                        placeholder="Monto total"
                        type="number"
                        className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                      />
                      <Button onClick={createContract} disabled={isBusy}>
                        Guardar contrato
                      </Button>
                    </div>
                  </Dialog>
                </div>

                {contracts.length === 0 ? <p className="text-sm text-[#60718f]">Aun no hay contratos registrados.</p> : null}

                {contracts.map((contract) => (
                  <article key={contract.id} className="rounded-2xl border border-[#d8e1ef] bg-white p-4">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div>
                        <p className="text-lg font-semibold text-[#1f3050]">{contract.title}</p>
                        <p className="text-sm text-[#60718f]">{contract.counterpartyEntity}</p>
                        <p className="text-xs text-[#60718f]">{contract.contractType}</p>
                      </div>
                      <span className={`inline-flex rounded-full border px-3 py-1 text-xs font-semibold ${statusTone(contract.status)}`}>{contract.status}</span>
                    </div>

                    <div className="mt-3 grid gap-2 text-sm text-[#425a82] md:grid-cols-4">
                      <p>Inicio: {formatDate(contract.startDate)}</p>
                      <p>Fin: {formatDate(contract.endDate)}</p>
                      <p>Monto: {contract.totalAmount ? formatCurrency(contract.totalAmount, contract.currency) : "Sin monto"}</p>
                      <p>
                        Progreso: {contract.progress.completed}/{contract.progress.total} ({contract.progress.percent}%)
                      </p>
                    </div>

                    <div className="mt-3 rounded-xl border border-[#dbe4f2] bg-[#f8fbff] p-3">
                      <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#4b6287]">Documentos del contrato</p>
                      {contract.documents.length === 0 ? <p className="mt-2 text-xs text-[#60718f]">Sin documentos cargados.</p> : null}

                      {contract.documents.length > 0 ? (
                        <ul className="mt-2 space-y-2">
                          {contract.documents.map((document) => (
                            <li key={document.id} className="rounded-lg border border-[#d8e2ef] bg-white px-3 py-2">
                              <div className="flex flex-wrap items-center justify-between gap-2">
                                <div>
                                  <p className="text-sm font-semibold text-[#1f3050]">{document.fileName}</p>
                                  <p className="text-xs text-[#60718f]">
                                    {contractDocumentKindLabel(document.kind)} | {formatFileSize(document.sizeBytes)} | {formatDateTime(document.createdAt)}
                                  </p>
                                  {contract.sourceProposalId && document.kind === "SIGNED_CONTRACT" ? (
                                    <p className="mt-1 rounded-md border border-[#d3e3fa] bg-[#eef5ff] px-2 py-1 text-[11px] font-semibold text-[#2c5b9e]">
                                      Por que este archivo: continuidad M5-&gt;M8 desde propuesta {contract.sourceProposalId}.
                                    </p>
                                  ) : null}
                                </div>
                                <div className="flex flex-wrap gap-2">
                                  <a
                                    href={`/api/contracts/${encodeURIComponent(contract.id)}/documents/${encodeURIComponent(document.id)}`}
                                    className="inline-flex h-8 items-center rounded-lg border border-[#cfd8e7] px-2 text-xs font-semibold text-[#2f4a74]"
                                  >
                                    Descargar
                                  </a>
                                  <button
                                    type="button"
                                    className="inline-flex h-8 items-center rounded-lg border border-[#ebc9ce] bg-[#fff4f6] px-2 text-xs font-semibold text-[#ab3e4d]"
                                    onClick={() => {
                                      void deleteContractDocument(contract.id, document.id);
                                    }}
                                  >
                                    Eliminar
                                  </button>
                                </div>
                              </div>
                            </li>
                          ))}
                        </ul>
                      ) : null}
                    </div>

                    <div className="mt-3 flex flex-wrap items-center gap-2">
                      <select
                        value={contract.status}
                        onChange={(event) => updateContractStatus(contract.id, event.target.value as ContractRecordView["status"])}
                        className="h-9 rounded-lg border border-[#cfd8e7] bg-white px-2 text-sm"
                      >
                        <option value="ACTIVE">ACTIVE</option>
                        <option value="COMPLETED">COMPLETED</option>
                        <option value="PAUSED">PAUSED</option>
                        <option value="CANCELLED">CANCELLED</option>
                      </select>

                      <Link href={`/proteccion-legal?contractId=${encodeURIComponent(contract.id)}`}>
                        <Button size="sm" variant="secondary">
                          Abrir caso legal
                        </Button>
                      </Link>
                    </div>
                  </article>
                ))}
              </div>
            ),
          },
          {
            id: "deliverables",
            label: "Entregables",
            content: (
              <div className="space-y-3">
                <Dialog triggerLabel="Nuevo Entregable" title="Nuevo Entregable" description="Vincula un entregable a un contrato">
                  <div className="space-y-2">
                    <select
                      value={newDeliverable.contractId}
                      onChange={(event) => setNewDeliverable((prev) => ({ ...prev, contractId: event.target.value }))}
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    >
                      <option value="">Selecciona contrato</option>
                      {contracts.map((item) => (
                        <option key={item.id} value={item.id}>
                          {item.title}
                        </option>
                      ))}
                    </select>
                    <input
                      value={newDeliverable.title}
                      onChange={(event) => setNewDeliverable((prev) => ({ ...prev, title: event.target.value }))}
                      placeholder="Titulo del entregable"
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <input
                      type="date"
                      value={newDeliverable.dueDate}
                      onChange={(event) => setNewDeliverable((prev) => ({ ...prev, dueDate: event.target.value }))}
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <input
                      type="number"
                      value={newDeliverable.amountLinked}
                      onChange={(event) => setNewDeliverable((prev) => ({ ...prev, amountLinked: event.target.value }))}
                      placeholder="Monto vinculado"
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <Button onClick={createDeliverable} disabled={isBusy}>
                      Guardar entregable
                    </Button>
                  </div>
                </Dialog>

                {deliverables.length === 0 ? <p className="text-sm text-[#60718f]">Sin entregables registrados.</p> : null}

                {deliverables.map((item) => (
                  <article key={item.id} className="rounded-xl border border-[#d8e1ef] bg-white p-3">
                    <div className="flex flex-wrap items-center justify-between gap-2">
                      <div>
                        <p className="text-sm font-semibold text-[#1d335a]">{item.title}</p>
                        <p className="text-xs text-[#60718f]">{item.contractTitle}</p>
                      </div>
                      <select
                        value={item.status}
                        onChange={(event) => updateDeliverableStatus(item.id, event.target.value as ContractDeliverableView["status"])}
                        className="h-8 rounded-lg border border-[#cfd8e7] bg-white px-2 text-xs"
                      >
                        <option value="PENDING">PENDING</option>
                        <option value="DELIVERED">DELIVERED</option>
                        <option value="APPROVED">APPROVED</option>
                        <option value="REJECTED">REJECTED</option>
                        <option value="OVERDUE">OVERDUE</option>
                      </select>
                    </div>
                    <p className="mt-1 text-xs text-[#60718f]">Vence: {formatDate(item.dueDate)} {item.isOverdue ? "(vencido)" : ""}</p>
                  </article>
                ))}
              </div>
            ),
          },
          {
            id: "payments",
            label: "Pagos",
            content: (
              <div className="space-y-3">
                <Dialog triggerLabel="Registrar Pago" title="Registrar Pago" description="Agrega un pago vinculado al contrato">
                  <div className="space-y-2">
                    <select
                      value={newPayment.contractId}
                      onChange={(event) => setNewPayment((prev) => ({ ...prev, contractId: event.target.value }))}
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    >
                      <option value="">Selecciona contrato</option>
                      {contracts.map((item) => (
                        <option key={item.id} value={item.id}>
                          {item.title}
                        </option>
                      ))}
                    </select>
                    <input
                      type="number"
                      value={newPayment.amount}
                      onChange={(event) => setNewPayment((prev) => ({ ...prev, amount: event.target.value }))}
                      placeholder="Monto"
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <input
                      type="date"
                      value={newPayment.paymentDate}
                      onChange={(event) => setNewPayment((prev) => ({ ...prev, paymentDate: event.target.value }))}
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <input
                      value={newPayment.concept}
                      onChange={(event) => setNewPayment((prev) => ({ ...prev, concept: event.target.value }))}
                      placeholder="Concepto"
                      className="h-10 w-full rounded-lg border border-[#cfd8e7] px-3"
                    />
                    <Button onClick={createPayment} disabled={isBusy}>
                      Guardar pago
                    </Button>
                  </div>
                </Dialog>

                {payments.length === 0 ? <p className="text-sm text-[#60718f]">Sin pagos registrados.</p> : null}

                {payments.map((item) => (
                  <article key={item.id} className="rounded-xl border border-[#d8e1ef] bg-white p-3">
                    <div className="flex flex-wrap items-center justify-between gap-2">
                      <p className="text-sm font-semibold text-[#1d335a]">{item.contractTitle}</p>
                      <span className="text-sm font-semibold text-[#1d335a]">{formatCurrency(item.amount, item.currency)}</span>
                    </div>
                    <p className="mt-1 text-xs text-[#60718f]">{item.concept}</p>
                    <p className="mt-1 text-xs text-[#60718f]">
                      {formatDate(item.paymentDate)} - {item.status}
                    </p>
                  </article>
                ))}
              </div>
            ),
          },
        ]}
      />
    </div>
  );
}
