import { Icon } from "@iconify/react";
import { useEffect, useMemo, useRef, useState } from "react";
import styled from "styled-components";
import { EmptyState, ScreenGuia } from "../_standards";
import { fmtMonedaFina } from "../_standards/enums/monedas";
import { aFechaISO, fmtFechaHora } from "../../utils/fecha";
import { Badge, BotonSecundario, Encabezado } from "./estilos";
import { renderRespuesta } from "./renderRespuesta";
import {
  AUTOR_MENSAJE,
  CATEGORIA_TICKET,
  estadoVisual,
  MOTIVO_NO_RESUELTO,
  RESULTADO_TICKET,
  RESULTADOS_FILTRO,
} from "./soporteIa.enums";
import {
  useEtiquetaMutation,
  useReporteDetalleQuery,
  useReporteResumenQuery,
  useReporteTicketsQuery,
  useSesionSoporteQuery,
} from "./useSoporteIa";

const GUIA_PASOS = [
  {
    icon: "lucide:gauge",
    color: "#3b82f6",
    titulo: "Autoresolución",
    desc: "Consultas que el agente resolvió (con o sin indicaciones) sobre las consultas reales. Los saludos no cuentan; las abandonadas sí, como no resueltas.",
  },
  {
    icon: "lucide:circle-alert",
    color: "#f59e0b",
    titulo: "Lista de trabajo",
    desc: "Los no resueltos por motivo son lo que hay que mejorar. Si un motivo aparece en varias empresas a la vez, probablemente es una falla de la plataforma.",
  },
  {
    icon: "lucide:check-check",
    color: "#22c55e",
    titulo: "Golden set",
    desc: "Marcá cada respuesta como correcta o incorrecta. Las correctas forman el golden set: ningún cambio de prompt o modelo se despliega sin pasarlo.",
  },
];

const DIAS_RAPIDOS = [7, 30, 90];

const restarDias = (dias) => aFechaISO(new Date(Date.now() - dias * 86_400_000));

const pct = (v) => (v === null || v === undefined ? "—" : `${Math.round(v * 100)}%`);
const seg = (ms) => (ms === null || ms === undefined ? "—" : `${(ms / 1000).toFixed(1)} s`);

export function ReporteSoporteIaPage() {
  const { data: sesion, isLoading: cargandoSesion } = useSesionSoporteQuery();
  const habilitado = !!sesion?.es_novasis;

  const [rango, setRango] = useState({ desde: restarDias(30), hasta: aFechaISO(new Date()) });
  const [filtros, setFiltros] = useState({ resultado: "", motivo: "", pagina: 1 });
  const [abierto, setAbierto] = useState(null);

  const { data: resumen, isLoading: cargandoResumen } = useReporteResumenQuery(rango, habilitado);
  const { data: lista } = useReporteTicketsQuery({ ...rango, ...filtros }, habilitado);

  if (cargandoSesion) return <Pantalla>Cargando…</Pantalla>;
  if (!habilitado) {
    return (
      <Pantalla>
        <EmptyState
          icon="lucide:lock"
          title="Solo para el equipo de Novasis"
          description="Este reporte lo ve únicamente el superadministrador de la empresa Novasis."
        />
      </Pantalla>
    );
  }

  const t = resumen?.totales;
  const totalPaginas = lista ? Math.max(1, Math.ceil(lista.total / lista.tam)) : 1;

  return (
    <Pantalla>
      <Encabezado>
        <div className="icono">
          <Icon icon="lucide:chart-no-axes-combined" />
        </div>
        <div>
          <h1>Reporte de Soporte IA</h1>
          <p>Qué resolvió el agente, qué no y por qué. Todas las empresas.</p>
        </div>
      </Encabezado>

      <ScreenGuia titulo="¿Cómo leer este reporte?" pasos={GUIA_PASOS} />

      <Filtros>
        <div className="rapidos" role="group" aria-label="Rango rápido">
          {DIAS_RAPIDOS.map((d) => (
            <BotonSecundario
              key={d}
              type="button"
              onClick={() => {
                setRango({ desde: restarDias(d), hasta: aFechaISO(new Date()) });
                setFiltros((f) => ({ ...f, pagina: 1 }));
              }}
            >
              Últimos {d} días
            </BotonSecundario>
          ))}
        </div>
        <label>
          <span>
            <Icon icon="lucide:calendar" /> Desde
          </span>
          <input
            type="date"
            value={rango.desde}
            onChange={(e) => setRango((r) => ({ ...r, desde: e.target.value }))}
          />
        </label>
        <label>
          <span>
            <Icon icon="lucide:calendar" /> Hasta
          </span>
          <input type="date" value={rango.hasta} onChange={(e) => setRango((r) => ({ ...r, hasta: e.target.value }))} />
        </label>
      </Filtros>

      {cargandoResumen || !t ? (
        <div>Cargando…</div>
      ) : (
        <>
          <KpiGrid role="group" aria-label="Indicadores">
            <Kpi
              icono="lucide:gauge"
              color="#3b82f6"
              label="Autoresolución"
              valor={pct(t.autoresolucion)}
              ayuda={`${t.resueltos} de ${t.consultas_reales} consultas reales`}
            />
            <Kpi
              icono="lucide:list-checks"
              color="#22c55e"
              label="Con indicaciones"
              valor={t.con_indicaciones}
              ayuda="El cliente lo resolvió con la guía del agente"
            />
            <Kpi
              icono="lucide:circle-alert"
              color="#f59e0b"
              label="Sin resolver"
              valor={t.no_resueltos}
              ayuda={`${t.abandonados} abandonadas a mitad de camino`}
            />
            <Kpi
              icono="lucide:thumbs-up"
              color="#22c55e"
              label="Conformidad"
              valor={pct(t.tasa_conformidad_positiva)}
              ayuda={`${t.conformidad_positiva} 👍 · ${t.conformidad_negativa} 👎`}
            />
            <Kpi
              icono="lucide:timer"
              color="#94a3b8"
              label="Primer texto (p50)"
              valor={seg(resumen.latencia.primer_texto_p50_ms)}
              ayuda={`p95 ${seg(resumen.latencia.primer_texto_p95_ms)}`}
            />
            <Kpi
              icono="lucide:coins"
              color="#94a3b8"
              label="Costo"
              valor={fmtMonedaFina(resumen.costo_usd, "USD")}
              ayuda={`${t.empresas} empresas · ${t.tickets} tickets`}
            />
          </KpiGrid>

          {resumen.fallas_en_varias_empresas.length > 0 && (
            <Aviso role="alert">
              <Icon icon="lucide:siren" className="icono" />
              <div>
                <strong>Posible falla de la plataforma</strong>
                {resumen.fallas_en_varias_empresas.map((f) => (
                  <p key={f.motivo}>
                    {MOTIVO_NO_RESUELTO[f.motivo] ?? f.motivo}: {f.tickets} consultas en {f.empresas} empresas en
                    la última semana ({f.ejemplos.join(", ")}).
                  </p>
                ))}
              </div>
            </Aviso>
          )}

          <DosColumnas>
            <Tarjeta>
              <h2>Sin resolver, por motivo</h2>
              {resumen.no_resueltos_por_motivo.length === 0 ? (
                <p className="vacio">Nada sin resolver en este rango.</p>
              ) : (
                <Tabla>
                  <tbody>
                    {resumen.no_resueltos_por_motivo.map((m) => (
                      <tr
                        key={m.motivo}
                        className="clic"
                        onClick={() => setFiltros({ resultado: "NO_RESUELTO", motivo: m.motivo, pagina: 1 })}
                      >
                        <td>{MOTIVO_NO_RESUELTO[m.motivo] ?? m.motivo}</td>
                        <td className="num">{m.tickets}</td>
                        <td className="num tenue">{m.empresas} emp.</td>
                      </tr>
                    ))}
                  </tbody>
                </Tabla>
              )}
            </Tarjeta>
            <Tarjeta>
              <h2>Por empresa</h2>
              <Tabla>
                <thead>
                  <tr>
                    <th>Empresa</th>
                    <th className="num">Consultas</th>
                    <th className="num">Resueltas</th>
                    <th className="num">Costo</th>
                  </tr>
                </thead>
                <tbody>
                  {resumen.por_empresa.map((e) => (
                    <tr key={e.empresa_id}>
                      <td>{e.empresa ?? e.ruc}</td>
                      <td className="num">{e.tickets}</td>
                      <td className="num">{e.resueltos}</td>
                      <td className="num">{fmtMonedaFina(e.costo_usd, "USD")}</td>
                    </tr>
                  ))}
                </tbody>
              </Tabla>
            </Tarjeta>
          </DosColumnas>
        </>
      )}

      <Tarjeta>
        <div className="barra">
          <h2>Consultas</h2>
          <label>
            <span>Resultado</span>
            <select
              value={filtros.resultado}
              onChange={(e) => setFiltros((f) => ({ ...f, resultado: e.target.value, pagina: 1 }))}
            >
              <option value="">Todos</option>
              {RESULTADOS_FILTRO.map((r) => (
                <option key={r} value={r}>
                  {RESULTADO_TICKET[r].label}
                </option>
              ))}
            </select>
          </label>
          <label>
            <span>Motivo</span>
            <select
              value={filtros.motivo}
              onChange={(e) => setFiltros((f) => ({ ...f, motivo: e.target.value, pagina: 1 }))}
            >
              <option value="">Todos</option>
              {Object.entries(MOTIVO_NO_RESUELTO).map(([k, v]) => (
                <option key={k} value={k}>
                  {v}
                </option>
              ))}
            </select>
          </label>
        </div>
        {!lista || lista.tickets.length === 0 ? (
          <EmptyState compact icon="lucide:inbox" title="No hay consultas con estos filtros" />
        ) : (
          <>
            <Tabla>
              <thead>
                <tr>
                  <th>Ticket</th>
                  <th>Empresa</th>
                  <th>Consulta</th>
                  <th>Categoría</th>
                  <th>Resultado</th>
                  <th>Fecha</th>
                </tr>
              </thead>
              <tbody>
                {lista.tickets.map((x) => {
                  const visual = estadoVisual(x);
                  return (
                    <tr key={x.id} className="clic" onClick={() => setAbierto(x.id)}>
                      <td>SOP-{x.numero}</td>
                      <td>{x.empresa_razon_social ?? x.empresa_ruc}</td>
                      <td className="consulta">{x.titulo}</td>
                      <td>{CATEGORIA_TICKET[x.categoria] ?? "—"}</td>
                      <td>
                        <Badge $color={visual.color}>
                          <Icon icon={visual.icon} /> {visual.label}
                        </Badge>
                        {x.motivo_no_resuelto && (
                          <div className="tenue">{MOTIVO_NO_RESUELTO[x.motivo_no_resuelto]}</div>
                        )}
                      </td>
                      <td className="tenue">{fmtFechaHora(x.created_at)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </Tabla>
            <Paginacion>
              <BotonSecundario
                type="button"
                disabled={filtros.pagina <= 1}
                onClick={() => setFiltros((f) => ({ ...f, pagina: f.pagina - 1 }))}
              >
                <Icon icon="lucide:chevron-left" /> Anterior
              </BotonSecundario>
              <span>
                Página {filtros.pagina} de {totalPaginas} · {lista.total} consultas
              </span>
              <BotonSecundario
                type="button"
                disabled={filtros.pagina >= totalPaginas}
                onClick={() => setFiltros((f) => ({ ...f, pagina: f.pagina + 1 }))}
              >
                Siguiente <Icon icon="lucide:chevron-right" />
              </BotonSecundario>
            </Paginacion>
          </>
        )}
      </Tarjeta>

      {abierto && <DetalleTicket id={abierto} onCerrar={() => setAbierto(null)} />}
    </Pantalla>
  );
}

// eslint-disable-next-line react/prop-types
function Kpi({ icono, color, label, valor, ayuda }) {
  return (
    <KpiCard $color={color}>
      <div className="icono">
        <Icon icon={icono} />
      </div>
      <div>
        <div className="label">{label}</div>
        <div className="valor">{valor}</div>
        {ayuda && <div className="ayuda">{ayuda}</div>}
      </div>
    </KpiCard>
  );
}

// eslint-disable-next-line react/prop-types
function DetalleTicket({ id, onCerrar }) {
  const { data: t, isLoading } = useReporteDetalleQuery(id);
  const etiqueta = useEtiquetaMutation();
  const dialogo = useRef(null);
  const trazasPorTurno = useMemo(() => {
    const mapa = new Map();
    for (const tr of t?.trazas ?? []) {
      const lista = mapa.get(tr.mensaje_orden) ?? [];
      lista.push(tr);
      mapa.set(tr.mensaje_orden, lista);
    }
    return mapa;
  }, [t]);

  useEffect(() => {
    dialogo.current?.focus();
    const esc = (e) => e.key === "Escape" && onCerrar();
    window.addEventListener("keydown", esc);
    return () => window.removeEventListener("keydown", esc);
  }, [onCerrar]);

  return (
    <Overlay onClick={onCerrar}>
      <Dialogo
        role="dialog"
        aria-modal="true"
        aria-labelledby="detalle-ticket-titulo"
        tabIndex={-1}
        ref={dialogo}
        onClick={(e) => e.stopPropagation()}
      >
        <div className="cabecera">
          <div>
            <h2 id="detalle-ticket-titulo">{t ? `SOP-${t.numero} · ${t.empresa_razon_social ?? t.empresa_ruc}` : "…"}</h2>
            {t && (
              <p>
                {t.usuario_nombre} · {fmtFechaHora(t.created_at)} · {t.prompt_version} · {t.modelo}
              </p>
            )}
          </div>
          <button type="button" className="cerrar" aria-label="Cerrar" onClick={onCerrar}>
            <Icon icon="lucide:x" />
          </button>
        </div>
        {isLoading || !t ? (
          <p>Cargando…</p>
        ) : (
          <div className="cuerpo">
            {t.mensajes.map((m) => (
              <div key={m.orden} className={`mensaje ${m.autor}`}>
                <div className="quien">
                  {m.autor === AUTOR_MENSAJE.CLIENTE ? "Cliente" : m.autor === AUTOR_MENSAJE.BOT ? "Agente" : "Sistema"}
                  {m.autor === AUTOR_MENSAJE.BOT && (
                    <span className="tenue">
                      {" "}
                      · {seg(m.primer_token_ms)} al primer texto · {m.tokens_in}+{m.tokens_out} tokens ·{" "}
                      {fmtMonedaFina(m.costo_usd, "USD")}
                    </span>
                  )}
                </div>
                <div className="texto">{m.autor === AUTOR_MENSAJE.CLIENTE ? m.texto : renderRespuesta(m.texto)}</div>
                {m.autor === AUTOR_MENSAJE.BOT && (
                  <>
                    {(trazasPorTurno.get(m.orden) ?? []).map((tr) => (
                      <details key={tr.id} className="traza">
                        <summary>
                          <Icon icon={tr.fuera_de_alcance ? "lucide:shield-alert" : "lucide:database"} />{" "}
                          {tr.herramienta} · {tr.duracion_ms} ms
                          {tr.error ? ` · error: ${tr.error}` : ""}
                        </summary>
                        <pre>{JSON.stringify({ parametros: tr.parametros, vio_el_agente: tr.proyeccion }, null, 2)}</pre>
                      </details>
                    ))}
                    <div className="etiqueta" role="group" aria-label="¿La respuesta es correcta?">
                      <span>¿Correcta?</span>
                      <button
                        type="button"
                        aria-pressed={m.correcta === true}
                        className={m.correcta === true ? "si activo" : "si"}
                        onClick={() => etiqueta.mutate({ id: t.id, orden: m.orden, correcta: m.correcta === true ? null : true })}
                      >
                        <Icon icon="lucide:check" /> Sí
                      </button>
                      <button
                        type="button"
                        aria-pressed={m.correcta === false}
                        className={m.correcta === false ? "no activo" : "no"}
                        onClick={() =>
                          etiqueta.mutate({ id: t.id, orden: m.orden, correcta: m.correcta === false ? null : false })
                        }
                      >
                        <Icon icon="lucide:x" /> No
                      </button>
                    </div>
                  </>
                )}
              </div>
            ))}
          </div>
        )}
      </Dialogo>
    </Overlay>
  );
}

// ── Estilos ──────────────────────────────────────────────────────────

const Pantalla = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  color: ${(p) => p.theme.text};
`;

const Filtros = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
  .rapidos {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
  }
  label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    span {
      font-size: 0.78rem;
      font-weight: 600;
      color: ${(p) => p.theme.textSecondary};
      display: inline-flex;
      align-items: center;
      gap: 0.3rem;
    }
  }
  input {
    min-width: 150px;
    color: ${(p) => p.theme.text};
    background: ${(p) => p.theme.inputBg};
    border: 1px solid ${(p) => p.theme.inputBorder};
    border-radius: 8px;
    padding: 0.45rem 0.75rem;
  }
`;

const KpiGrid = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.75rem;
`;

const KpiCard = styled.div`
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  padding: 0.8rem;
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 12px;
  background: ${(p) => p.theme.bg2};
  .icono {
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 10px;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    color: ${(p) => p.$color};
    background: ${(p) => `${p.$color}26`};
  }
  .label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    color: ${(p) => p.theme.textSecondary};
  }
  .valor {
    font-size: 1.1rem;
    font-weight: 700;
  }
  .ayuda {
    font-size: 0.72rem;
    color: ${(p) => p.theme.textSecondary};
  }
`;

const Aviso = styled.div`
  display: flex;
  gap: 0.75rem;
  padding: 0.8rem 1rem;
  border-radius: 12px;
  border: 1px solid #ef4444;
  background: #ef444414;
  font-size: 0.85rem;
  .icono {
    color: #ef4444;
    font-size: 1.4rem;
    flex-shrink: 0;
  }
  p {
    margin: 0.25rem 0 0;
  }
`;

const DosColumnas = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
`;

const Tarjeta = styled.section`
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 12px;
  background: ${(p) => p.theme.bg2};
  padding: 0.9rem 1rem;
  overflow-x: auto;
  h2 {
    font-size: 0.9rem;
    font-weight: 700;
    margin: 0 0 0.6rem;
  }
  .vacio {
    font-size: 0.85rem;
    color: ${(p) => p.theme.textSecondary};
  }
  .barra {
    display: flex;
    gap: 0.75rem;
    align-items: flex-end;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
    h2 {
      margin: 0 auto 0 0;
    }
    label {
      display: flex;
      flex-direction: column;
      gap: 0.2rem;
      font-size: 0.78rem;
      font-weight: 600;
      color: ${(p) => p.theme.textSecondary};
    }
    select {
      min-width: 180px;
      color: ${(p) => p.theme.text};
      background: ${(p) => p.theme.inputBg};
      border: 1px solid ${(p) => p.theme.inputBorder};
      border-radius: 8px;
      padding: 0.4rem 0.6rem;
    }
  }
`;

const Tabla = styled.table`
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  th {
    text-align: left;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    color: ${(p) => p.theme.textSecondary};
    padding: 0.4rem 0.5rem;
    border-bottom: 1px solid ${(p) => p.theme.borderColor};
  }
  td {
    padding: 0.45rem 0.5rem;
    border-bottom: 1px solid ${(p) => p.theme.borderColor};
    vertical-align: top;
  }
  .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  .tenue {
    color: ${(p) => p.theme.textSecondary};
    font-size: 0.78rem;
  }
  .consulta {
    max-width: 360px;
  }
  tr.clic {
    cursor: pointer;
    &:hover {
      background: ${(p) => p.theme.bgAlpha};
    }
  }
`;

const Paginacion = styled.div`
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.6rem;
  font-size: 0.8rem;
  color: ${(p) => p.theme.textSecondary};
`;

const Overlay = styled.div`
  position: fixed;
  inset: 0;
  z-index: 1300;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
  display: grid;
  place-items: center;
  padding: 1rem;
`;

const Dialogo = styled.div`
  width: min(860px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  border-radius: 16px;
  background: ${(p) => p.theme.bg};
  color: ${(p) => p.theme.text};
  padding: 1.25rem 1.5rem;
  outline: none;
  .cabecera {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    h2 {
      margin: 0;
      font-size: 1rem;
      font-weight: 700;
    }
    p {
      margin: 0.2rem 0 0;
      font-size: 0.78rem;
      color: ${(p) => p.theme.textSecondary};
    }
  }
  .cerrar {
    all: unset;
    cursor: pointer;
    font-size: 1.2rem;
    color: ${(p) => p.theme.textSecondary};
  }
  .cuerpo {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    margin-top: 1rem;
  }
  .mensaje {
    border: 1px solid ${(p) => p.theme.borderColor};
    border-radius: 10px;
    padding: 0.6rem 0.8rem;
    font-size: 0.85rem;
  }
  .mensaje.cliente {
    background: ${(p) => p.theme.bg6};
  }
  .quien {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    margin-bottom: 0.3rem;
  }
  .tenue {
    color: ${(p) => p.theme.textSecondary};
    text-transform: none;
    font-weight: 400;
  }
  .texto p {
    margin: 0 0 0.35rem;
  }
  .texto ol,
  .texto ul {
    margin: 0.2rem 0 0.4rem 1.2rem;
    padding: 0;
  }
  .traza {
    margin-top: 0.4rem;
    font-size: 0.78rem;
    color: ${(p) => p.theme.textSecondary};
    summary {
      cursor: pointer;
    }
    pre {
      white-space: pre-wrap;
      word-break: break-word;
      background: ${(p) => p.theme.bg6};
      border-radius: 8px;
      padding: 0.5rem;
      max-height: 280px;
      overflow: auto;
    }
  }
  .etiqueta {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.5rem;
    font-size: 0.78rem;
    color: ${(p) => p.theme.textSecondary};
    button {
      display: inline-flex;
      align-items: center;
      gap: 0.25rem;
      cursor: pointer;
      border-radius: 8px;
      padding: 0.2rem 0.6rem;
      border: 1px solid ${(p) => p.theme.borderColor};
      background: transparent;
      color: ${(p) => p.theme.text};
    }
    .si.activo {
      border-color: #22c55e;
      color: #22c55e;
      background: #22c55e1a;
    }
    .no.activo {
      border-color: #ef4444;
      color: #ef4444;
      background: #ef44441a;
    }
  }
`;
