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 { MonedaInput } from "../../common/MonedaInput";
import { SearchableSelect } from "../../ui/SearchableSelect";
import { hoyISO } from "../../../utils/fecha";
import {
  useCrearRendicionMutation,
  useEnviarTesoreriaMutation,
  useRecibosDisponiblesQuery,
} from "../../../tanstack/RendicionesStack";

const formatMoney = (num, decimales = 0) =>
  new Intl.NumberFormat("es-PY", {
    minimumFractionDigits: decimales,
    maximumFractionDigits: decimales,
  }).format(num || 0);
const hoy = () => hoyISO();

// ── Styled Components ──────────────────────────────────────────────
const Overlay = styled.div`
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 1rem;
`;
const Dialog = styled.div`
  background: ${(p) => p.theme.bg2};
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 16px;
  width: 100%;
  max-width: 640px;
  max-height: 90vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  box-shadow: ${(p) => p.theme.boxshadow};
`;
const Header = styled.div`
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid ${(p) => p.theme.borderColor};
  flex-shrink: 0;
`;
const HeaderIcon = styled.div`
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 10px;
  background: ${(p) => p.theme.bg6};
  display: flex;
  align-items: center;
  justify-content: center;
  color: ${(p) => p.theme.primary};
  font-size: 1.1rem;
  flex-shrink: 0;
`;
const HeaderText = styled.div`
  flex: 1;
  h3 {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: ${(p) => p.theme.text};
  }
  p {
    margin: 0.15rem 0 0;
    font-size: 0.8rem;
    color: ${(p) => p.theme.textSecondary};
  }
`;
const CloseBtn = styled.button`
  background: none;
  border: none;
  cursor: pointer;
  color: ${(p) => p.theme.textSecondary};
  font-size: 1.1rem;
  padding: 0.3rem;
  border-radius: 6px;
  display: flex;
  align-items: center;
  transition:
    background 0.15s,
    color 0.15s;
  &:hover {
    background: ${(p) => p.theme.bgAlpha};
    color: ${(p) => p.theme.text};
  }
`;
const Body = styled.div`
  padding: 1.25rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
`;
const FieldGrid = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  @media (max-width: 500px) {
    grid-template-columns: 1fr;
  }
`;
const FormField = styled.div`
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  label {
    font-size: 0.78rem;
    color: ${(p) => p.theme.textSecondary};
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    svg {
      font-size: 0.85rem;
    }
  }
  input,
  select,
  textarea {
    background: ${(p) => p.theme.inputBg};
    border: 1px solid ${(p) => p.theme.inputBorder};
    border-radius: 8px;
    padding: 0.55rem 0.75rem;
    color: ${(p) => p.theme.text};
    font-size: 0.875rem;
    outline: none;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
    transition:
      border-color 0.15s,
      box-shadow 0.15s;
    &:focus {
      border-color: ${(p) => p.theme.primary};
      box-shadow: 0 0 0 3px ${(p) => p.theme.primary}20;
    }
    &::placeholder {
      color: ${(p) => p.theme.textSecondary}60;
    }
  }
  textarea {
    resize: vertical;
    min-height: 60px;
  }
`;
const FullField = styled(FormField)`
  grid-column: 1 / -1;
`;
const SectionLabel = styled.p`
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: ${(p) => p.theme.textSecondary};
  text-transform: uppercase;
  letter-spacing: 0.07em;
  display: flex;
  align-items: center;
  justify-content: space-between;
`;
const RecibosTable = styled.div`
  border: 1px solid ${(p) => p.theme.borderColor};
  border-radius: 10px;
  overflow: hidden;
  max-height: 260px;
  overflow-y: auto;
  table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
    th,
    td {
      padding: 0.5rem 0.75rem;
      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;
    }
    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;
      }
    }
    .monto {
      text-align: right;
      font-weight: 600;
      white-space: nowrap;
    }
  }
`;
const EmptyState = styled.div`
  padding: 1.5rem;
  text-align: center;
  color: ${(p) => p.theme.textSecondary};
  font-size: 0.85rem;
`;
const TotalBanner = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.65rem 1rem;
  border-radius: 10px;
  background: ${(p) => p.theme.primary}12;
  border: 1px solid ${(p) => p.theme.primary}30;
  font-size: 0.85rem;
  .total {
    font-weight: 700;
    color: ${(p) => p.theme.primary};
    font-size: 1rem;
  }
`;
const SelectAllBtn = styled.button`
  background: none;
  border: none;
  cursor: pointer;
  color: ${(p) => p.theme.primary};
  font-size: 0.75rem;
  font-weight: 600;
  &:hover {
    text-decoration: underline;
  }
`;
const Footer = styled.div`
  padding: 1rem 1.5rem;
  border-top: 1px solid ${(p) => p.theme.borderColor};
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  flex-shrink: 0;
  @media (max-width: 400px) {
    flex-direction: column-reverse;
    button {
      width: 100%;
      justify-content: center;
    }
  }
`;
const SecondaryBtn = styled.button`
  padding: 0.55rem 1.25rem;
  border-radius: 8px;
  border: 1px solid ${(p) => p.theme.borderColor};
  background: transparent;
  color: ${(p) => p.theme.textSecondary};
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.15s;
  &:hover {
    background: ${(p) => p.theme.bgAlpha};
    color: ${(p) => p.theme.text};
  }
`;
const PrimaryBtn = styled.button`
  padding: 0.55rem 1.4rem;
  border-radius: 8px;
  border: none;
  background: ${(p) => p.theme.primary};
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  transition: opacity 0.15s;
  &:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }
  &:not(:disabled):hover {
    opacity: 0.88;
  }
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
  .spin {
    animation: spin 1s linear infinite;
  }
`;
const Spinner = styled(Icon)`
  animation: spin 1s linear infinite;
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
`;

// ── Componente ─────────────────────────────────────────────────────
// Caso de uso: El cobrador o supervisor selecciona cobrador y fecha,
// el sistema busca recibos sin rendición y calcula los montos automáticamente.
export function CrearRendicionDialog({ open, onClose }) {
  const [cobradorId, setCobradorId] = useState("");
  const [monedaId, setMonedaId] = useState("");
  const [fecha, setFecha] = useState(hoy());
  const [observaciones, setObservaciones] = useState("");
  const [selectedRecibos, setSelectedRecibos] = useState([]);
  const [totalDeclarado, setTotalDeclarado] = useState("");
  const [enviarAlCrear, setEnviarAlCrear] = useState(true);

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

  const { data: empresaMonedas = [] } = useQuery({
    queryKey: ["empresa-monedas"],
    queryFn: getEmpresaMonedas,
  });

  // Solo monedas activas de la empresa (empresa_monedas → moneda)
  const monedas = useMemo(
    () =>
      empresaMonedas
        .filter((em) => em.active !== false && em.moneda)
        .map((em) => ({ ...em.moneda, es_principal: em.es_principal })),
    [empresaMonedas],
  );

  // Pre-seleccionar moneda principal de la empresa (o PYG, o la primera)
  useEffect(() => {
    if (!monedaId && monedas.length > 0) {
      const principal = monedas.find((m) => m.es_principal);
      const pyg = monedas.find((m) => (m.codigo || "").toUpperCase() === "PYG");
      setMonedaId(principal?.id || pyg?.id || monedas[0].id);
    }
  }, [monedas, monedaId]);

  const monedaSeleccionada = useMemo(
    () => monedas.find((m) => m.id === monedaId),
    [monedas, monedaId],
  );
  const codigoMoneda = (monedaSeleccionada?.codigo || "PYG").toUpperCase();
  // Monedas sin centavos — fallback duro si la DB trae mal el valor
  const MONEDAS_SIN_DECIMALES = ["PYG", "CLP", "JPY", "KRW", "ISK", "VND"];
  const decimalesMoneda = MONEDAS_SIN_DECIMALES.includes(codigoMoneda)
    ? 0
    : (monedaSeleccionada?.decimales ?? monedaSeleccionada?.decimales_estandar ?? 2);
  const simboloMoneda = monedaSeleccionada?.simbolo || (codigoMoneda === "PYG" ? "₲" : codigoMoneda);

  const { data: recibosDisponibles = [], isLoading: loadingRecibos } =
    useRecibosDisponiblesQuery(cobradorId, fecha, monedaId);

  const crearMutation = useCrearRendicionMutation();
  const enviarMutation = useEnviarTesoreriaMutation();

  // Auto-seleccionar todos los recibos cuando cambian los disponibles
  const recibosIds = useMemo(
    () => recibosDisponibles.map((r) => r.id).join(","),
    [recibosDisponibles],
  );
  useEffect(() => {
    if (recibosIds) {
      setSelectedRecibos(recibosIds.split(","));
    } else {
      setSelectedRecibos([]);
    }
  }, [recibosIds]);

  const toggleRecibo = (id) => {
    setSelectedRecibos((prev) =>
      prev.includes(id) ? prev.filter((r) => r !== id) : [...prev, id],
    );
  };

  const totalSeleccionado = useMemo(() => {
    const raw = recibosDisponibles
      .filter((r) => selectedRecibos.includes(r.id))
      .reduce((sum, r) => sum + Number(r.monto_total || 0), 0);
    // Redondeamos según los decimales de la moneda (PYG=0, USD=2…) para evitar diferencias falsas
    const factor = Math.pow(10, decimalesMoneda);
    return Math.round(raw * factor) / factor;
  }, [recibosDisponibles, selectedRecibos, decimalesMoneda]);

  // Desglose por medio de pago de los recibos seleccionados
  const desgloseMedios = useMemo(() => {
    const acc = { efectivo: 0, cheque: 0, transferencia: 0, tarjeta: 0, otro: 0 };
    recibosDisponibles
      .filter((r) => selectedRecibos.includes(r.id))
      .forEach((r) => {
        if (r.modo === "MULTI") {
          (r.medios_pago_multi || []).forEach((mp) => {
            const monto = Number(mp.monto || 0);
            const m = String(mp.medio || "").toUpperCase();
            if (m === "EFECTIVO") acc.efectivo += monto;
            else if (m === "CHEQUE") acc.cheque += monto;
            else if (m === "TRANSFERENCIA") acc.transferencia += monto;
            else if (m === "TARJETA") acc.tarjeta += monto;
            else acc.otro += monto;
          });
        } else {
          (r.recibo_cobro_detalle || []).forEach((det) => {
            const monto = Number(det.monto_pagado || 0);
            const codigo = det.medio_pago?.codigo;
            if (codigo === 1) acc.efectivo += monto;
            else if (codigo === 2) acc.cheque += monto;
            else if (codigo === 3 || codigo === 4) acc.tarjeta += monto;
            else if (codigo === 5) acc.transferencia += monto;
            else acc.otro += monto;
          });
        }
      });
    return acc;
  }, [recibosDisponibles, selectedRecibos]);

  // Sincronizar total_declarado con el total calculado cuando cambia la selección
  useEffect(() => {
    setTotalDeclarado(totalSeleccionado ? String(totalSeleccionado) : "");
  }, [totalSeleccionado]);

  const diferenciaDeclarada =
    Number(totalDeclarado || 0) - totalSeleccionado;

  const handleCrear = () => {
    crearMutation.mutate(
      {
        cobrador_id: cobradorId,
        moneda_id: monedaId,
        fecha_cobranza: fecha,
        recibo_ids: selectedRecibos.length > 0 ? selectedRecibos : undefined,
        total_declarado: totalDeclarado ? Number(totalDeclarado) : undefined,
        observaciones_cobrador: observaciones || undefined,
      },
      {
        onSuccess: (rendicion) => {
          if (enviarAlCrear && rendicion?.id) {
            enviarMutation.mutate(
              { id: rendicion.id, data: {} },
              { onSettled: () => onClose() },
            );
          } else {
            onClose();
          }
        },
      },
    );
  };

  if (!open) return null;

  return (
    <Overlay onClick={onClose}>
      <Dialog onClick={(e) => e.stopPropagation()}>
        <Header>
          <HeaderIcon>
            <Icon icon="lucide:file-plus-2" />
          </HeaderIcon>
          <HeaderText>
            <h3>Nueva Rendición de Cobranza</h3>
            <p>Seleccioná el cobrador y la fecha para generar la rendición</p>
          </HeaderText>
          <CloseBtn onClick={onClose}>
            <Icon icon="lucide:x" />
          </CloseBtn>
        </Header>

        <Body>
          <FieldGrid>
            <FormField>
              <label>
                <Icon icon="lucide:user" /> Cobrador *
              </label>
              <SearchableSelect
                options={cobradores.map((c) => ({
                  id: c.id,
                  label: `${c.nombre} ${c.apellido || ""}`.trim(),
                }))}
                value={cobradorId}
                onChange={(id) => {
                  setCobradorId(id || "");
                  setSelectedRecibos([]);
                }}
                placeholder="Buscar cobrador..."
                size="small"
              />
            </FormField>
            <FormField>
              <label>
                <Icon icon="lucide:coins" /> Moneda *
              </label>
              <SearchableSelect
                options={monedas.map((m) => ({
                  id: m.id,
                  label: `${m.codigo || ""} — ${m.descripcion || ""}`.trim(),
                }))}
                value={monedaId}
                onChange={(id) => {
                  setMonedaId(id || "");
                  setSelectedRecibos([]);
                }}
                placeholder="Buscar moneda..."
                size="small"
              />
            </FormField>
            <FormField>
              <label>
                <Icon icon="lucide:calendar" /> Fecha de Cobranza *
              </label>
              <input
                type="date"
                value={fecha}
                onChange={(e) => {
                  setFecha(e.target.value);
                  setSelectedRecibos([]);
                }}
              />
            </FormField>
            <FullField>
              <label>
                <Icon icon="lucide:message-square" /> Observaciones
              </label>
              <textarea
                value={observaciones}
                onChange={(e) => setObservaciones(e.target.value)}
                placeholder="Novedades, incidentes, comentarios del cobrador (opcional)"
                rows={2}
              />
            </FullField>
          </FieldGrid>

          {/* Recibos disponibles */}
          {cobradorId && (
            <div>
              <SectionLabel>
                Recibos disponibles ({recibosDisponibles.length})
                {recibosDisponibles.length > 0 && (
                  <SelectAllBtn
                    onClick={() =>
                      setSelectedRecibos(
                        selectedRecibos.length === recibosDisponibles.length
                          ? []
                          : recibosDisponibles.map((r) => r.id),
                      )
                    }
                  >
                    {selectedRecibos.length === recibosDisponibles.length
                      ? "Deseleccionar todos"
                      : "Seleccionar todos"}
                  </SelectAllBtn>
                )}
              </SectionLabel>

              {loadingRecibos ? (
                <EmptyState>
                  <Icon
                    icon="lucide:loader-2"
                    className="spin"
                    style={{ fontSize: "1.2rem" }}
                  />{" "}
                  Cargando recibos...
                </EmptyState>
              ) : recibosDisponibles.length === 0 ? (
                <EmptyState>
                  <Icon
                    icon="lucide:inbox"
                    style={{ fontSize: "1.5rem", marginBottom: 4 }}
                  />
                  <br />
                  No hay recibos sin rendición para esta fecha y cobrador
                </EmptyState>
              ) : (
                <RecibosTable>
                  <table>
                    <thead>
                      <tr>
                        <th style={{ width: 30 }} />
                        <th>Nro. Recibo</th>
                        <th>Cliente</th>
                        <th>Factura(s)</th>
                        <th className="monto">Monto</th>
                      </tr>
                    </thead>
                    <tbody>
                      {recibosDisponibles.map((recibo) => {
                        const sel = selectedRecibos.includes(recibo.id);
                        const fmtFac = (f) =>
                          f ? `${f.dest}-${f.dpunexp}-${f.dnumdoc}` : null;
                        const facturasMulti = (recibo.facturas_multi || [])
                          .map((m) => fmtFac(m.factura))
                          .filter(Boolean);
                        const facturasLegacy = (recibo.recibo_cobro_detalle || [])
                          .map((d) => fmtFac(d.factura_cuotas?.factura_cab))
                          .filter(Boolean);
                        const facturas = Array.from(
                          new Set([...facturasMulti, ...facturasLegacy]),
                        );
                        return (
                          <tr
                            key={recibo.id}
                            onClick={() => toggleRecibo(recibo.id)}
                            style={{
                              background: sel
                                ? "rgba(59,130,246,0.08)"
                                : undefined,
                            }}
                          >
                            <td>
                              <input type="checkbox" checked={sel} readOnly />
                            </td>
                            <td>{recibo.numero_recibo}</td>
                            <td>
                              {recibo.clientes?.personas?.razon_social || "-"}
                            </td>
                            <td style={{ fontSize: "0.75rem", opacity: 0.85 }}>
                              {facturas.length === 0
                                ? "-"
                                : facturas.length <= 2
                                  ? facturas.join(", ")
                                  : `${facturas.slice(0, 2).join(", ")} +${facturas.length - 2}`}
                            </td>
                            <td className="monto">
                              {simboloMoneda} {formatMoney(recibo.monto_total, decimalesMoneda)}
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </RecibosTable>
              )}

              {selectedRecibos.length > 0 && (
                <TotalBanner style={{ marginTop: "0.75rem" }}>
                  <span>
                    {selectedRecibos.length} recibo(s) seleccionado(s)
                  </span>
                  <span className="total">
                    Total: {simboloMoneda} {formatMoney(totalSeleccionado, decimalesMoneda)}
                  </span>
                </TotalBanner>
              )}

              {selectedRecibos.length > 0 && (
                <div
                  style={{
                    marginTop: "0.75rem",
                    display: "grid",
                    gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
                    gap: "0.5rem",
                    fontSize: "0.78rem",
                  }}
                >
                  {[
                    ["Efectivo", desgloseMedios.efectivo, "lucide:banknote"],
                    ["Cheque", desgloseMedios.cheque, "lucide:scroll-text"],
                    ["Transfer.", desgloseMedios.transferencia, "lucide:arrow-left-right"],
                    ["Tarjeta", desgloseMedios.tarjeta, "lucide:credit-card"],
                    ...(desgloseMedios.otro > 0
                      ? [["Otro", desgloseMedios.otro, "lucide:more-horizontal"]]
                      : []),
                  ].map(([label, monto, icon]) => (
                    <div
                      key={label}
                      style={{
                        border: "1px solid rgba(148,163,184,0.25)",
                        borderRadius: 8,
                        padding: "0.45rem 0.55rem",
                        display: "flex",
                        alignItems: "center",
                        gap: 6,
                      }}
                    >
                      <Icon icon={icon} />
                      <div style={{ display: "flex", flexDirection: "column" }}>
                        <span style={{ opacity: 0.7 }}>{label}</span>
                        <strong>{simboloMoneda} {formatMoney(monto, decimalesMoneda)}</strong>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          {selectedRecibos.length > 0 && (
            <FormField>
              <label>
                <Icon icon="lucide:wallet" /> Total declarado ({simboloMoneda}) *
              </label>
              <MonedaInput
                value={Number(totalDeclarado) || 0}
                onChange={(n) => setTotalDeclarado(n ? String(n) : "")}
                moneda={codigoMoneda}
                placeholder="Ej: 1.250.000"
                fullWidth
              />
              <small
                style={{
                  fontSize: "0.72rem",
                  color:
                    diferenciaDeclarada === 0
                      ? "#22c55e"
                      : Math.abs(diferenciaDeclarada) < 1
                        ? "#f59e0b"
                        : "#ef4444",
                  marginTop: 4,
                }}
              >
                {diferenciaDeclarada === 0
                  ? "✓ Coincide con el total cobrado"
                  : `Diferencia vs. cobrado: ${simboloMoneda} ${formatMoney(diferenciaDeclarada, decimalesMoneda)}`}
              </small>
            </FormField>
          )}

          {selectedRecibos.length > 0 && (
            <label
              style={{
                display: "flex",
                alignItems: "center",
                gap: 8,
                fontSize: "0.85rem",
                cursor: "pointer",
              }}
            >
              <input
                type="checkbox"
                checked={enviarAlCrear}
                onChange={(e) => setEnviarAlCrear(e.target.checked)}
              />
              Enviar a tesorería al crear (si no, queda como BORRADOR)
            </label>
          )}
        </Body>

        <Footer>
          <SecondaryBtn onClick={onClose}>Cancelar</SecondaryBtn>
          <PrimaryBtn
            onClick={handleCrear}
            disabled={crearMutation.isPending || !cobradorId || !fecha || !monedaId || selectedRecibos.length === 0}
          >
            {crearMutation.isPending || enviarMutation.isPending ? (
              <>
                <Spinner icon="lucide:loader-2" />{" "}
                {enviarMutation.isPending ? "Enviando..." : "Creando..."}
              </>
            ) : (
              <>
                <Icon icon="lucide:file-check" />{" "}
                {enviarAlCrear ? "Crear y enviar" : "Crear borrador"}
              </>
            )}
          </PrimaryBtn>
        </Footer>
      </Dialog>
    </Overlay>
  );
}
