import { Icon } from "@iconify/react";
import { useQuery } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import { getCobradoresActivos } from "../../../api/vendedores-cobradores.service";
import { getEmpresaMonedas } from "../../../api/monedas.service";
import {
    useEnviarTesoreriaMutation,
    useRendicionesQuery,
    useResumenDiarioQuery,
} from "../../../tanstack/RendicionesStack";
import { ScreenGuia } from "../../_standards";
import { CrearRendicionDialog } from "./CrearRendicionDialog";
import { DetalleRendicionDialog } from "./DetalleRendicionDialog";
import { RevisarRendicionDialog } from "./RevisarRendicionDialog";
import { hoyISO } from "../../../utils/fecha";

const GUIA_PASOS = [
  {
    icon: "lucide:file-plus-2",
    color: "#3b82f6",
    titulo: "1. Crear rendición",
    desc: "Cobrador selecciona los recibos del día y declara el total efectivamente recaudado. Queda en BORRADOR.",
  },
  {
    icon: "lucide:send",
    color: "#f59e0b",
    titulo: "2. Enviar a tesorería",
    desc: "Al enviar, la rendición pasa a PENDIENTE y queda lista para que Tesorería verifique cada medio de pago.",
  },
  {
    icon: "lucide:shield-check",
    color: "#22c55e",
    titulo: "3. Verificar y aprobar",
    desc: "Tesorería valida monto declarado vs cobrado por cada medio. Al aprobar, las comisiones del cobrador quedan liquidables.",
  },
  {
    icon: "lucide:alert-circle",
    color: "#ef4444",
    titulo: "4. Observar / Rechazar",
    desc: "Si hay diferencias o medios rechazados, se devuelve al cobrador (OBSERVADO) o se rechaza con motivo.",
  },
];
const GUIA_NOTAS = [
  { icon: "lucide:info", text: "Cada cobrador sólo puede tener una rendición activa (BORRADOR/PENDIENTE/OBSERVADO) a la vez." },
  { icon: "lucide:info", text: "Las comisiones quedan en estado 'aprobada' al aprobar la rendición; aparecerán en el tab 'Comisiones a liquidar'." },
  { icon: "lucide:info", text: "El código de la rendición es correlativo por empresa y se asigna automáticamente al crear." },
];

const MONEDAS_SIN_DECIMALES = ["PYG", "CLP", "JPY", "KRW", "ISK", "VND"];
const decimalesDe = (moneda) => {
  const cod = (moneda?.codigo || "PYG").toUpperCase();
  if (MONEDAS_SIN_DECIMALES.includes(cod)) return 0;
  return moneda?.decimales ?? moneda?.decimales_estandar ?? 2;
};
const simboloDe = (moneda) =>
  moneda?.simbolo || ((moneda?.codigo || "PYG").toUpperCase() === "PYG" ? "₲" : (moneda?.codigo || "₲"));
const formatMoney = (num, decimales = 0) =>
  new Intl.NumberFormat("es-PY", {
    minimumFractionDigits: decimales,
    maximumFractionDigits: decimales,
  }).format(num || 0);
const formatMonto = (num, moneda) =>
  `${simboloDe(moneda)} ${formatMoney(num, decimalesDe(moneda))}`;
const formatFecha = (fecha) => {
  if (!fecha) return "-";
  const d = new Date(fecha);
  if (isNaN(d.getTime())) return "-";
  return `${String(d.getUTCDate()).padStart(2, "0")}/${String(d.getUTCMonth() + 1).padStart(2, "0")}/${d.getUTCFullYear()}`;
};

const ESTADO_CONFIG = {
  BORRADOR: { icon: "lucide:file-edit", color: "#94a3b8", label: "Borrador" },
  PENDIENTE: { icon: "lucide:clock", color: "#f59e0b", label: "Pendiente" },
  OBSERVADO: { icon: "lucide:alert-circle", color: "#3b82f6", label: "Observado" },
  APROBADO: { icon: "lucide:check-circle", color: "#22c55e", label: "Aprobado" },
  RECHAZADO: { icon: "lucide:x-circle", color: "#ef4444", label: "Rechazado" },
  ANULADO: { icon: "lucide:ban", color: "#64748b", label: "Anulado" },
  // legacy fallbacks
  pendiente: { icon: "lucide:clock", color: "#f59e0b", label: "Pendiente" },
  aprobada: { icon: "lucide:check-circle", color: "#22c55e", label: "Aprobada" },
  rechazada: { icon: "lucide:x-circle", color: "#ef4444", label: "Rechazada" },
  con_observacion: { icon: "lucide:alert-circle", color: "#3b82f6", label: "Con Observación" },
};

const hoy = () => hoyISO();

// ── Styled Components ──────────────────────────────────────────────
const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
`;
const DateRow = styled.div`
  display: flex;
  align-items: center;
  gap: 0.75rem;
  input[type="date"] {
    background: ${(p) => p.theme.inputBg};
    border: 1px solid ${(p) => p.theme.inputBorder};
    border-radius: 8px;
    padding: 0.45rem 0.75rem;
    color: ${(p) => p.theme.text};
    font-size: 0.875rem;
    outline: none;
    font-family: inherit;
    &:focus {
      border-color: ${(p) => p.theme.primary};
      box-shadow: 0 0 0 3px ${(p) => p.theme.primary}20;
    }
  }
`;
const KpiGrid = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
`;
const KpiCard = styled.div`
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 12px;
  padding: 0.85rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  .icon-box {
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: ${(p) => p.$color}15;
    color: ${(p) => p.$color};
    font-size: 1.1rem;
    flex-shrink: 0;
  }
  .info {
    min-width: 0;
    .label {
      font-size: 0.72rem;
      color: ${(p) => p.theme.textSecondary};
      font-weight: 600;
      text-transform: uppercase;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .value {
      font-size: 1.1rem;
      font-weight: 700;
      color: ${(p) => p.$color};
      line-height: 1.3;
      white-space: nowrap;
    }
  }
`;
const SectionBar = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  .title {
    font-size: 1.05rem;
    font-weight: 700;
    color: ${(p) => p.theme.text};
  }
`;
const BtnGroup = styled.div`
  display: flex;
  gap: 0.5rem;
`;
const Btn = styled.button`
  padding: 0.45rem 1rem;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  transition: all 0.15s;
  border: 1px solid ${(p) => p.$border || "transparent"};
  background: ${(p) => p.$bg || "transparent"};
  color: ${(p) => p.$color || p.theme.text};
  &:hover {
    opacity: 0.85;
  }
`;
const FiltersBox = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) auto;
  gap: 0.75rem;
  background: ${(p) => p.theme.bg6};
  border-radius: 10px;
  padding: 0.85rem 1rem;
  align-items: end;
  select,
  input {
    background: ${(p) => p.theme.inputBg};
    border: 1px solid ${(p) => p.theme.inputBorder};
    border-radius: 8px;
    padding: 0.45rem 0.75rem;
    color: ${(p) => p.theme.text};
    font-size: 0.82rem;
    outline: none;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
    &:focus {
      border-color: ${(p) => p.theme.primary};
    }
  }
  label {
    font-size: 0.7rem;
    font-weight: 600;
    color: ${(p) => p.theme.textSecondary};
    text-transform: uppercase;
    margin-bottom: 0.25rem;
    display: block;
  }
`;
const DataTable = styled.div`
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 12px;
  overflow: hidden;
  table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
    th,
    td {
      padding: 0.6rem 0.85rem;
      text-align: left;
    }
    th {
      background: ${(p) => p.theme.bg6};
      font-weight: 700;
      color: ${(p) => p.theme.textSecondary};
      font-size: 0.72rem;
      text-transform: uppercase;
      letter-spacing: 0.05em;
      position: sticky;
      top: 0;
      z-index: 1;
    }
    tbody tr {
      border-bottom: 1px solid ${(p) => p.theme.borderColor};
      cursor: pointer;
      transition: background 0.12s;
      &:hover {
        background: ${(p) => p.theme.bgAlpha};
      }
      &:last-child {
        border-bottom: none;
      }
    }
    .right {
      text-align: right;
    }
    .center {
      text-align: center;
    }
    .bold {
      font-weight: 600;
    }
    .monto {
      white-space: nowrap;
    }
  }
`;
const Badge = styled.span`
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.6rem;
  border-radius: 20px;
  font-size: 0.7rem;
  font-weight: 600;
  color: ${(p) => p.$color};
  background: ${(p) => p.$color}14;
  border: 1px solid ${(p) => p.$color}30;
  white-space: nowrap;
`;
const ActionIcon = styled.button`
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  border-radius: 6px;
  display: flex;
  align-items: center;
  color: ${(p) => p.$color || p.theme.textSecondary};
  font-size: 1rem;
  &:hover {
    background: ${(p) => p.theme.bgAlpha};
    color: ${(p) => p.theme.text};
  }
`;
const EmptyRow = styled.div`
  padding: 2.5rem;
  text-align: center;
  color: ${(p) => p.theme.textSecondary};
  font-size: 0.85rem;
`;
const PaginationBar = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border-top: 1px solid ${(p) => p.theme.borderColor};
  font-size: 0.82rem;
  color: ${(p) => p.theme.textSecondary};
  button {
    background: none;
    border: 1px solid ${(p) => p.theme.borderColor};
    border-radius: 6px;
    padding: 0.3rem 0.8rem;
    cursor: pointer;
    color: ${(p) => p.theme.text};
    font-size: 0.78rem;
    &:disabled {
      opacity: 0.35;
      cursor: not-allowed;
    }
    &:not(:disabled):hover {
      background: ${(p) => p.theme.bgAlpha};
    }
  }
`;
const PrimaryBtn = styled.button`
  padding: 0.45rem 1rem;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  border: none;
  background: ${(p) => p.theme.primary};
  color: #fff;
  &:hover {
    opacity: 0.88;
  }
`;
const Spinner = styled(Icon)`
  animation: spin 1s linear infinite;
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
`;

// ── Panel principal ─────────────────────────────────────────────
export const RendicionesPanel = () => {
  const [fechaResumen, setFechaResumen] = useState(hoy());
  const [filters, setFilters] = useState({
    cobrador_id: "",
    fecha_desde: "",
    fecha_hasta: "",
    estado: "",
    moneda_id: "",
    page: 1,
    limit: 15,
  });
  const [showFilters, setShowFilters] = useState(false);
  const [crearOpen, setCrearOpen] = useState(false);
  const [detalleId, setDetalleId] = useState(null);
  const [revisarOpen, setRevisarOpen] = useState(null);

  const { data: resumen, isLoading: loadingResumen } =
    useResumenDiarioQuery(fechaResumen);
  const { data: rendicionesData, isLoading: loadingRendiciones } =
    useRendicionesQuery(filters);
  const rendiciones = rendicionesData?.data || [];
  const enviarMutation = useEnviarTesoreriaMutation();

  const { data: empresaMonedas = [] } = useQuery({
    queryKey: ["empresa-monedas"],
    queryFn: getEmpresaMonedas,
  });
  const monedasFiltro = useMemo(
    () =>
      empresaMonedas
        .filter((em) => em.active !== false && em.moneda)
        .map((em) => ({ ...em.moneda, es_principal: em.es_principal })),
    [empresaMonedas],
  );

  useEffect(() => {
    if (!filters.moneda_id && monedasFiltro.length > 0) {
      const principal = monedasFiltro.find((m) => m.es_principal);
      const pyg = monedasFiltro.find((m) => (m.codigo || "").toUpperCase() === "PYG");
      const elegida = principal?.id || pyg?.id || monedasFiltro[0].id;
      setFilters((f) => ({ ...f, moneda_id: elegida }));
    }
  }, [monedasFiltro, filters.moneda_id]);

  const kpis = useMemo(() => {
    if (!resumen) return [];
    const porMonedaAll = resumen.totales_por_moneda || [];
    const monedaActual =
      porMonedaAll.find((m) => m.moneda?.id === filters.moneda_id) ||
      { cobrado: 0, diferencia: 0, moneda: monedasFiltro.find((m) => m.id === filters.moneda_id) || null };
    const cobradoValue = formatMonto(monedaActual.cobrado, monedaActual.moneda);
    const difTotalSimple = formatMonto(monedaActual.diferencia, monedaActual.moneda);
    const algunaDifNeg = Number(monedaActual.diferencia || 0) < 0;
    return [
      {
        label: "Total Cobrado",
        value: cobradoValue,
        icon: "lucide:banknote",
        color: "#22c55e",
      },
      {
        label: "Rendiciones",
        value: resumen.total_rendiciones || 0,
        icon: "lucide:file-text",
        color: "#3b82f6",
      },
      {
        label: "Pendientes (Tesorería)",
        value:
          (resumen.por_estado?.pendientes || 0) +
          (resumen.por_estado?.observadas || 0),
        icon: "lucide:clock",
        color: "#f59e0b",
      },
      {
        label: "Borradores",
        value: resumen.por_estado?.borrador || 0,
        icon: "lucide:file-edit",
        color: "#94a3b8",
      },
      {
        label: "Diferencia",
        value: difTotalSimple,
        icon: !algunaDifNeg ? "lucide:check-circle" : "lucide:alert-triangle",
        color: !algunaDifNeg ? "#22c55e" : "#ef4444",
      },
    ];
  }, [resumen, filters.moneda_id, monedasFiltro]);

  const { data: cobradores = [] } = useQuery({
    queryKey: ["cobradores-activos"],
    queryFn: getCobradoresActivos,
    enabled: showFilters,
  });

  const set = (field, value) =>
    setFilters((f) => ({ ...f, [field]: value, page: 1 }));

  return (
    <Wrapper>
      <ScreenGuia
        titulo="¿Cómo funciona Rendiciones de Cobranza?"
        intro="Cobradores rinden lo recaudado en el día; Tesorería verifica cada medio de pago y aprueba para habilitar la liquidación de comisiones."
        pasos={GUIA_PASOS}
        notas={GUIA_NOTAS}
      />
      {/* Fecha + Moneda + KPIs */}
      <DateRow>
        <label
          style={{ fontSize: "0.75rem", fontWeight: 600, color: "inherit" }}
        >
          Fecha
        </label>
        <input
          type="date"
          value={fechaResumen}
          onChange={(e) => setFechaResumen(e.target.value)}
        />
        <label
          style={{ fontSize: "0.75rem", fontWeight: 600, color: "inherit", marginLeft: "1rem" }}
        >
          Moneda
        </label>
        <select
          value={filters.moneda_id}
          onChange={(e) => set("moneda_id", e.target.value)}
          style={{ padding: "0.4rem 0.6rem" }}
        >
          {monedasFiltro.map((m) => (
            <option key={m.id} value={m.id}>
              {m.codigo || m.descripcion}
            </option>
          ))}
        </select>
        {loadingResumen && (
          <Spinner icon="lucide:loader-2" style={{ fontSize: "1rem" }} />
        )}
      </DateRow>

      <KpiGrid>
        {kpis.map((k) => (
          <KpiCard key={k.label} $color={k.color}>
            <div className="icon-box">
              <Icon icon={k.icon} />
            </div>
            <div className="info">
              <div className="label">{k.label}</div>
              <div className="value">{k.value}</div>
            </div>
          </KpiCard>
        ))}
      </KpiGrid>

      {/* Toolbar */}
      <SectionBar>
        <span className="title">Rendiciones</span>
        <BtnGroup>
          <Btn
            $border="currentColor"
            $color="inherit"
            onClick={() => setShowFilters(!showFilters)}
          >
            <Icon icon="lucide:sliders-horizontal" /> Filtros
          </Btn>
          <PrimaryBtn onClick={() => setCrearOpen(true)}>
            <Icon icon="lucide:file-plus-2" /> Nueva Rendición
          </PrimaryBtn>
        </BtnGroup>
      </SectionBar>

      {/* Filtros */}
      {showFilters && (
        <FiltersBox>
          <div>
            <label>Cobrador</label>
            <select
              value={filters.cobrador_id}
              onChange={(e) => set("cobrador_id", e.target.value)}
            >
              <option value="">Todos</option>
              {cobradores.map((c) => (
                <option key={c.id} value={c.id}>
                  {`${c.nombre} ${c.apellido || ""}`.trim()}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label>Desde</label>
            <input
              type="date"
              value={filters.fecha_desde}
              onChange={(e) => set("fecha_desde", e.target.value)}
            />
          </div>
          <div>
            <label>Hasta</label>
            <input
              type="date"
              value={filters.fecha_hasta}
              onChange={(e) => set("fecha_hasta", e.target.value)}
            />
          </div>
          <div>
            <label>Estado</label>
            <select
              value={filters.estado}
              onChange={(e) => set("estado", e.target.value)}
            >
              <option value="">Todos</option>
              <option value="BORRADOR">Borrador</option>
              <option value="PENDIENTE">Pendiente</option>
              <option value="OBSERVADO">Observado</option>
              <option value="APROBADO">Aprobado</option>
              <option value="RECHAZADO">Rechazado</option>
              <option value="ANULADO">Anulado</option>
            </select>
          </div>
          <Btn
            $color="inherit"
            onClick={() =>
              setFilters((f) => ({
                cobrador_id: "",
                fecha_desde: "",
                fecha_hasta: "",
                estado: "",
                moneda_id: f.moneda_id,
                page: 1,
                limit: 15,
              }))
            }
          >
            <Icon icon="lucide:x" /> Limpiar
          </Btn>
        </FiltersBox>
      )}

      {/* Tabla */}
      <DataTable>
        <table>
          <thead>
            <tr>
              <th>Código</th>
              <th>Fecha</th>
              <th>Cobrador</th>
              <th className="center">Moneda</th>
              <th className="right">Declarado</th>
              <th className="right">Cobrado</th>
              <th className="right">Diferencia</th>
              <th>Estado</th>
              <th className="center">Acciones</th>
            </tr>
          </thead>
          <tbody>
            {loadingRendiciones ? (
              <tr>
                <td colSpan={9}>
                  <EmptyRow>
                    <Spinner
                      icon="lucide:loader-2"
                      style={{ fontSize: "1.2rem" }}
                    />{" "}
                    Cargando...
                  </EmptyRow>
                </td>
              </tr>
            ) : rendiciones.length === 0 ? (
              <tr>
                <td colSpan={9}>
                  <EmptyRow>
                    <Icon
                      icon="lucide:inbox"
                      style={{ fontSize: "1.5rem", marginBottom: 4 }}
                    />
                    <br />
                    No hay rendiciones para los filtros seleccionados
                  </EmptyRow>
                </td>
              </tr>
            ) : (
              rendiciones.map((r) => {
                const est =
                  ESTADO_CONFIG[r.estado] || ESTADO_CONFIG.PENDIENTE;
                const dif = Number(r.diferencia || 0);
                return (
                  <tr key={r.id} onClick={() => setDetalleId(r.id)}>
                    <td className="bold">{r.codigo || "—"}</td>
                    <td>{formatFecha(r.fecha_cobranza)}</td>
                    <td
                      style={{
                        display: "flex",
                        alignItems: "center",
                        gap: "0.35rem",
                      }}
                    >
                      <Icon
                        icon="lucide:user"
                        style={{
                          fontSize: "0.85rem",
                          flexShrink: 0,
                          opacity: 0.5,
                        }}
                      />
                      {r.cobrador
                        ? `${r.cobrador.nombre} ${r.cobrador.apellido || ""}`.trim()
                        : "-"}
                    </td>
                    <td className="center" style={{ fontSize: "0.75rem", opacity: 0.85 }}>
                      {r.moneda?.codigo || "—"}
                    </td>
                    <td className="right monto">
                      {formatMonto(r.total_declarado ?? r.monto_esperado, r.moneda)}
                    </td>
                    <td className="right monto bold">
                      {formatMonto(r.monto_cobrado, r.moneda)}
                    </td>
                    <td
                      className="right monto bold"
                      style={{ color: dif >= 0 ? "#22c55e" : "#ef4444" }}
                    >
                      {dif >= 0 ? "+" : ""}{formatMonto(dif, r.moneda)}
                    </td>
                    <td>
                      <Badge $color={est.color}>
                        <Icon icon={est.icon} style={{ fontSize: "0.75rem" }} />{" "}
                        {est.label}
                      </Badge>
                    </td>
                    <td className="center">
                      <div
                        style={{
                          display: "flex",
                          gap: "0.3rem",
                          justifyContent: "center",
                        }}
                      >
                        <ActionIcon
                          title="Ver detalle"
                          onClick={(e) => {
                            e.stopPropagation();
                            setDetalleId(r.id);
                          }}
                        >
                          <Icon icon="lucide:eye" />
                        </ActionIcon>
                        {(r.estado === "BORRADOR" ||
                          r.estado === "OBSERVADO") && (
                          <ActionIcon
                            $color="#f59e0b"
                            title="Enviar a tesorería"
                            onClick={(e) => {
                              e.stopPropagation();
                              enviarMutation.mutate({ id: r.id, data: {} });
                            }}
                          >
                            <Icon icon="lucide:send" />
                          </ActionIcon>
                        )}
                        {(r.estado === "PENDIENTE" ||
                          r.estado === "pendiente" ||
                          r.estado === "con_observacion") && (
                          <ActionIcon
                            $color="#3b82f6"
                            title="Revisar / Verificar"
                            onClick={(e) => {
                              e.stopPropagation();
                              setRevisarOpen(r);
                            }}
                          >
                            <Icon icon="lucide:clipboard-check" />
                          </ActionIcon>
                        )}
                      </div>
                    </td>
                  </tr>
                );
              })
            )}
          </tbody>
        </table>
        {rendicionesData?.totalPages > 1 && (
          <PaginationBar>
            <button
              disabled={rendicionesData.page <= 1}
              onClick={() => setFilters((f) => ({ ...f, page: f.page - 1 }))}
            >
              Anterior
            </button>
            <span>
              {rendicionesData.page} de {rendicionesData.totalPages}
            </span>
            <button
              disabled={rendicionesData.page >= rendicionesData.totalPages}
              onClick={() => setFilters((f) => ({ ...f, page: f.page + 1 }))}
            >
              Siguiente
            </button>
          </PaginationBar>
        )}
      </DataTable>

      {/* Diálogos */}
      {crearOpen && (
        <CrearRendicionDialog
          open={crearOpen}
          onClose={() => setCrearOpen(false)}
        />
      )}
      {detalleId && (
        <DetalleRendicionDialog
          id={detalleId}
          onClose={() => setDetalleId(null)}
          onRevisar={(r) => {
            setDetalleId(null);
            setRevisarOpen(r);
          }}
        />
      )}
      {revisarOpen && (
        <RevisarRendicionDialog
          rendicion={revisarOpen}
          onClose={() => setRevisarOpen(null)}
        />
      )}
    </Wrapper>
  );
};
