"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { NormativeAnalysisHistoryView } from "@/lib/normative-analysis/history";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { cn } from "@/lib/utils";

type NormativeDocumentType = "BASES_LICITACION" | "CONVOCATORIA" | "ANEXOS" | "REGLAMENTO" | "LEY" | "OTRO";

type NormativeAnalysisViewProps = {
  linkedSource?: {
    id: string;
    title: string;
    issuingEntity: string | null;
  } | null;
  linkedProposal?: {
    id: string;
    title: string;
    issuingEntity: string | null;
  } | null;
  autoAnalyzeOnLoad?: boolean;
  moduleContext?: "normative" | "candados";
};

type AnalyzeApiPayload = {
  ok?: boolean;
  error?: string;
  code?: string;
  item?: NormativeAnalysisHistoryView;
};

type HistoryApiPayload = {
  ok?: boolean;
  error?: string;
  items?: NormativeAnalysisHistoryView[];
};

type DeleteApiPayload = {
  ok?: boolean;
  error?: string;
};

const MAX_UPLOAD_BYTES = 20 * 1024 * 1024;

const documentTypeOptions: Array<{ value: NormativeDocumentType; label: string }> = [
  { value: "BASES_LICITACION", label: "Bases de Licitacion" },
  { value: "CONVOCATORIA", label: "Convocatoria" },
  { value: "ANEXOS", label: "Anexos" },
  { value: "REGLAMENTO", label: "Reglamento" },
  { value: "LEY", label: "Ley" },
  { value: "OTRO", label: "Otro" },
];

function formatDateTime(value: string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return "Fecha no disponible";
  }

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

function getDocumentTypeLabel(value: NormativeDocumentType) {
  return documentTypeOptions.find((option) => option.value === value)?.label ?? "Otro";
}

function getViabilityBadgeTone(score: number) {
  if (score >= 75) {
    return "border-[#b9e6cd] bg-[#eaf9f1] text-[#1f8b63]";
  }

  if (score >= 55) {
    return "border-[#f0deb0] bg-[#fff8e9] text-[#9d6d08]";
  }

  return "border-[#f1c7ce] bg-[#fff1f4] text-[#b03f4f]";
}

function getRiskBadgeTone(level: "alto" | "medio" | "bajo") {
  if (level === "alto") {
    return "border-[#f1c7ce] bg-[#fff1f4] text-[#b03f4f]";
  }

  if (level === "medio") {
    return "border-[#f0deb0] bg-[#fff8e9] text-[#9d6d08]";
  }

  return "border-[#b9e6cd] bg-[#eaf9f1] text-[#1f8b63]";
}

function getPriorityTone(priority: "alta" | "media" | "baja") {
  if (priority === "alta") {
    return "border-[#f1c7ce] bg-[#fff1f4] text-[#b03f4f]";
  }

  if (priority === "media") {
    return "border-[#f0deb0] bg-[#fff8e9] text-[#9d6d08]";
  }

  return "border-[#b9e6cd] bg-[#eaf9f1] text-[#1f8b63]";
}

function getSeverityTone(level: "alto" | "medio" | "bajo") {
  if (level === "alto") {
    return "border-[#f1c7ce] bg-[#fff1f4] text-[#b03f4f]";
  }

  if (level === "medio") {
    return "border-[#f0deb0] bg-[#fff8e9] text-[#9d6d08]";
  }

  return "border-[#b9e6cd] bg-[#eaf9f1] text-[#1f8b63]";
}

type SuspiciousPattern = {
  key: string;
  phrase: string;
  description: string;
  level: "alto" | "medio" | "bajo";
  category: "Direccionamiento" | "Candado Indebido";
  count: number;
};

function normalizePatternKey(value: string) {
  return value.trim().toLowerCase();
}

function inferPatternCategory(input: string): SuspiciousPattern["category"] {
  const text = input.toLowerCase();
  if (text.includes("exclusiv") || text.includes("marca") || text.includes("solo") || text.includes("obligatori")) {
    return "Direccionamiento";
  }

  return "Candado Indebido";
}

function inferPatternLevel(input: string): SuspiciousPattern["level"] {
  const text = input.toLowerCase();
  if (text.includes("alto") || text.includes("critic") || text.includes("grave")) {
    return "alto";
  }

  if (text.includes("bajo") || text.includes("leve")) {
    return "bajo";
  }

  return "medio";
}

function buildSuspiciousPatterns(result: NormativeAnalysisHistoryView["result"] | null): SuspiciousPattern[] {
  if (!result) {
    return [];
  }

  const grouped = new Map<string, SuspiciousPattern>();

  for (const lock of result.lockIns) {
    const key = normalizePatternKey(lock.title || lock.impact || "candado");
    if (!key) {
      continue;
    }

    const existing = grouped.get(key);
    if (existing) {
      existing.count += 1;
      continue;
    }

    grouped.set(key, {
      key,
      phrase: lock.title || "Patron detectado",
      description: lock.impact || lock.recommendation || "Posible restriccion que limita la competencia.",
      level: inferPatternLevel(`${lock.title} ${lock.impact} ${lock.recommendation}`),
      category: inferPatternCategory(`${lock.title} ${lock.impact} ${lock.recommendation}`),
      count: 1,
    });
  }

  return Array.from(grouped.values());
}

function UploadIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden>
      <path
        d="M12 16V5m0 0-4 4m4-4 4 4M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

function BookIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden>
      <path
        d="M4 5.5A2.5 2.5 0 0 1 6.5 3H20v16H6.5A2.5 2.5 0 0 0 4 21V5.5Zm0 0A2.5 2.5 0 0 1 6.5 8H20"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

export function NormativeAnalysisView({
  linkedSource,
  linkedProposal,
  autoAnalyzeOnLoad = false,
  moduleContext = "normative",
}: NormativeAnalysisViewProps) {
  const inputRef = useRef<HTMLInputElement | null>(null);
  const autoAnalyzeAttemptedRef = useRef(false);
  const [isGuideOpen, setIsGuideOpen] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [documentType, setDocumentType] = useState<NormativeDocumentType>("BASES_LICITACION");
  const [issuingEntity, setIssuingEntity] = useState(linkedProposal?.issuingEntity ?? linkedSource?.issuingEntity ?? "");
  const [history, setHistory] = useState<NormativeAnalysisHistoryView[]>([]);
  const [selectedHistoryId, setSelectedHistoryId] = useState<string | null>(null);
  const [isLoadingHistory, setIsLoadingHistory] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);

  const selectedItem = useMemo(() => history.find((entry) => entry.id === selectedHistoryId) ?? null, [history, selectedHistoryId]);
  const hasMissingContinuityContext = !linkedSource && !linkedProposal;
  const suspiciousPatterns = useMemo(() => buildSuspiciousPatterns(selectedItem?.result ?? null), [selectedItem?.result]);
  const criticalAlertsCount = useMemo(() => {
    if (!selectedItem) {
      return 0;
    }

    const criticalRequirements = selectedItem.result.criticalRequirements.filter((item) => item.severity === "alto").length;
    const highPatterns = suspiciousPatterns.filter((item) => item.level === "alto").length;
    return criticalRequirements + highPatterns;
  }, [selectedItem, suspiciousPatterns]);
  const cleanlinessIndex = useMemo(() => {
    if (!selectedItem) {
      return 0;
    }

    const riskPenalty = selectedItem.riskLevel === "alto" ? 30 : selectedItem.riskLevel === "medio" ? 20 : 10;
    const raw = 100 - suspiciousPatterns.length * 18 - criticalAlertsCount * 22 - riskPenalty;
    return Math.max(0, Math.min(100, Math.round(raw)));
  }, [criticalAlertsCount, selectedItem, suspiciousPatterns.length]);

  useEffect(() => {
    setIssuingEntity(linkedProposal?.issuingEntity ?? linkedSource?.issuingEntity ?? "");
  }, [linkedProposal?.issuingEntity, linkedSource?.issuingEntity]);

  useEffect(() => {
    autoAnalyzeAttemptedRef.current = false;
  }, [linkedSource?.id, linkedProposal?.id]);

  useEffect(() => {
    let isMounted = true;

    async function loadHistory() {
      setIsLoadingHistory(true);
      try {
        const historyUrl = linkedProposal?.id
          ? `/api/normative-analysis/history?take=50&proposalId=${encodeURIComponent(linkedProposal.id)}`
          : linkedSource?.id
            ? `/api/normative-analysis/history?take=50&sourceId=${encodeURIComponent(linkedSource.id)}`
            : "/api/normative-analysis/history?take=50";
        const response = await fetch(historyUrl);
        const payload = (await response.json().catch(() => ({}))) as HistoryApiPayload;

        if (!response.ok || !payload.ok || !payload.items) {
          if (isMounted) {
            setErrorMessage(payload.error ?? "No fue posible cargar el historial de analisis.");
          }
          return;
        }

        if (!isMounted) {
          return;
        }

        setHistory(payload.items);
        const preferredBySource = linkedSource ? payload.items.find((item) => item.sourceLicitationId === linkedSource.id) ?? null : null;
        setSelectedHistoryId(preferredBySource?.id ?? payload.items[0]?.id ?? null);
      } catch {
        if (isMounted) {
          setErrorMessage("No fue posible cargar el historial de analisis.");
        }
      } finally {
        if (isMounted) {
          setIsLoadingHistory(false);
        }
      }
    }

    loadHistory();
    return () => {
      isMounted = false;
    };
  }, [linkedSource, linkedProposal]);

  function onFileSelected(file: File | null) {
    if (!file) {
      setSelectedFile(null);
      return;
    }

    if (!file.name.toLowerCase().endsWith(".pdf")) {
      setErrorMessage("Solo se permiten archivos PDF.");
      return;
    }

    if (file.size > MAX_UPLOAD_BYTES) {
      setErrorMessage("El archivo excede el limite de 20MB.");
      return;
    }

    setErrorMessage(null);
    setSelectedFile(file);
  }

  const handleAnalyzeProposalDocument = useCallback(async () => {
    if (!linkedProposal?.id) {
      setErrorMessage("No hay una propuesta de Modulo 5 vinculada para analisis automatico.");
      return false;
    }

    setErrorMessage(null);
    setIsSubmitting(true);

    try {
      const formData = new FormData();
      formData.append("documentType", documentType);
      if (issuingEntity.trim()) {
        formData.append("issuingEntity", issuingEntity.trim());
      }
      formData.append("sourceProposalId", linkedProposal.id);
      if (linkedSource?.id) {
        formData.append("sourceLicitationId", linkedSource.id);
      }
      formData.append("useSourceDocument", "1");

      const response = await fetch("/api/normative-analysis", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json().catch(() => null)) as AnalyzeApiPayload | null;
      if (!response.ok || !payload?.ok || !payload.item) {
        const suffix = payload?.code ? ` [${payload.code}]` : "";
        setErrorMessage((payload?.error ?? "No fue posible analizar el documento principal de Modulo 5.") + suffix);
        return false;
      }

      setHistory((previous) => [payload.item as NormativeAnalysisHistoryView, ...previous.filter((item) => item.id !== payload.item?.id)]);
      setSelectedHistoryId(payload.item.id);
      setSelectedFile(null);
      if (inputRef.current) {
        inputRef.current.value = "";
      }
      return true;
    } catch {
      setErrorMessage("No fue posible enviar el documento principal de Modulo 5 para analisis.");
      return false;
    } finally {
      setIsSubmitting(false);
    }
  }, [documentType, issuingEntity, linkedProposal?.id, linkedSource?.id]);

  const handleAnalyzeSourceDocument = useCallback(async () => {
    if (!linkedSource?.id) {
      setErrorMessage("No hay una oportunidad de Modulo 3 vinculada para analisis automatico.");
      return false;
    }

    setErrorMessage(null);
    setIsSubmitting(true);

    try {
      const formData = new FormData();
      formData.append("documentType", documentType);
      if (issuingEntity.trim()) {
        formData.append("issuingEntity", issuingEntity.trim());
      }
      formData.append("sourceLicitationId", linkedSource.id);
      formData.append("useSourceDocument", "1");

      const response = await fetch("/api/normative-analysis", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json().catch(() => null)) as AnalyzeApiPayload | null;
      if (!response.ok || !payload?.ok || !payload.item) {
        const suffix = payload?.code ? ` [${payload.code}]` : "";
        setErrorMessage((payload?.error ?? "No fue posible analizar el documento principal de Modulo 3.") + suffix);
        return false;
      }

      setHistory((previous) => [payload.item as NormativeAnalysisHistoryView, ...previous.filter((item) => item.id !== payload.item?.id)]);
      setSelectedHistoryId(payload.item.id);
      setSelectedFile(null);
      if (inputRef.current) {
        inputRef.current.value = "";
      }
      return true;
    } catch {
      setErrorMessage("No fue posible enviar el documento principal para analisis.");
      return false;
    } finally {
      setIsSubmitting(false);
    }
  }, [documentType, issuingEntity, linkedSource?.id]);

  async function handleAnalyze() {
    if (!selectedFile && linkedProposal?.id) {
      await handleAnalyzeProposalDocument();
      return;
    }

    if (!selectedFile && linkedSource?.id) {
      await handleAnalyzeSourceDocument();
      return;
    }

    if (!selectedFile) {
      setErrorMessage("Selecciona un documento PDF para continuar.");
      return;
    }

    setErrorMessage(null);
    setIsSubmitting(true);

    try {
      const formData = new FormData();
      formData.append("file", selectedFile);
      formData.append("documentType", documentType);
      if (issuingEntity.trim()) {
        formData.append("issuingEntity", issuingEntity.trim());
      }
      if (linkedSource?.id) {
        formData.append("sourceLicitationId", linkedSource.id);
      }
      if (linkedProposal?.id) {
        formData.append("sourceProposalId", linkedProposal.id);
      }

      const response = await fetch("/api/normative-analysis", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json().catch(() => null)) as AnalyzeApiPayload | null;

      if (!response.ok || !payload?.ok || !payload.item) {
        const suffix = payload?.code ? ` [${payload.code}]` : "";
        setErrorMessage((payload?.error ?? "No fue posible analizar el documento.") + suffix);
        return;
      }

      setHistory((previous) => [payload.item as NormativeAnalysisHistoryView, ...previous.filter((item) => item.id !== payload.item?.id)]);
      setSelectedHistoryId(payload.item.id);
      setSelectedFile(null);
      if (inputRef.current) {
        inputRef.current.value = "";
      }
    } catch {
      setErrorMessage("No fue posible enviar el archivo para analisis.");
    } finally {
      setIsSubmitting(false);
    }
  }

  useEffect(() => {
    const hasLinkedContext = Boolean(linkedProposal?.id || linkedSource?.id);

    if (!autoAnalyzeOnLoad || !hasLinkedContext || isLoadingHistory || isSubmitting || autoAnalyzeAttemptedRef.current) {
      return;
    }

    const hasMatchingHistory = linkedSource?.id ? history.some((item) => item.sourceLicitationId === linkedSource.id) : false;
    if (hasMatchingHistory) {
      return;
    }

    autoAnalyzeAttemptedRef.current = true;
    if (linkedProposal?.id) {
      void handleAnalyzeProposalDocument();
      return;
    }

    void handleAnalyzeSourceDocument();
  }, [
    autoAnalyzeOnLoad,
    handleAnalyzeProposalDocument,
    handleAnalyzeSourceDocument,
    history,
    isLoadingHistory,
    isSubmitting,
    linkedProposal?.id,
    linkedSource?.id,
  ]);

  async function handleDeleteHistoryItem(id: string) {
    setDeletingId(id);
    setErrorMessage(null);

    try {
      const response = await fetch(`/api/normative-analysis/history/${encodeURIComponent(id)}`, {
        method: "DELETE",
      });
      const payload = (await response.json().catch(() => ({}))) as DeleteApiPayload;

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

      setHistory((previous) => {
        const next = previous.filter((item) => item.id !== id);
        setSelectedHistoryId((current) => (current === id ? next[0]?.id ?? null : current));
        return next;
      });
    } catch {
      setErrorMessage("No fue posible eliminar el analisis.");
    } finally {
      setDeletingId(null);
    }
  }

  if (moduleContext === "candados") {
    const activeFileName = selectedFile?.name ?? selectedItem?.fileName ?? "";
    const extractedWords = selectedItem ? Math.max(0, Math.round(selectedItem.extractedChars / 5)) : 0;

    return (
      <div className="space-y-4">
        {hasMissingContinuityContext ? (
          <p className="rounded-xl border border-[#f0deb0] bg-[#fff8e9] px-3 py-2 text-sm text-[#8d6308]">
            Advertencia de continuidad: estas analizando sin fuente vinculada de M3/M5; guarda el origen para mantener trazabilidad entre modulos.
          </p>
        ) : null}

        <div className="grid gap-3 rounded-xl border border-[#d8e0ec] bg-[#f4f7fb] p-2 md:grid-cols-2">
          <div className="flex items-center justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-[#13284d]">Analisis de Bases</div>
          <div className="flex items-center justify-center rounded-lg px-3 py-2 text-sm font-semibold text-[#5f7090]">Evaluacion de Viabilidad</div>
        </div>

        <Card>
          <CardContent className="space-y-4 p-4">
            <div>
              <h3 className="text-2xl font-semibold text-[#152949] [font-family:var(--font-display)]">Analizar Bases de Licitacion</h3>
              <p className="text-base text-[#5f7090]">Sube el PDF de las bases para detectar indicios de direccionamiento, favoritismo o candados indebidos.</p>
            </div>

            <div className="grid gap-2 md:grid-cols-2">
              <button
                type="button"
                className="rounded-lg border border-[#d7dfed] bg-[#f8fbff] px-4 py-2 text-sm font-semibold text-[#17305a]"
                onClick={() => inputRef.current?.click()}
              >
                Subir PDF
              </button>
              <div className="rounded-lg border border-[#e2e8f3] bg-[#f8fbff] px-4 py-2 text-center text-sm font-semibold text-[#7c8da8]">Pegar Texto</div>
            </div>

            <div
              className={cn(
                "rounded-xl border-2 border-dashed p-4 transition",
                isDragging ? "border-[#365ea7] bg-[#eff4ff]" : "border-[#d2dceb] bg-[#fcfdff]",
              )}
              onDragOver={(event) => {
                event.preventDefault();
                setIsDragging(true);
              }}
              onDragLeave={() => setIsDragging(false)}
              onDrop={(event) => {
                event.preventDefault();
                setIsDragging(false);
                onFileSelected(event.dataTransfer.files?.[0] ?? null);
              }}
              onClick={() => inputRef.current?.click()}
            >
              {activeFileName ? (
                <div className="flex items-center justify-between gap-3">
                  <div className="min-w-0">
                    <p className="truncate text-lg font-semibold text-[#1a2d4f]">{activeFileName}</p>
                    {extractedWords > 0 ? <p className="text-sm text-[#5f7090]">{extractedWords} palabras extraidas</p> : null}
                  </div>
                  <Button size="sm" variant="secondary" onClick={() => inputRef.current?.click()}>
                    Cambiar
                  </Button>
                </div>
              ) : (
                <div className="text-center">
                  <p className="text-lg font-semibold text-[#1d2d4b]">Arrastra tu documento aqui</p>
                  <p className="text-sm text-[#5f7190]">o haz clic para seleccionar</p>
                  <p className="text-sm text-[#5f7190]">Solo archivos PDF (max. 20MB)</p>
                </div>
              )}
            </div>

            <input
              ref={inputRef}
              type="file"
              accept="application/pdf,.pdf"
              className="hidden"
              onChange={(event) => onFileSelected(event.target.files?.[0] ?? null)}
            />

            {errorMessage ? <p className="text-sm font-semibold text-[#c53a4c]">{errorMessage}</p> : null}

            <div className="flex justify-end">
              <Button onClick={handleAnalyze} disabled={isSubmitting}>
                {isSubmitting ? "Escaneando..." : "Escanear Documento"}
              </Button>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardContent className="space-y-4 p-4">
            <div className="grid gap-4 md:grid-cols-3">
              <div className="text-center">
                <p className="text-5xl font-semibold text-[#13284d]">{cleanlinessIndex}%</p>
                <p className="text-sm text-[#5f7090]">Indice de Limpieza</p>
                <div className="mx-auto mt-2 h-2 w-full max-w-[240px] overflow-hidden rounded-full bg-[#dbe3ef]">
                  <div className="h-full bg-gradient-to-r from-[#1f3f84] to-[#2bb67f]" style={{ width: `${Math.max(5, cleanlinessIndex)}%` }} />
                </div>
              </div>
              <div className="text-center">
                <p className="text-5xl font-semibold text-[#13284d]">{suspiciousPatterns.length}</p>
                <p className="text-sm text-[#5f7090]">Patrones Detectados</p>
              </div>
              <div className="text-center">
                <p className="text-5xl font-semibold text-[#13284d]">{criticalAlertsCount}</p>
                <p className="text-sm text-[#5f7090]">Alertas Criticas</p>
              </div>
            </div>
          </CardContent>
        </Card>

        <section className="space-y-3">
          <p className="text-2xl font-semibold text-[#13284d] [font-family:var(--font-display)]">Patrones Sospechosos ({suspiciousPatterns.length})</p>
          {suspiciousPatterns.length === 0 ? (
            <Card>
              <CardContent className="py-6 text-sm text-[#60718f]">Escanea un documento para ver riesgos y candados detectados.</CardContent>
            </Card>
          ) : (
            suspiciousPatterns.map((pattern) => (
              <div
                key={pattern.key}
                className={cn(
                  "rounded-xl border p-4",
                  pattern.level === "alto" ? "border-[#f3c0c8] bg-[#fff9fa]" : "border-[#f0deb0] bg-[#fffdf5]",
                )}
              >
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <p className="text-xl font-semibold text-[#1a2d4f]">&quot;{pattern.phrase}&quot;</p>
                  <div className="flex flex-wrap items-center gap-2 text-sm font-semibold">
                    <span className={cn("rounded-full border px-3 py-0.5", getRiskBadgeTone(pattern.level))}>{pattern.level}</span>
                    <span className="rounded-full bg-[#24a575] px-3 py-0.5 text-white">{pattern.category}</span>
                    <span className="rounded-full border border-[#d4deeb] bg-white px-3 py-0.5 text-[#344c72]">{pattern.count}x</span>
                  </div>
                </div>
                <p className="mt-2 text-base text-[#5f7090]">{pattern.description}</p>
              </div>
            ))
          )}
        </section>
      </div>
    );
  }

  return (
    <div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)]">
      <section className="space-y-4">
        {hasMissingContinuityContext ? (
          <p className="rounded-xl border border-[#f0deb0] bg-[#fff8e9] px-3 py-2 text-sm text-[#8d6308]">
            Advertencia de continuidad: no hay contexto vinculado de M3 o M5. Si continuas, el historial puede quedar sin linea de origen.
          </p>
        ) : null}

        {linkedProposal ? (
          <Card className="border-[#c8e3da] bg-[#edf8f3]">
            <CardContent className="space-y-1 p-4">
              <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#2f6e59]">Propuesta vinculada (M5)</p>
              <p className="text-sm font-semibold text-[#194736]">{linkedProposal.title}</p>
              {linkedProposal.issuingEntity ? <p className="text-sm text-[#3f7a66]">{linkedProposal.issuingEntity}</p> : null}
            </CardContent>
          </Card>
        ) : null}

        {linkedSource ? (
          <Card className="border-[#cfe0fb] bg-[#edf4ff]">
            <CardContent className="space-y-1 p-4">
              <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#395a93]">Oportunidad origen (M3)</p>
              <p className="text-sm font-semibold text-[#1d335a]">{linkedSource.title}</p>
              {linkedSource.issuingEntity ? <p className="text-sm text-[#58709a]">{linkedSource.issuingEntity}</p> : null}
            </CardContent>
          </Card>
        ) : null}

        <Card className="border-[#bdd4f5] bg-[#eef4ff]">
          <CardContent className="space-y-2 p-4">
            <button type="button" className="flex w-full items-center justify-between text-left" onClick={() => setIsGuideOpen((previous) => !previous)}>
              <span className="text-xl font-semibold text-[#1f3f84]">Guia para mejores resultados</span>
              <span className="text-xl text-[#1f3f84]">{isGuideOpen ? "˄" : "˅"}</span>
            </button>
            <p className="text-sm text-[#38517c]">Como preparar tu documento para un analisis exitoso?</p>
            {isGuideOpen ? (
              <div className="rounded-lg border border-[#c8d9f4] bg-white p-3 text-sm text-[#425c89]">
                Asegura que el PDF sea legible, incluya fechas y anexos completos, y de preferencia no sea un escaneo borroso. Si el documento contiene tablas o
                requisitos tecnicos, sube la version mas reciente.
              </div>
            ) : null}
          </CardContent>
        </Card>

        <Card>
          <CardContent className="space-y-4 p-4">
            <div>
              <h3 className="text-4xl font-semibold text-[#1a2b48] [font-family:var(--font-display)]">Analizar Documento Normativo</h3>
              <p className="mt-1 text-base text-[#5f7090]">Sube bases de licitacion, convocatorias, reglamentos o leyes para obtener un analisis inteligente.</p>
            </div>

            <button
              type="button"
              className={cn(
                "flex w-full flex-col items-center justify-center rounded-xl border-2 border-dashed px-4 py-8 text-center transition",
                isDragging ? "border-[#365ea7] bg-[#eff4ff]" : "border-[#cfd8e9] bg-[#fbfdff]",
              )}
              onDragOver={(event) => {
                event.preventDefault();
                setIsDragging(true);
              }}
              onDragLeave={() => setIsDragging(false)}
              onDrop={(event) => {
                event.preventDefault();
                setIsDragging(false);
                onFileSelected(event.dataTransfer.files?.[0] ?? null);
              }}
              onClick={() => inputRef.current?.click()}
            >
              <UploadIcon className="h-12 w-12 text-[#5a6f95]" />
              <p className="mt-3 text-xl font-semibold text-[#1d2d4b]">{selectedFile ? selectedFile.name : "Arrastra tu documento aqui"}</p>
              <p className="mt-2 text-sm text-[#5f7190]">o haz clic para seleccionar</p>
              <p className="mt-1 text-sm text-[#5f7190]">Solo archivos PDF (max. 20MB)</p>
            </button>

            <input
              ref={inputRef}
              type="file"
              accept="application/pdf,.pdf"
              className="hidden"
              onChange={(event) => onFileSelected(event.target.files?.[0] ?? null)}
            />

            <div className="grid gap-3 md:grid-cols-2">
              <label className="space-y-1 text-sm font-semibold text-[#33415c]">
                Tipo de Documento
                <select
                  value={documentType}
                  onChange={(event) => setDocumentType(event.target.value as NormativeDocumentType)}
                  className="h-10 w-full rounded-lg border border-[#cfd8e6] px-3 text-sm"
                >
                  {documentTypeOptions.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </select>
              </label>

              <label className="space-y-1 text-sm font-semibold text-[#33415c]">
                Entidad Emisora (opcional)
                <input
                  value={issuingEntity}
                  onChange={(event) => setIssuingEntity(event.target.value)}
                  className="h-10 w-full rounded-lg border border-[#cfd8e6] px-3 text-sm"
                  placeholder="Ej: IMSS, CFE, Gobierno"
                />
              </label>
            </div>

            {errorMessage ? <p className="text-sm font-semibold text-[#c53a4c]">{errorMessage}</p> : null}
            {!selectedFile && linkedProposal?.id ? (
              <p className="text-xs font-semibold text-[#506891]">
                Sin archivo cargado, se analizara primero el PDF de la propuesta (M5). Si no existe, se usara el documento principal de M3 cuando este disponible.
              </p>
            ) : !selectedFile && linkedSource?.id ? (
              <p className="text-xs font-semibold text-[#506891]">Sin archivo cargado, se analizara automaticamente el PDF principal vinculado desde Modulo 3.</p>
            ) : null}

            <div className="flex justify-end">
              <Button onClick={handleAnalyze} disabled={isSubmitting}>
                {isSubmitting
                  ? "Analizando..."
                  : !selectedFile && linkedProposal?.id
                    ? "Analizar PDF de propuesta (M5)"
                    : !selectedFile && linkedSource?.id
                      ? "Analizar PDF principal (M3)"
                      : "Analizar con IA"}
              </Button>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardContent className="space-y-3 p-4">
            <div>
              <h3 className="text-5xl font-semibold text-[#13274e] [font-family:var(--font-display)]">Historial de Analisis</h3>
              <p className="text-base text-[#5f7190]">{history.length} documentos analizados</p>
            </div>

            {isLoadingHistory ? <p className="text-sm text-[#60718f]">Cargando historial...</p> : null}

            {!isLoadingHistory && history.length === 0 ? (
              <p className="text-sm text-[#60718f]">Todavia no hay analisis guardados para esta cuenta.</p>
            ) : null}

            {history.length > 0 ? (
              <div className="max-h-[620px] space-y-2 overflow-auto pr-1">
                {history.map((item) => (
                  <div
                    key={item.id}
                    className={cn(
                      "rounded-xl border p-3",
                      selectedHistoryId === item.id ? "border-[#89aee8] bg-[#edf4ff]" : "border-[#dce4f1] bg-white",
                    )}
                  >
                    <div className="flex items-start justify-between gap-2">
                      <button type="button" className="min-w-0 flex-1 text-left" onClick={() => setSelectedHistoryId(item.id)}>
                        <div className="flex flex-wrap items-center gap-2">
                          <p className="truncate text-lg font-semibold text-[#1f304f]">{item.fileName}</p>
                          <span className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-semibold ${getViabilityBadgeTone(item.viabilityScore)}`}>
                            {item.riskLevel}
                          </span>
                        </div>
                        <p className="mt-1 text-sm text-[#60718f]">
                          {getDocumentTypeLabel(item.documentType)} · {formatDateTime(item.analyzedAt)}
                        </p>
                        <p className="mt-1 text-sm font-semibold text-[#233a62]">Viabilidad: {item.viabilityScore}%</p>
                      </button>
                      <button
                        type="button"
                        className="rounded-md px-2 py-1 text-sm text-[#6a7d9c] transition hover:bg-[#e8eef9]"
                        onClick={() => handleDeleteHistoryItem(item.id)}
                        disabled={deletingId === item.id}
                      >
                        {deletingId === item.id ? "..." : "🗑"}
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            ) : null}
          </CardContent>
        </Card>
      </section>

      <section>
        <Card className="min-h-[600px] border-dashed border-[#d1dae8] bg-[#f9fbff]">
          <CardContent className="h-full p-6">
            {!selectedItem ? (
              <div className="flex h-full min-h-[540px] flex-col items-center justify-center text-center">
                <BookIcon className="h-16 w-16 text-[#b0bccf]" />
                <p className="mt-6 text-3xl font-semibold text-[#1b2d4e] [font-family:var(--font-display)]">Sin analisis seleccionado</p>
                <p className="mt-2 max-w-md text-base text-[#60718f]">Sube un documento para analizarlo o selecciona uno del historial para ver resultados.</p>
              </div>
            ) : (
              <div className="space-y-4">
                <div className="grid gap-3 lg:grid-cols-2">
                  <Card className="border-[#d6e0ef] bg-white">
                    <CardContent className="p-4">
                      <p className="text-sm font-semibold text-[#20345a]">Viabilidad de Participacion</p>
                      <p className="mt-1 text-5xl font-semibold text-[#15294d]">{selectedItem.result.participationViability.score}%</p>
                      <div className="mt-3 h-3 w-full overflow-hidden rounded-full bg-[#dce5f1]">
                        <div
                          className="h-full bg-gradient-to-r from-[#1f3f84] via-[#1f3f84] to-[#2bb67f]"
                          style={{ width: `${Math.max(8, Math.min(100, selectedItem.result.participationViability.score))}%` }}
                        />
                      </div>
                      <p className="mt-2 text-sm text-[#5d7090]">{selectedItem.result.participationViability.rationale}</p>
                    </CardContent>
                  </Card>

                  <Card className="border-[#d6e0ef] bg-white">
                    <CardContent className="p-4">
                      <p className="text-sm font-semibold text-[#20345a]">Nivel de Riesgo</p>
                      <div className="mt-2 flex items-center justify-between gap-2">
                        <span className={`inline-flex rounded-full border px-4 py-1 text-4xl font-semibold ${getRiskBadgeTone(selectedItem.result.risk.level)}`}>
                          {selectedItem.result.risk.level}
                        </span>
                        <span
                          className={cn(
                            "inline-flex h-3 w-3 rounded-full",
                            selectedItem.result.risk.level === "alto"
                              ? "bg-[#e34a5b]"
                              : selectedItem.result.risk.level === "medio"
                                ? "bg-[#d7a022]"
                                : "bg-[#2eab78]",
                          )}
                        />
                      </div>
                      <p className="mt-3 text-sm text-[#5d7090]">{selectedItem.result.risk.description}</p>
                    </CardContent>
                  </Card>
                </div>

                <Card className="border-[#d6e0ef] bg-white">
                  <CardContent className="space-y-2 p-4">
                    <div>
                      <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#4d648a]">Analisis activo</p>
                      <h3 className="mt-1 text-xl font-semibold text-[#1d2f4f]">{selectedItem.fileName}</h3>
                      <p className="mt-1 text-sm text-[#60718f]">{formatDateTime(selectedItem.analyzedAt)}</p>
                    </div>
                    <div className="flex flex-wrap gap-2 text-xs">
                      <span className="rounded-full border border-[#d3deef] bg-[#f5f8ff] px-2 py-1 font-semibold text-[#355184]">
                        {getDocumentTypeLabel(selectedItem.documentType)}
                      </span>
                      <span className="rounded-full border border-[#d3deef] bg-[#f5f8ff] px-2 py-1 font-semibold text-[#355184]">
                        Metodo: {selectedItem.methodUsed.toUpperCase()}
                      </span>
                      <span className="rounded-full border border-[#d3deef] bg-[#f5f8ff] px-2 py-1 font-semibold text-[#355184]">
                        Confianza: {selectedItem.confidence.toUpperCase()}
                      </span>
                    </div>
                    <p className="mt-2 text-base text-[#314766]">{selectedItem.result.executiveSummary}</p>
                  </CardContent>
                </Card>

                <div className="grid gap-3 lg:grid-cols-2">
                  <Card className="border-[#d6e0ef] bg-white">
                    <CardContent className="space-y-2 p-4">
                      <div className="flex items-center justify-between gap-2">
                        <p className="text-sm font-semibold text-[#20345a]">Valor por dinero</p>
                        <span className={`inline-flex rounded-full border px-3 py-1 text-sm font-semibold ${getViabilityBadgeTone(selectedItem.result.valueForMoney.score)}`}>
                          {selectedItem.result.valueForMoney.score}%
                        </span>
                      </div>
                      <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#5f7190]">Senales</p>
                      <ul className="space-y-1 text-sm text-[#5d7090]">
                        {selectedItem.result.valueForMoney.signals.map((item, index) => (
                          <li key={`${item}-${index}`} className="rounded-lg border border-[#e1e8f3] bg-[#f8fbff] px-3 py-2">
                            {item}
                          </li>
                        ))}
                      </ul>
                      <p className="pt-1 text-xs font-semibold uppercase tracking-[0.08em] text-[#5f7190]">Acciones</p>
                      <ul className="space-y-1 text-sm text-[#5d7090]">
                        {selectedItem.result.valueForMoney.actions.map((item, index) => (
                          <li key={`${item}-${index}`} className="rounded-lg border border-[#d1eadc] bg-[#f3fbf6] px-3 py-2">
                            {item}
                          </li>
                        ))}
                      </ul>
                    </CardContent>
                  </Card>

                  <Card className="border-[#d6e0ef] bg-white">
                    <CardContent className="space-y-2 p-4">
                      <div className="flex items-center justify-between gap-2">
                        <p className="text-sm font-semibold text-[#20345a]">Economia circular</p>
                        <span
                          className={`inline-flex rounded-full border px-3 py-1 text-sm font-semibold ${
                            selectedItem.result.circularEconomy.applicable
                              ? "border-[#b9e6cd] bg-[#eaf9f1] text-[#1f8b63]"
                              : "border-[#d8e1ef] bg-[#f3f6fb] text-[#5f7090]"
                          }`}
                        >
                          {selectedItem.result.circularEconomy.applicable ? "Aplica" : "No explicito"}
                        </span>
                      </div>
                      <p className="text-xs font-semibold uppercase tracking-[0.08em] text-[#5f7190]">Senales</p>
                      <ul className="space-y-1 text-sm text-[#5d7090]">
                        {selectedItem.result.circularEconomy.signals.map((item, index) => (
                          <li key={`${item}-${index}`} className="rounded-lg border border-[#e1e8f3] bg-[#f8fbff] px-3 py-2">
                            {item}
                          </li>
                        ))}
                      </ul>
                      <p className="pt-1 text-xs font-semibold uppercase tracking-[0.08em] text-[#5f7190]">Acciones</p>
                      <ul className="space-y-1 text-sm text-[#5d7090]">
                        {selectedItem.result.circularEconomy.actions.map((item, index) => (
                          <li key={`${item}-${index}`} className="rounded-lg border border-[#d1eadc] bg-[#f3fbf6] px-3 py-2">
                            {item}
                          </li>
                        ))}
                      </ul>
                    </CardContent>
                  </Card>
                </div>

                <details open className="rounded-xl border border-[#cce5d7] bg-[#eff9f2]">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Requisitos Obligatorios <span className="ml-2 rounded-full bg-[#2faf7f] px-2 py-0.5 text-sm text-white">{selectedItem.result.requiredChecklist.length}</span>
                  </summary>
                  <div className="space-y-3 px-4 pb-4">
                    {selectedItem.result.requiredChecklist.map((item, index) => (
                      <div key={`${item.title}-${index}`} className="rounded-xl border border-[#d8e1ef] bg-[#f7fafc] p-4">
                        <p className="text-lg font-semibold text-[#152949]">{item.title}</p>
                        <p className="mt-1 text-base text-[#5a6f92]">{item.description}</p>
                      </div>
                    ))}
                  </div>
                </details>

                <details open className="rounded-xl border border-[#efdca5] bg-[#fff9ea]">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Requisitos Criticos <span className="ml-2 rounded-full bg-[#f0deb0] px-2 py-0.5 text-sm text-[#8d6308]">{selectedItem.result.criticalRequirements.length}</span>
                  </summary>
                  <div className="space-y-3 px-4 pb-4">
                    {selectedItem.result.criticalRequirements.map((item, index) => (
                      <div key={`${item.title}-${index}`} className="rounded-xl border border-[#efdca5] bg-[#fffef7] p-4">
                        <div className="flex flex-wrap items-center justify-between gap-2">
                          <p className="text-lg font-semibold text-[#152949]">{item.title}</p>
                          <span className={`inline-flex rounded-full border px-3 py-0.5 text-sm font-semibold ${getSeverityTone(item.severity)}`}>{item.severity}</span>
                        </div>
                        <p className="mt-1 text-base text-[#5a6f92]">{item.description}</p>
                      </div>
                    ))}
                  </div>
                </details>

                <details open className="rounded-xl border border-[#efc1c8] bg-[#fff4f6]">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Posibles Candados Detectados <span className="ml-2 rounded-full bg-[#f8d9de] px-2 py-0.5 text-sm text-[#ad3f4f]">{selectedItem.result.lockIns.length}</span>
                  </summary>
                  <div className="space-y-3 px-4 pb-4">
                    {selectedItem.result.lockIns.map((item, index) => (
                      <div key={`${item.title}-${index}`} className="rounded-xl border border-[#efc1c8] bg-[#fffafb] p-4">
                        <p className="text-lg font-semibold text-[#152949]">{item.title}</p>
                        <p className="mt-1 text-base text-[#b03f4f]">
                          <span className="font-semibold">Impacto:</span> {item.impact}
                        </p>
                        <p className="mt-1 text-base text-[#1f8b63]">
                          <span className="font-semibold">Recomendacion:</span> {item.recommendation}
                        </p>
                      </div>
                    ))}
                  </div>
                </details>

                <details open className="rounded-xl border border-[#bfe8d0] bg-[#f0faf4]">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Recomendaciones de Preparacion{" "}
                    <span className="ml-2 rounded-full bg-[#ccefd9] px-2 py-0.5 text-sm text-[#1e8b63]">{selectedItem.result.preparationRecommendations.length}</span>
                  </summary>
                  <div className="space-y-3 px-4 pb-4">
                    {selectedItem.result.preparationRecommendations.map((item, index) => (
                      <div key={`${item.title}-${index}`} className="rounded-xl border border-[#cfe7d9] bg-[#f7fcf9] p-4">
                        <div className="flex flex-wrap items-center justify-between gap-2">
                          <p className="text-lg font-semibold text-[#152949]">{item.title}</p>
                          <span className={`inline-flex rounded-full border px-3 py-0.5 text-sm font-semibold ${getPriorityTone(item.priority)}`}>Prioridad {item.priority}</span>
                        </div>
                        <p className="mt-1 text-base text-[#5a6f92]">{item.description}</p>
                      </div>
                    ))}
                  </div>
                </details>

                <details open className="rounded-xl border border-[#d6e0ef] bg-white">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Formatos Oficiales Detectados{" "}
                    <span className="ml-2 rounded-full bg-[#2faf7f] px-2 py-0.5 text-sm text-white">{selectedItem.result.officialFormats.length}</span>
                  </summary>
                  <div className="space-y-2 px-4 pb-4">
                    {selectedItem.result.officialFormats.map((item, index) => (
                      <div key={`${item}-${index}`} className="rounded-xl border border-[#e1e8f3] bg-[#f8fbff] p-3 text-base text-[#51688f]">
                        {item}
                      </div>
                    ))}
                  </div>
                </details>

                <details open className="rounded-xl border border-[#d6e0ef] bg-white">
                  <summary className="cursor-pointer px-4 py-3 text-xl font-semibold text-[#1d335a]">
                    Trazabilidad por documento{" "}
                    <span className="ml-2 rounded-full bg-[#d9e6fb] px-2 py-0.5 text-sm text-[#2f4f87]">{selectedItem.result.sourceTraceability.length}</span>
                  </summary>
                  <div className="space-y-2 px-4 pb-4">
                    {selectedItem.result.sourceTraceability.map((item, index) => (
                      <div key={`${item.sourceLabel}-${index}`} className="rounded-xl border border-[#e1e8f3] bg-[#f8fbff] p-3">
                        <p className="inline-flex rounded-full border border-[#c9d9f0] bg-white px-2 py-0.5 text-[11px] font-semibold text-[#315b96]">
                          Por que este archivo
                        </p>
                        <p className="text-sm font-semibold text-[#1d335a]">{item.sourceLabel}</p>
                        <p className="text-xs text-[#5f7090]">{item.documentType}</p>
                        <p className="mt-1 text-xs text-[#4f6588]">Campos: {item.fields.join(", ") || "Sin campos reportados"}</p>
                      </div>
                    ))}
                  </div>
                </details>

                <Card className="border-[#d6e0ef] bg-[#f7f9fc]">
                  <CardContent className="flex flex-wrap items-center justify-between gap-3 p-4">
                    <div>
                      <p className="text-4xl font-semibold text-[#13274e] [font-family:var(--font-display)]">Listo para participar?</p>
                      <p className="text-xl text-[#5f7090]">Con el analisis completado, prepara tu propuesta en el Modulo 5</p>
                    </div>
                    <Link
                      href={
                        selectedItem.sourceLicitationId
                          ? `/gestion-licitaciones?sourceId=${encodeURIComponent(selectedItem.sourceLicitationId)}&autocreate=1&autofill=1`
                          : "/gestion-licitaciones"
                      }
                    >
                      <Button size="lg" className="rounded-2xl px-7">
                        Preparar Propuesta
                      </Button>
                    </Link>
                  </CardContent>
                </Card>
              </div>
            )}
          </CardContent>
        </Card>
      </section>
    </div>
  );
}
