import { Icon } from "@iconify/react";
import { Alert, Box, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Tooltip, Typography } from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import {
  actualizarAnticipo,
  anularAnticipo,
  aprobarAnticipo,
  crearAnticipo,
  eliminarAnticipo,
  getAnticipos,
  getEmpleados,
} from "../../api/rrhh.service";
import {
  Badge,
  Container,
  EmptyState,
  Field,
  FieldsGrid,
  Footer,
  FooterActionButton,
  FormHead,
  FormPanel,
  GhostButton,
  ListBody,
  ListPanel,
  RowActions,
  SectionTitle,
  TableWrap,
  ToolBar,
} from "../ui/FormShell";
import { TablePaginationBar } from "../_standards";
import { SearchableSelect } from "../ui/SearchableSelect";
import { getTesCuentas } from "../../api/tes.service";
import { useConfirmDialog } from "../../hooks/useConfirmDialog";
import { RRHHGuia } from "./_shared/RRHHGuia";
import { RRHHPrereqChecklist } from "./_shared/RRHHPrereqChecklist";
import { RRHHEmptyState } from "./_shared/RRHHEmptyState";
import { useRRHHContext } from "./_shared/RRHHContext";
import { MonedaInput } from "../common/MonedaInput";
import { InlineValidationBanner } from "./_shared/InlineValidationBanner";
import { hoyISO } from "../../utils/fecha";

const empleadoOptionLabel = (e) => `${e.numero_empleado} — ${e.apellidos}, ${e.nombres}`;
const ESTADO_OPTIONS = [
  { id: "PENDIENTE", label: "Pendiente" },
  { id: "APROBADO", label: "Aprobado" },
  { id: "DESCONTADO", label: "Descontado" },
  { id: "ANULADO", label: "Anulado" },
];
const MES_OPTIONS = [
  { id: 1, label: "01 — Enero" }, { id: 2, label: "02 — Febrero" },
  { id: 3, label: "03 — Marzo" }, { id: 4, label: "04 — Abril" },
  { id: 5, label: "05 — Mayo" }, { id: 6, label: "06 — Junio" },
  { id: 7, label: "07 — Julio" }, { id: 8, label: "08 — Agosto" },
  { id: 9, label: "09 — Septiembre" }, { id: 10, label: "10 — Octubre" },
  { id: 11, label: "11 — Noviembre" }, { id: 12, label: "12 — Diciembre" },
];

const todayYmd = () => hoyISO();

const buildEmptyForm = () => {
  const today = new Date();
  return {
    empleado_id: "",
    fecha_solicitud: todayYmd(),
    monto: 0,
    periodo_anio: today.getFullYear(),
    periodo_mes: today.getMonth() + 1,
    observacion: "",
  };
};

const fmtFecha = (value) => {
  if (!value) return "-";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return "-";
  return d.toLocaleDateString("es-PY");
};

const fmtPeriodo = (anio, mes) =>
  `${String(mes).padStart(2, "0")}/${anio}`;

const fmtMonto = (value) => Number(value || 0).toLocaleString("es-PY");

export function AnticiposTab() {
  const { confirm, prompt, dialogs } = useConfirmDialog();
  const { reloadBadges } = useRRHHContext();
  const [data, setData] = useState([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(20);
  const [estadoFiltro, setEstadoFiltro] = useState("");
  const [empleadoFiltro, setEmpleadoFiltro] = useState("");
  const [loading, setLoading] = useState(false);
  // Cuentas PYG de Tesorería. Vacío = la empresa no usa el módulo y el anticipo se
  // aprueba sin registrar egreso, como antes.
  const [tesCuentas, setTesCuentas] = useState([]);
  const [aprobarState, setAprobarState] = useState({ open: false });
  const usaTesoreria = tesCuentas.length > 0;
  const cuentaOptions = tesCuentas.map((c) => ({ id: c.id, label: `${c.nombre} · PYG` }));

  const [empleados, setEmpleados] = useState([]);

  const [showForm, setShowForm] = useState(false);


  const [editingId, setEditingId] = useState(null);
  const [form, setForm] = useState(buildEmptyForm());
  const [saving, setSaving] = useState(false);
  const [erroresForm, setErroresForm] = useState([]);

  const totalPages = useMemo(() => Math.max(1, Math.ceil(total / limit)), [total, limit]);

  const cargarEmpleados = async () => {
    try {
      const resp = await getEmpleados({ page: 1, limit: 200, estado: "ACTIVO" });
      setEmpleados(resp?.data || []);
    } catch {
      toast.error("No se pudieron cargar empleados");
    }
  };

  const load = async () => {
    try {
      setLoading(true);
      const params = { page, limit };
      if (estadoFiltro) params.estado = estadoFiltro;
      if (empleadoFiltro) params.empleado_id = empleadoFiltro;
      const resp = await getAnticipos(params);
      setData(resp?.data || []);
      setTotal(resp?.total || 0);
    } catch {
      toast.error("Error al cargar anticipos");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => { cargarEmpleados(); }, []);
  useEffect(() => { load(); /* eslint-disable-next-line */ }, [page, limit, estadoFiltro, empleadoFiltro]);

  useEffect(() => {
    getTesCuentas({ activo: true })
      .then((cuentas) => {
        const lista = Array.isArray(cuentas) ? cuentas : cuentas?.data || [];
        setTesCuentas(lista.filter((c) => c.activo !== false && c.moneda === "PYG"));
      })
      .catch(() => setTesCuentas([]));
  }, []);

  const handleNuevo = () => {
    setEditingId(null);
    setForm(buildEmptyForm());
    setErroresForm([]);
    setShowForm(true);
  };

  const handleEditar = (a) => {
    setErroresForm([]);
    setEditingId(a.id);
    setForm({
      empleado_id: a.empleado_id,
      fecha_solicitud: a.fecha_solicitud ? a.fecha_solicitud.slice(0, 10) : todayYmd(),
      monto: Number(a.monto) || 0,
      periodo_anio: a.periodo_anio,
      periodo_mes: a.periodo_mes,
      observacion: a.observacion || "",
    });
    setShowForm(true);
  };

  const handleGuardar = async () => {
    const errs = [];
    if (!form.empleado_id) errs.push({ campo: "Empleado", mensaje: "Seleccioná un empleado" });
    if (!Number(form.monto) || Number(form.monto) <= 0) errs.push({ campo: "Monto", mensaje: "Debe ser mayor a cero" });
    if (errs.length) { setErroresForm(errs); return; }
    setErroresForm([]);

    try {
      setSaving(true);
      const payload = {
        ...form,
        monto: Number(form.monto),
        periodo_anio: Number(form.periodo_anio),
        periodo_mes: Number(form.periodo_mes),
        observacion: form.observacion || undefined,
      };
      if (editingId) {
        const { empleado_id, ...rest } = payload;
        await actualizarAnticipo(editingId, rest);
        toast.success("Anticipo actualizado");
      } else {
        await crearAnticipo(payload);
        toast.success("Anticipo creado");
        reloadBadges();
      }
      setShowForm(false);
      setEditingId(null);
      setForm(buildEmptyForm());
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "Error al guardar anticipo");
    } finally {
      setSaving(false);
    }
  };

  // Aprobar = desembolsar: se pide la cuenta de la que sale la plata y la fecha real
  // del pago, porque el backend registra con eso el egreso de Tesorería y el asiento.
  const handleAprobar = (a) => {
    setAprobarState({
      open: true,
      anticipo: a,
      cuentaId: tesCuentas.length === 1 ? tesCuentas[0].id : "",
      fechaPago: todayYmd(),
      guardando: false,
    });
  };

  const confirmarAprobacion = async () => {
    const { anticipo, cuentaId, fechaPago } = aprobarState;
    if (usaTesoreria && !cuentaId) {
      toast.error("Elegí la cuenta desde la que se paga el anticipo.");
      return;
    }
    setAprobarState((p) => ({ ...p, guardando: true }));
    try {
      await aprobarAnticipo(anticipo.id, {
        ...(cuentaId ? { cuenta_tesoreria_id: cuentaId } : {}),
        ...(fechaPago ? { fecha_pago: fechaPago } : {}),
      });
      toast.success(
        usaTesoreria
          ? "Anticipo aprobado y registrado en Tesorería"
          : "Anticipo aprobado",
      );
      setAprobarState({ open: false });
      load();
      reloadBadges();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo aprobar");
      setAprobarState((p) => ({ ...p, guardando: false }));
    }
  };

  const handleAnular = async (a) => {
    const comentario = await prompt({
      title: "Anular anticipo",
      message: `Anticipo de ${fmtMonto(a.monto)} para ${a.empleado.nombres} ${a.empleado.apellidos}.`,
      label: "Motivo de anulación",
      placeholder: "Opcional",
      confirmText: "Anular",
      confirmColor: "warning",
    });
    if (comentario === null) return;
    try {
      await anularAnticipo(a.id, comentario ? { comentario } : {});
      toast.success("Anticipo anulado");
      load();
      reloadBadges();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo anular");
    }
  };

  const handleEliminar = async (a) => {
    const ok = await confirm({
      title: "Eliminar anticipo",
      message: "¿Eliminar este anticipo PENDIENTE?",
      confirmText: "Eliminar",
      confirmColor: "error",
    });
    if (!ok) return;
    try {
      await eliminarAnticipo(a.id);
      toast.success("Anticipo eliminado");
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo eliminar");
    }
  };

  const updateField = (key, value) => setForm((p) => ({ ...p, [key]: value }));

  if (showForm) {
    return (
      <Container>
        <FormPanel>
          <FormHead>
            <SectionTitle>
              <Icon icon={editingId ? "lucide:edit-3" : "lucide:plus-circle"} />
              {editingId ? "Editar anticipo" : "Nuevo anticipo"}
            </SectionTitle>
            <GhostButton onClick={() => { setShowForm(false); setEditingId(null); }}>
              <Icon icon="lucide:x" /> Cerrar
            </GhostButton>
          </FormHead>

          <InlineValidationBanner errores={erroresForm} titulo="Revisá los siguientes campos" />

          <FieldsGrid $cols={4}>
            <Field $span={2}>
              <label>Empleado *</label>
              <SearchableSelect
                options={empleados}
                value={form.empleado_id}
                disabled={!!editingId}
                onChange={(id) => updateField("empleado_id", id || "")}
                getOptionLabel={empleadoOptionLabel}
                placeholder="Buscar por número, nombre o apellido..."
              />
            </Field>
            <Field>
              <label>Fecha solicitud *</label>
              <input type="date" value={form.fecha_solicitud}
                onChange={(e) => updateField("fecha_solicitud", e.target.value)} />
            </Field>
            <MonedaInput
              label="Monto *"
              fullWidth
              value={form.monto}
              onChange={(v) => updateField("monto", v)}
              helperText="Se descuenta automáticamente en la próxima liquidación"
            />

            <Field>
              <label>Período año *</label>
              <input type="number" min="2020" max="2100" value={form.periodo_anio}
                onChange={(e) => updateField("periodo_anio", e.target.value)} />
              <small style={{ opacity: 0.6, fontSize: "0.75rem" }}>Año de la liquidación donde se descontará</small>
            </Field>
            <Field>
              <label>Período mes *</label>
              <SearchableSelect
                options={MES_OPTIONS}
                value={form.periodo_mes}
                onChange={(id) => updateField("periodo_mes", id ?? form.periodo_mes)}
                clearable={false}
                placeholder="Mes"
              />
            </Field>
            <Field $span={2}>
              <label>Observación</label>
              <input value={form.observacion}
                onChange={(e) => updateField("observacion", e.target.value)} />
            </Field>
          </FieldsGrid>

          <Footer>
            <FooterActionButton type="button" $variant="danger" disabled={saving}
              onClick={() => { setShowForm(false); setEditingId(null); }}>
              <Icon icon="lucide:x-circle" /> Cancelar
            </FooterActionButton>
            <FooterActionButton type="button" $variant="primary" disabled={saving}
              onClick={handleGuardar}>
              <Icon icon="lucide:check-circle" />
              {saving ? "Guardando..." : editingId ? "Actualizar anticipo" : "Crear anticipo"}
            </FooterActionButton>
          </Footer>
        </FormPanel>
        {dialogs}
      </Container>
    );
  }

  return (
    <Container>
      <RRHHGuia seccion="anticipos" />
      <RRHHPrereqChecklist tabKey="anticipos" />
      <ListPanel>
        <ListBody>
          <ToolBar>
            <Box sx={{ minWidth: 200 }}>
              <SearchableSelect
                label="Estado"
                options={ESTADO_OPTIONS}
                value={estadoFiltro}
                onChange={(id) => { setEstadoFiltro(id || ""); setPage(1); }}
                placeholder="Todos los estados"
              />
            </Box>
            <Box sx={{ minWidth: 280 }}>
              <SearchableSelect
                label="Empleado"
                options={empleados}
                value={empleadoFiltro}
                onChange={(id) => { setEmpleadoFiltro(id || ""); setPage(1); }}
                getOptionLabel={empleadoOptionLabel}
                placeholder="Todos los empleados"
              />
            </Box>
            <Tooltip title="Refrescar">
              <GhostButton onClick={load} disabled={loading}>
                <Icon icon="lucide:refresh-cw" />
              </GhostButton>
            </Tooltip>
            <Box sx={{ flex: 1 }} />
            <FooterActionButton type="button" $variant="primary" onClick={handleNuevo}>
              <Icon icon="lucide:plus" /> Nuevo anticipo
            </FooterActionButton>
          </ToolBar>

          {loading ? (
            <EmptyState>Cargando...</EmptyState>
          ) : data.length === 0 ? (
            <RRHHEmptyState
              icon="lucide:wallet-cards"
              titulo="Sin anticipos registrados"
              descripcion="Los anticipos de salario permiten adelantar parte del sueldo al empleado. El monto se descuenta automáticamente en la próxima liquidación. Solo los anticipos APROBADOS afectan la nómina."
              ctaLabel="Registrar anticipo"
              onCta={handleNuevo}
              onVerGuia={() => document.getElementById("rrhh-guia-anticipos")?.scrollIntoView({ behavior: "smooth" })}
            />
          ) : (
            <TableWrap>
              <table>
                <thead>
                  <tr>
                    <th>Fecha</th>
                    <th>Empleado</th>
                    <th>Período</th>
                    <th style={{ textAlign: "right" }}>Monto</th>
                    <th>Estado</th>
                    <th>Observación</th>
                    <th style={{ textAlign: "center" }}>Acciones</th>
                  </tr>
                </thead>
                <tbody>
                  {data.map((a) => {
                    const emp = a.empleado;
                    const esPendiente = a.estado === "PENDIENTE";
                    const esAprobado = a.estado === "APROBADO";
                    const sePuedeAnular = esPendiente || esAprobado;
                    return (
                      <tr key={a.id}>
                        <td>{fmtFecha(a.fecha_solicitud)}</td>
                        <td>
                          {emp ? (
                            <>
                              <strong>{emp.numero_empleado}</strong> — {emp.apellidos}, {emp.nombres}
                            </>
                          ) : "-"}
                        </td>
                        <td>{fmtPeriodo(a.periodo_anio, a.periodo_mes)}</td>
                        <td style={{ textAlign: "right", fontFamily: "monospace" }}>
                          {fmtMonto(a.monto)}
                        </td>
                        <td><Badge $state={a.estado}>{a.estado}</Badge></td>
                        <td style={{ maxWidth: 240, overflow: "hidden", textOverflow: "ellipsis" }}>
                          {a.observacion || "—"}
                        </td>
                        <td style={{ textAlign: "center" }}>
                          <RowActions>
                            {esPendiente && (
                              <>
                                <Tooltip title="Editar">
                                  <IconButton size="small" onClick={() => handleEditar(a)}>
                                    <Icon icon="lucide:pencil" width={16} />
                                  </IconButton>
                                </Tooltip>
                                <Tooltip title="Aprobar">
                                  <IconButton size="small" color="success" onClick={() => handleAprobar(a)}>
                                    <Icon icon="lucide:check-circle" width={16} />
                                  </IconButton>
                                </Tooltip>
                              </>
                            )}
                            {sePuedeAnular && (
                              <Tooltip title="Anular">
                                <IconButton size="small" color="warning" onClick={() => handleAnular(a)}>
                                  <Icon icon="lucide:ban" width={16} />
                                </IconButton>
                              </Tooltip>
                            )}
                            {esPendiente && (
                              <Tooltip title="Eliminar">
                                <IconButton size="small" color="error" onClick={() => handleEliminar(a)}>
                                  <Icon icon="lucide:trash-2" width={16} />
                                </IconButton>
                              </Tooltip>
                            )}
                          </RowActions>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </TableWrap>
          )}

          <TablePaginationBar
            page={page}
            totalPages={totalPages}
            onPageChange={setPage}
            total={total}
            shown={data.length}
            noun="anticipos"
            rowsPerPage={limit}
            onRowsPerPageChange={(n) => {
              setLimit(n);
              setPage(1);
            }}
          />
        </ListBody>
      </ListPanel>

      <Dialog
        open={!!aprobarState.open}
        onClose={() => !aprobarState.guardando && setAprobarState({ open: false })}
        maxWidth="xs"
        fullWidth
      >
        <DialogTitle sx={{ pb: 1 }}>Aprobar anticipo</DialogTitle>
        <DialogContent>
          {aprobarState.anticipo && (
            <Typography variant="body2" sx={{ mb: 2 }}>
              {fmtMonto(aprobarState.anticipo.monto)} para{" "}
              <strong>
                {aprobarState.anticipo.empleado?.nombres} {aprobarState.anticipo.empleado?.apellidos}
              </strong>
            </Typography>
          )}

          {usaTesoreria ? (
            <FieldsGrid $cols={1}>
              <Field>
                <label>Cuenta desde la que se paga *</label>
                <SearchableSelect
                  options={cuentaOptions}
                  value={aprobarState.cuentaId || ""}
                  onChange={(id) => setAprobarState((p) => ({ ...p, cuentaId: id || "" }))}
                  placeholder="Elegí la cuenta…"
                />
              </Field>
              <Field>
                <label>Fecha del pago *</label>
                <input
                  type="date"
                  value={aprobarState.fechaPago || ""}
                  onChange={(e) => setAprobarState((p) => ({ ...p, fechaPago: e.target.value }))}
                />
                <small>Es la fecha con la que el movimiento entra al extracto de Tesorería.</small>
              </Field>
            </FieldsGrid>
          ) : (
            <Alert severity="info" sx={{ py: 0.5 }}>
              La empresa no tiene Tesorería activa: el anticipo se aprueba sin registrar el egreso.
            </Alert>
          )}

          {usaTesoreria && (
            <Alert severity="success" variant="outlined" sx={{ mt: 2, py: 0.5 }}>
              Se registrará el egreso y el asiento DEBE «Anticipos al Personal» / HABER la cuenta elegida.
            </Alert>
          )}
        </DialogContent>
        <DialogActions sx={{ px: 3, pb: 2 }}>
          <GhostButton
            onClick={() => setAprobarState({ open: false })}
            disabled={aprobarState.guardando}
          >
            Cancelar
          </GhostButton>
          <FooterActionButton
            type="button"
            $variant="primary"
            onClick={confirmarAprobacion}
            disabled={aprobarState.guardando || (usaTesoreria && !aprobarState.cuentaId)}
          >
            <Icon icon="lucide:check-circle" /> {aprobarState.guardando ? "Aprobando…" : "Aprobar"}
          </FooterActionButton>
        </DialogActions>
      </Dialog>

      {dialogs}
    </Container>
  );
}
