import { Icon } from "@iconify/react";
import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, Typography } from "@mui/material";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { toast } from "sonner";
import { registrarTipoCambio } from "../../api/contabilidad.service";
import { createCotizacion, getCotizacionesPendientesHoy } from "../../api/monedas.service";
import { usePermission } from "../../hooks/usePermission";
import { fmtFechaCalendario, hoyISO } from "../../utils/fecha";
import { MonedaInput } from "../common/MonedaInput";

// "Más tarde" vale para el día: mañana vuelve a preguntar.
const CLAVE_POSPUESTO = "cotizacion_diaria_pospuesta";
const pospuestoHoy = () => {
  try {
    return localStorage.getItem(CLAVE_POSPUESTO) === hoyISO();
  } catch {
    return false;
  }
};

/**
 * Aviso diario: si la empresa trabaja con una moneda distinta de PYG y todavía
 * no se cargó la cotización de hoy, la pide al entrar. Solo a quien puede
 * cargarla. Se guarda en Configuración → Monedas y en Contabilidad → Tipo de
 * Cambio a la vez (el backend sincroniza las dos); la venta es la tasa contable.
 */
export const CotizacionDiariaDialog = () => {
  const { can: canContab } = usePermission("CONTABILIDAD");
  const { can: canAdmin } = usePermission("ADMINISTRACION");
  // Con ADM_COTIZ_REGISTRAR se carga compra y venta (Configuración → Monedas).
  // Con solo CONT_TC_TIPO_CAMBIO_CREAR se carga la tasa por Contabilidad: el
  // backend la copia como venta a Configuración.
  const viaConfiguracion = canAdmin("ADM_COTIZ_REGISTRAR");
  const puedeCargar = viaConfiguracion || canContab("CONT_TC_TIPO_CAMBIO_CREAR");

  const hoy = hoyISO();
  const [pospuesto, setPospuesto] = useState(pospuestoHoy);
  const [valores, setValores] = useState({}); // { [moneda_id]: { compra, venta } }
  const [guardando, setGuardando] = useState(false);
  const queryClient = useQueryClient();

  const { data } = useQuery({
    queryKey: ["cotizaciones-pendientes-hoy", hoy],
    queryFn: () => getCotizacionesPendientesHoy(hoy),
    enabled: puedeCargar && !pospuesto,
    staleTime: 10 * 60 * 1000,
  });
  const pendientes = data?.pendientes ?? [];

  if (!puedeCargar || pospuesto || pendientes.length === 0) return null;

  const valor = (m, campo) => valores[m.moneda_id]?.[campo] ?? (m.ultima ? m.ultima[campo] : 0);
  const setValor = (m, campo, v) =>
    setValores((prev) => ({ ...prev, [m.moneda_id]: { compra: valor(m, "compra"), venta: valor(m, "venta"), ...prev[m.moneda_id], [campo]: v } }));
  const completo = pendientes.every(
    (m) => Number(valor(m, "venta")) > 0 && (!viaConfiguracion || Number(valor(m, "compra")) > 0),
  );

  const posponer = () => {
    try {
      localStorage.setItem(CLAVE_POSPUESTO, hoy);
    } catch {
      // Sin storage: vuelve a aparecer al recargar, no es grave.
    }
    setPospuesto(true);
  };

  const guardar = async () => {
    setGuardando(true);
    try {
      for (const m of pendientes) {
        if (viaConfiguracion) {
          await createCotizacion({
            moneda_id: m.moneda_id,
            fecha: hoy,
            cotizacion_compra: Number(valor(m, "compra")),
            cotizacion_venta: Number(valor(m, "venta")),
          });
        } else {
          await registrarTipoCambio({ moneda: m.codigo, fecha: hoy, tasa: Number(valor(m, "venta")) });
        }
      }
      toast.success("Cotización del día registrada");
      queryClient.invalidateQueries({ queryKey: ["cotizaciones-pendientes-hoy"] });
      queryClient.invalidateQueries({ queryKey: ["cotizaciones"] });
      queryClient.invalidateQueries({ queryKey: ["tipos-cambio"] });
    } catch (err) {
      toast.error(err?.response?.data?.message || "No se pudo registrar la cotización");
    } finally {
      setGuardando(false);
    }
  };

  return (
    <Dialog open maxWidth="sm" fullWidth>
      <DialogTitle sx={{ display: "flex", alignItems: "center", gap: 1 }}>
        <Icon icon="lucide:coins" width={20} />
        Cotización del día — {fmtFechaCalendario(hoy)}
      </DialogTitle>
      <DialogContent>
        <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
          Todavía no se cargó la cotización de hoy. Se usa en facturas, cobros y pagos en moneda extranjera, y la{" "}
          <strong>venta</strong> es la tasa de los asientos contables. Queda guardada en Configuración → Monedas y en
          Contabilidad → Tipo de Cambio.
        </Typography>
        <Stack spacing={2}>
          {pendientes.map((m) => (
            <Box key={m.moneda_id}>
              <Typography variant="subtitle2" sx={{ mb: 1 }}>
                {m.codigo} — {m.descripcion}
                {m.ultima && (
                  <Typography component="span" variant="caption" color="text.secondary">
                    {" "}· última: {fmtFechaCalendario(m.ultima.fecha)}
                  </Typography>
                )}
              </Typography>
              <Box sx={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))", gap: 2 }}>
                {viaConfiguracion && (
                  <MonedaInput
                    label="Compra (Gs.)"
                    moneda="PYG"
                    allowPygDecimals
                    decimales={2}
                    value={valor(m, "compra")}
                    onChange={(v) => setValor(m, "compra", v)}
                  />
                )}
                <MonedaInput
                  label={viaConfiguracion ? "Venta (Gs.)" : "Tasa del día — venta (Gs.)"}
                  moneda="PYG"
                  allowPygDecimals
                  decimales={2}
                  value={valor(m, "venta")}
                  onChange={(v) => setValor(m, "venta", v)}
                />
              </Box>
            </Box>
          ))}
        </Stack>
        {pendientes.some((m) => m.ultima) && (
          <Alert severity="info" variant="outlined" sx={{ mt: 2, py: 0 }}>
            Viene precargada la última cotización registrada: confirmala o corregila con la de hoy.
          </Alert>
        )}
      </DialogContent>
      <DialogActions sx={{ p: 2 }}>
        <Button onClick={posponer} disabled={guardando}>
          Más tarde
        </Button>
        <Button variant="contained" onClick={guardar} disabled={guardando || !completo}>
          {guardando ? "Guardando…" : "Guardar cotización"}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default CotizacionDiariaDialog;
