import { Icon } from "@iconify/react";
import { Box, IconButton, Tooltip, Typography } from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import {
  anularNovedadPresentismo,
  actualizarNovedad,
  crearNovedad,
  eliminarNovedad,
  getEmpleados,
  getNovedades,
  procesarNovedadesPresentismo,
} 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 { useConfirmDialog } from "../../hooks/useConfirmDialog";
import { RRHHGuia } from "./_shared/RRHHGuia";
import { RRHHPrereqChecklist } from "./_shared/RRHHPrereqChecklist";
import { RRHHEmptyState } from "./_shared/RRHHEmptyState";
import { InlineValidationBanner } from "./_shared/InlineValidationBanner";
import { hoyISO } from "../../utils/fecha";

const empleadoOptionLabel = (e) => `${e.numero_empleado} — ${e.apellidos}, ${e.nombres}`;

const TIPO_OPTIONS = [
  { id: "AUSENCIA", label: "Ausencia" },
  { id: "AUSENCIA_JORNADA", label: "Ausencia jornada" },
  { id: "AUSENCIA_BLOQUE", label: "Ausencia bloque" },
  { id: "AUSENCIA_JUSTIFICADA", label: "Ausencia justificada" },
  { id: "TARDANZA", label: "Tardanza" },
  { id: "TARDANZA_JUSTIFICADA", label: "Tardanza justificada" },
  { id: "SALIDA_ANTICIPADA", label: "Salida anticipada" },
];

const JUSTIFICADO_OPTIONS = [
  { id: "todos", label: "Todos" },
  { id: "true", label: "Sólo justificadas" },
  { id: "false", label: "Sólo no justificadas" },
];

const todayYmd = () => hoyISO();

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

const fmtHora = (value) => {
  if (!value) return "-";
  // Backend devuelve ISO string como "1970-01-01T08:30:00.000Z" (Time)
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return String(value).slice(0, 5);
  return `${String(d.getUTCHours()).padStart(2, "0")}:${String(d.getUTCMinutes()).padStart(2, "0")}`;
};

const buildEmptyForm = () => ({
  empleado_id: "",
  fecha: todayYmd(),
  tipo_novedad: "TARDANZA",
  hora_entrada_real: "",
  hora_entrada_esperada: "",
  minutos_tardanza: "",
  justificado: false,
  tipo_justificacion: "",
  impacta_liquidacion: true,
  observacion: "",
});

export function NovedadesTab() {
  const { confirm, dialogs } = useConfirmDialog();
  const [data, setData] = useState([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(20);
  const [empleados, setEmpleados] = useState([]);
  const [tipoFiltro, setTipoFiltro] = useState("");
  const [empleadoFiltro, setEmpleadoFiltro] = useState("");
  const [justificadoFiltro, setJustificadoFiltro] = useState("todos");
  const [fechaDesde, setFechaDesde] = useState("");
  const [fechaHasta, setFechaHasta] = useState("");
  const [loading, setLoading] = useState(false);

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


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

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

  useEffect(() => {
    getEmpleados({ page: 1, limit: 200 })
      .then((resp) => setEmpleados(resp?.data || []))
      .catch(() => toast.error("No se pudieron cargar empleados"));
  }, []);

  const load = async () => {
    try {
      setLoading(true);
      const params = { page, limit };
      if (tipoFiltro) params.tipo_novedad = tipoFiltro;
      if (empleadoFiltro) params.empleado_id = empleadoFiltro;
      if (justificadoFiltro && justificadoFiltro !== "todos") params.justificado = justificadoFiltro;
      if (fechaDesde) params.fecha_desde = fechaDesde;
      if (fechaHasta) params.fecha_hasta = fechaHasta;
      const resp = await getNovedades(params);
      setData(resp?.data || []);
      setTotal(resp?.total || 0);
    } catch {
      toast.error("Error al cargar novedades");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => { load(); /* eslint-disable-next-line */ }, [page, limit, tipoFiltro, empleadoFiltro, justificadoFiltro, fechaDesde, fechaHasta]);

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

  const handleEditar = (n) => {
    setEditingId(n.id);
    setForm({
      empleado_id: n.empleado_id,
      fecha: n.fecha?.slice(0, 10) || todayYmd(),
      tipo_novedad: n.tipo_novedad,
      hora_entrada_real: n.hora_entrada_real ? fmtHora(n.hora_entrada_real) : "",
      hora_entrada_esperada: n.hora_entrada_esperada ? fmtHora(n.hora_entrada_esperada) : "",
      minutos_tardanza: n.minutos_tardanza ?? "",
      justificado: !!n.justificado,
      tipo_justificacion: n.tipo_justificacion || "",
      impacta_liquidacion: n.impacta_liquidacion ?? true,
      observacion: n.observacion || "",
    });
    setShowForm(true);
  };

  const handleGuardar = async () => {
    const errs = [];
    if (!form.empleado_id) errs.push({ campo: "Empleado", mensaje: "Seleccioná un empleado" });
    if (!form.fecha) errs.push({ campo: "Fecha", mensaje: "Indicá la fecha de la novedad" });
    if (errs.length) { setErroresForm(errs); return; }
    setErroresForm([]);

    try {
      setSaving(true);
      const payload = {
        ...form,
        hora_entrada_real: form.hora_entrada_real || undefined,
        hora_entrada_esperada: form.hora_entrada_esperada || undefined,
        minutos_tardanza: form.minutos_tardanza !== "" ? Number(form.minutos_tardanza) : undefined,
        tipo_justificacion: form.tipo_justificacion || undefined,
        observacion: form.observacion || undefined,
      };
      if (editingId) {
        const { empleado_id, ...rest } = payload;
        await actualizarNovedad(editingId, rest);
        toast.success("Novedad actualizada");
      } else {
        await crearNovedad(payload);
        toast.success("Novedad creada");
      }
      setShowForm(false);
      setEditingId(null);
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "Error al guardar");
    } finally {
      setSaving(false);
    }
  };

  const handleEliminar = async (n) => {
    const ok = await confirm({
      title: "Eliminar novedad",
      message: "¿Eliminar esta novedad? Esta acción no se puede deshacer.",
      confirmText: "Eliminar",
      confirmColor: "error",
    });
    if (!ok) return;
    try {
      await eliminarNovedad(n.id);
      toast.success("Novedad eliminada");
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo eliminar");
    }
  };

  const handleAnular = async (n) => {
    const ok = await confirm({
      title: "Anular novedad",
      message: "¿Anular esta novedad de presentismo? Si está aplicada a una liquidación cerrada, la operación será rechazada.",
      confirmText: "Anular",
      confirmColor: "error",
    });
    if (!ok) return;
    try {
      await anularNovedadPresentismo(n.id, {});
      toast.success("Novedad anulada");
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo anular");
    }
  };

  const handleProcesarPeriodo = async () => {
    const now = new Date();
    const defaultDesde = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1))
      .toISOString()
      .slice(0, 10);
    const defaultHasta = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 0))
      .toISOString()
      .slice(0, 10);

    const rangoDesde = fechaDesde || defaultDesde;
    const rangoHasta = fechaHasta || defaultHasta;

    const ok = await confirm({
      title: "Procesar período",
      message: `Se procesarán novedades de presentismo entre ${rangoDesde} y ${rangoHasta}. ¿Continuar?`,
      confirmText: "Procesar",
    });
    if (!ok) return;

    try {
      setProcessing(true);
      const resp = await procesarNovedadesPresentismo({
        fecha_desde: rangoDesde,
        fecha_hasta: rangoHasta,
      });
      toast.success(
        `Procesado: ${resp?.novedades_generadas ?? 0} nuevas · ${resp?.novedades_previas_anuladas ?? 0} anuladas`,
      );
      load();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo procesar el período");
    } finally {
      setProcessing(false);
    }
  };

  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 novedad" : "Nueva novedad"}
            </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 empleado..." />
            </Field>
            <Field>
              <label>Fecha *</label>
              <input type="date" value={form.fecha}
                onChange={(e) => updateField("fecha", e.target.value)} />
              <small style={{ opacity: 0.6, fontSize: "0.75rem" }}>Fecha en que ocurrió la ausencia o tardanza</small>
            </Field>
            <Field>
              <label>Tipo *</label>
              <SearchableSelect options={TIPO_OPTIONS} value={form.tipo_novedad}
                onChange={(id) => updateField("tipo_novedad", id || "TARDANZA")}
                clearable={false} />
            </Field>

            <Field>
              <label>Hora esperada</label>
              <input type="time" value={form.hora_entrada_esperada}
                onChange={(e) => updateField("hora_entrada_esperada", e.target.value)} />
            </Field>
            <Field>
              <label>Hora real</label>
              <input type="time" value={form.hora_entrada_real}
                onChange={(e) => updateField("hora_entrada_real", e.target.value)} />
            </Field>
            <Field>
              <label>Minutos tardanza</label>
              <input type="number" min="0" max="720" value={form.minutos_tardanza}
                onChange={(e) => updateField("minutos_tardanza", e.target.value)} />
              <small style={{ opacity: 0.6, fontSize: "0.75rem" }}>Ej: 30 — se calcula automáticamente si ingresás hora esperada y hora real</small>
            </Field>
            <Field>
              <label>Impacta liquidación</label>
              <SearchableSelect
                options={[
                  { id: "true", label: "Sí (descuenta)" },
                  { id: "false", label: "No" },
                ]}
                value={form.impacta_liquidacion ? "true" : "false"}
                onChange={(id) => updateField("impacta_liquidacion", id === "true")}
                clearable={false}
              />
            </Field>

            <Field>
              <label>Justificado</label>
              <SearchableSelect
                options={[
                  { id: "false", label: "No" },
                  { id: "true", label: "Sí" },
                ]}
                value={form.justificado ? "true" : "false"}
                onChange={(id) => updateField("justificado", id === "true")}
                clearable={false}
              />
            </Field>
            <Field $span={3}>
              <label>Tipo de justificación</label>
              <input value={form.tipo_justificacion}
                placeholder="Certificado médico, permiso supervisor, etc."
                onChange={(e) => updateField("tipo_justificacion", e.target.value)} />
            </Field>
            <Field $span={4}>
              <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" : "Crear novedad"}
            </FooterActionButton>
          </Footer>
        </FormPanel>
        {dialogs}
      </Container>
    );
  }

  return (
    <Container>
      <RRHHGuia seccion="novedades" />
      <RRHHPrereqChecklist tabKey="novedades" />
      <ListPanel>
        <ListBody>
          <ToolBar>
            <Box sx={{ minWidth: 200 }}>
              <SearchableSelect label="Tipo" options={TIPO_OPTIONS} value={tipoFiltro}
                onChange={(id) => { setTipoFiltro(id || ""); setPage(1); }}
                placeholder="Todos los tipos" />
            </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>
            <Box sx={{ minWidth: 200 }}>
              <SearchableSelect label="Justificación" options={JUSTIFICADO_OPTIONS} value={justificadoFiltro}
                onChange={(id) => { setJustificadoFiltro(id || "todos"); setPage(1); }}
                clearable={false} />
            </Box>
            <Box sx={{ minWidth: 140 }}>
              <Field>
                <label>Desde</label>
                <input type="date" value={fechaDesde}
                  onChange={(e) => { setFechaDesde(e.target.value); setPage(1); }} />
              </Field>
            </Box>
            <Box sx={{ minWidth: 140 }}>
              <Field>
                <label>Hasta</label>
                <input type="date" value={fechaHasta}
                  onChange={(e) => { setFechaHasta(e.target.value); setPage(1); }} />
              </Field>
            </Box>
            <Tooltip title="Refrescar">
              <GhostButton onClick={load} disabled={loading}>
                <Icon icon="lucide:refresh-cw" />
              </GhostButton>
            </Tooltip>
            <Box sx={{ flex: 1 }} />
            <FooterActionButton type="button" onClick={handleProcesarPeriodo} disabled={processing}>
              <Icon icon="lucide:play-circle" /> {processing ? "Procesando..." : "Procesar período"}
            </FooterActionButton>
            <FooterActionButton type="button" $variant="primary" onClick={handleNuevo}>
              <Icon icon="lucide:plus" /> Nueva novedad
            </FooterActionButton>
          </ToolBar>

          {loading ? (
            <EmptyState>Cargando...</EmptyState>
          ) : data.length === 0 ? (
            <RRHHEmptyState
              icon="lucide:clock-alert"
              titulo="Sin novedades registradas"
              descripcion="Las novedades registran ausencias, tardanzas, licencias y suspensiones del período. Con el switch «Impacta liquidación» activo, se descuentan automáticamente en el próximo cálculo de nómina."
              ctaLabel="Registrar novedad"
              onCta={handleNuevo}
              onVerGuia={() => document.getElementById("rrhh-guia-novedades")?.scrollIntoView({ behavior: "smooth" })}
            />
          ) : (
            <TableWrap>
              <table>
                <thead>
                  <tr>
                    <th>Fecha</th>
                    <th>Empleado</th>
                    <th>Tipo</th>
                    <th>Esperada</th>
                    <th>Real</th>
                    <th style={{ textAlign: "right" }}>Min. tardanza</th>
                    <th style={{ textAlign: "center" }}>Justif.</th>
                    <th style={{ textAlign: "center" }}>Impacta</th>
                    <th style={{ textAlign: "center" }}>Estado</th>
                    <th style={{ textAlign: "center" }}>Acciones</th>
                  </tr>
                </thead>
                <tbody>
                  {data.map((n) => {
                    const emp = n.empleado;
                    return (
                      <tr key={n.id}>
                        <td>{fmtFecha(n.fecha)}</td>
                        <td>{emp ? `${emp.numero_empleado} — ${emp.apellidos}, ${emp.nombres}` : "-"}</td>
                        <td>
                          <Badge $state={n.tipo_novedad.includes("AUSENCIA") ? "ANULADA" : n.tipo_novedad.includes("TARDANZA") ? "PENDIENTE" : "INACTIVO"}>
                            {n.tipo_novedad.replace(/_/g, " ")}
                          </Badge>
                        </td>
                        <td>{fmtHora(n.hora_entrada_esperada)}</td>
                        <td>{fmtHora(n.hora_entrada_real)}</td>
                        <td style={{ textAlign: "right", fontFamily: "monospace" }}>
                          {n.minutos_tardanza ?? "-"}
                        </td>
                        <td style={{ textAlign: "center" }}>{n.justificado ? "✓" : "—"}</td>
                        <td style={{ textAlign: "center" }}>{n.impacta_liquidacion ? "✓" : "—"}</td>
                        <td style={{ textAlign: "center" }}>
                          <Badge $state={n.estado === "ANULADA" ? "ANULADA" : n.estado === "CONFIRMADA" ? "ACTIVO" : "PENDIENTE"}>
                            {n.estado || "CONFIRMADA"}
                          </Badge>
                        </td>
                        <td style={{ textAlign: "center" }}>
                          <RowActions>
                            {!n.generado_automatico && n.estado !== "ANULADA" && (
                              <>
                                <Tooltip title="Editar">
                                  <IconButton size="small" onClick={() => handleEditar(n)}>
                                    <Icon icon="lucide:pencil" width={16} />
                                  </IconButton>
                                </Tooltip>
                                <Tooltip title="Eliminar">
                                  <IconButton size="small" color="error" onClick={() => handleEliminar(n)}>
                                    <Icon icon="lucide:trash-2" width={16} />
                                  </IconButton>
                                </Tooltip>
                              </>
                            )}
                            {n.estado !== "ANULADA" && (
                              <Tooltip title="Anular">
                                <IconButton size="small" color="error" onClick={() => handleAnular(n)}>
                                  <Icon icon="lucide:ban" width={16} />
                                </IconButton>
                              </Tooltip>
                            )}
                          </RowActions>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </TableWrap>
          )}

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