import { Icon } from "@iconify/react";
import {
  Box,
  Button,
  Chip,
  IconButton,
  Paper,
  Skeleton,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { EmptyState, ListToolbar, ScreenGuia, TablePaginationBar } from "../components/_standards";
import {
  FILTROS_ESTADO_VIAJE,
  esViajeEditable,
  getEstadoViajeChip,
} from "../components/_standards/enums/estadosViaje";
import { useDebouncedValue } from "../hooks/useDebouncedValue";
import { usePermission } from "../hooks/usePermission";
import { AnularViajeDialog } from "../components/viajes/AnularViajeDialog";
import { ViajeCabeceraDialog } from "../components/viajes/ViajeCabeceraDialog";
import { useViajesQuery } from "../tanstack/ViajesStack";
import { fmtFechaCalendario } from "../utils/fecha";

const GUIA_PASOS = [
  {
    icon: "lucide:clipboard-list",
    color: "#3b82f6",
    titulo: "1. Armar el viaje",
    desc: "Creá el viaje con la fecha de salida, el vendedor y el vehículo. Podés armarlo antes de salir o al volver.",
  },
  {
    icon: "lucide:link",
    color: "#8b5cf6",
    titulo: "2. Enganchar los documentos",
    desc: "El sistema propone las órdenes de venta, remisiones, facturas y recibos del vendedor entre las fechas del viaje. Confirmás cuáles entran.",
  },
  {
    icon: "lucide:package",
    color: "#f59e0b",
    titulo: "3. Revisar la carga",
    desc: "Por producto: lo planificado, lo que salió en la remisión, lo que se facturó y la diferencia. En cajas si el producto tiene presentación cargada.",
  },
  {
    icon: "lucide:table",
    color: "#10b981",
    titulo: "4. Ver qué dejó en cada cliente",
    desc: "La matriz producto × cliente, con la opción de ver lo pedido, lo entregado o ambos comparados.",
  },
  {
    icon: "lucide:check-circle",
    color: "#22c55e",
    titulo: "5. Cerrar con los kilómetros",
    desc: "Al cerrar se exigen la fecha y el km de retorno. El costo del viaje sale de la rendición de viáticos asociada.",
  },
];

const GUIA_NOTAS = [
  {
    icon: "mdi:alert-outline",
    text: "Un documento pertenece a un solo viaje: si ya está en otro, no se puede volver a enganchar.",
  },
  {
    icon: "mdi:information-outline",
    text: "Los viáticos no se cargan acá: las rendiciones viven en Finanzas › Anticipos a Empleados y se asocian en la pestaña Gastos y km del viaje, una por persona.",
  },
  {
    icon: "mdi:lock-outline",
    text: "Un viaje cerrado no acepta cambios hasta que se lo reabra.",
  },
];

const LIMITE = 20;

export function ViajesPage() {
  const navigate = useNavigate();
  const ventasPerm = usePermission("VENTAS");
  const puedeCrear = ventasPerm.can("VEN_VJ_VIAJE_CREAR");

  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(LIMITE);
  const [busqueda, setBusqueda] = useState("");
  const [estado, setEstado] = useState("");
  const [mostrarFiltros, setMostrarFiltros] = useState(false);
  const [fechaDesde, setFechaDesde] = useState("");
  const [fechaHasta, setFechaHasta] = useState("");
  const [zona, setZona] = useState("");
  const busquedaDebounced = useDebouncedValue(busqueda, 400);

  const [dialogo, setDialogo] = useState(false);
  // Diálogos rápidos desde la fila: editar y anular sin entrar al detalle.
  const [viajeEditar, setViajeEditar] = useState(null);
  const [viajeAnular, setViajeAnular] = useState(null);
  const puedeEditar = ventasPerm.can("VEN_VJ_VIAJE_EDITAR");
  const puedeAnular = ventasPerm.can("VEN_VJ_VIAJE_ANULAR");

  const filtros = useMemo(
    () => ({
      page,
      limit,
      ...(busquedaDebounced.trim() && { search: busquedaDebounced.trim() }),
      ...(estado && { estado }),
      ...(fechaDesde && { fecha_desde: fechaDesde }),
      ...(fechaHasta && { fecha_hasta: fechaHasta }),
      ...(zona && { zona }),
    }),
    [page, limit, busquedaDebounced, estado, fechaDesde, fechaHasta, zona],
  );

  // Al cambiar la búsqueda (debounced) se vuelve a la primera página.
  useEffect(() => {
    setPage(1);
  }, [busquedaDebounced]);

  const { data, isLoading, isError, refetch } = useViajesQuery(filtros);
  // Memoizado: si no, el `?? []` crea un array nuevo en cada render y rompe el
  // memo del filtrado de abajo.
  const viajes = useMemo(() => data?.data ?? [], [data]);
  const meta = data?.meta ?? { total: 0, totalPages: 1 };

  // El backend no busca por texto: se filtra sobre la página cargada, que es
  // lo mismo que hacen las demás listas mientras no haya endpoint de búsqueda.
  // El filtrado por texto ya lo hace el backend; esta variable queda sólo
  // porque el resto del render la referencia.
  const visibles = viajes;

  const filtrosActivos = [fechaDesde, fechaHasta, zona].filter(Boolean).length;

  const kmRecorrido = (v) =>
    v.km_salida != null && v.km_retorno != null ? v.km_retorno - v.km_salida : null;

  const abrirCreacion = () => setDialogo(true);

  return (
    <Box sx={{ p: { xs: 1.5, sm: 3 } }}>
      <ScreenGuia
        titulo="¿Cómo funcionan los viajes de reparto?"
        moduloPadre="Ventas · Viajes"
        intro="Un viaje agrupa los documentos de un reparto y responde qué cargar en el camión, qué dejar en cada cliente, cuánto se vendió y cuánto costó."
        pasos={GUIA_PASOS}
        notas={GUIA_NOTAS}
      />

      <Stack
        direction="row"
        alignItems="center"
        justifyContent="space-between"
        mb={2}
        sx={{ flexWrap: "wrap", gap: 1 }}
      >
        <Box>
          <Typography variant="h6" sx={{ display: "flex", alignItems: "center", gap: 1 }}>
            <Icon icon="lucide:truck" />
            Viajes de reparto
          </Typography>
          <Typography variant="caption" color="text.secondary">
            {meta.total} {meta.total === 1 ? "viaje registrado" : "viajes registrados"}
          </Typography>
        </Box>
        {puedeCrear && (
          <Button
            id="viajes-nuevo-btn"
            variant="contained"
            startIcon={<Icon icon="lucide:plus" width={18} />}
            onClick={abrirCreacion}
          >
            Nuevo viaje
          </Button>
        )}
      </Stack>

      <ListToolbar
        searchText={busqueda}
        onSearchChange={setBusqueda}
        searchPlaceholder="Buscar por número o descripción…"
        showFilters={mostrarFiltros}
        onToggleFilters={() => setMostrarFiltros((v) => !v)}
        filtrosActivos={filtrosActivos}
        onRefresh={refetch}
        quickFilters={FILTROS_ESTADO_VIAJE}
        quickFilterActive={estado}
        quickFiltersLabel="Estado:"
        onQuickFilter={(v) => {
          setEstado(v);
          setPage(1);
        }}
        onClearFilters={
          filtrosActivos || estado
            ? () => {
                setEstado("");
                setFechaDesde("");
                setFechaHasta("");
                setZona("");
                setPage(1);
              }
            : undefined
        }
      />

      {mostrarFiltros && (
        <Paper variant="outlined" sx={{ p: 2, mb: 2, bgcolor: "action.hover", borderRadius: 1.5 }}>
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 180px), 1fr))",
              gap: 2,
              alignItems: "end",
            }}
          >
            <TextField
              label="Salida desde"
              type="date"
              size="small"
              value={fechaDesde}
              onChange={(e) => {
                setFechaDesde(e.target.value);
                setPage(1);
              }}
              InputLabelProps={{ shrink: true }}
            />
            <TextField
              label="Salida hasta"
              type="date"
              size="small"
              value={fechaHasta}
              onChange={(e) => {
                setFechaHasta(e.target.value);
                setPage(1);
              }}
              InputLabelProps={{ shrink: true }}
            />
            <TextField
              label="Zona"
              size="small"
              value={zona}
              onChange={(e) => {
                setZona(e.target.value);
                setPage(1);
              }}
              helperText="Ej.: Interior, Norte"
            />
            <Button
              variant="text"
              onClick={() => {
                setFechaDesde("");
                setFechaHasta("");
                setZona("");
                setPage(1);
              }}
              disabled={!filtrosActivos}
            >
              Limpiar filtros
            </Button>
          </Box>
        </Paper>
      )}

      {isError ? (
        <EmptyState
          icon="lucide:alert-triangle"
          title="No se pudo cargar la lista"
          description="Revisá la conexión y volvé a intentar."
          ctaLabel="Reintentar"
          onCta={refetch}
        />
      ) : isLoading ? (
        <Stack spacing={1}>
          {[...Array(5)].map((_, i) => (
            <Skeleton key={i} variant="rounded" height={52} />
          ))}
        </Stack>
      ) : visibles.length === 0 ? (
        <EmptyState
          icon="lucide:truck"
          title={busquedaDebounced || filtrosActivos || estado ? "Ningún viaje coincide" : "Todavía no hay viajes"}
          description={
            busquedaDebounced || filtrosActivos || estado
              ? "Probá con otros filtros o limpiá la búsqueda."
              : "Creá el primero para agrupar los documentos de un reparto y ver qué cargar en el camión."
          }
          ctaLabel={puedeCrear ? "Crear viaje" : undefined}
          ctaIcon="lucide:plus"
          onCta={puedeCrear ? abrirCreacion : undefined}
        />
      ) : (
        <>
          <TableContainer component={Paper} variant="outlined">
            <Table size="small" id="viajes-tabla">
              <TableHead>
                <TableRow>
                  <TableCell sx={{ minWidth: 120, width: 140 }}>Número</TableCell>
                  <TableCell sx={{ minWidth: 90, width: 100 }}>Salida</TableCell>
                  <TableCell sx={{ minWidth: 90, width: 100 }}>Retorno</TableCell>
                  <TableCell sx={{ minWidth: 200 }}>Descripción</TableCell>
                  <TableCell sx={{ minWidth: 120, width: 140 }}>Zona</TableCell>
                  <TableCell align="right" sx={{ minWidth: 90, width: 100 }}>Km</TableCell>
                  <TableCell align="center" sx={{ minWidth: 110, width: 130 }}>Estado</TableCell>
                  <TableCell align="center" sx={{ minWidth: 90, width: 100 }}>Acciones</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {visibles.map((v) => {
                  const chip = getEstadoViajeChip(v.estado);
                  const km = kmRecorrido(v);
                  return (
                    <TableRow
                      key={v.id}
                      hover
                      sx={{ cursor: "pointer" }}
                      onClick={() => navigate(`/viajes/${v.id}`)}
                    >
                      <TableCell sx={{ fontFamily: "monospace", fontWeight: 600 }}>{v.numero}</TableCell>
                      <TableCell>{fmtFechaCalendario(v.fecha_salida)}</TableCell>
                      <TableCell>{v.fecha_retorno ? fmtFechaCalendario(v.fecha_retorno) : "—"}</TableCell>
                      <TableCell>{v.descripcion || "—"}</TableCell>
                      <TableCell>{v.zona || "—"}</TableCell>
                      <TableCell align="right">{km != null ? km.toLocaleString("es-PY") : "—"}</TableCell>
                      <TableCell align="center">
                        <Chip
                          size="small"
                          color={chip.color}
                          icon={<Icon icon={chip.icon} width={14} />}
                          label={chip.label}
                        />
                      </TableCell>
                      <TableCell align="center" onClick={(e) => e.stopPropagation()}>
                        <Stack direction="row" spacing={0.5} justifyContent="center">
                          {esViajeEditable(v.estado) && puedeEditar && (
                            <Tooltip title="Editar">
                              <IconButton size="small" onClick={() => setViajeEditar(v)}>
                                <Icon icon="lucide:pencil" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {v.estado !== "ANULADO" && puedeAnular && (
                            <Tooltip title="Anular">
                              <IconButton size="small" color="error" onClick={() => setViajeAnular(v)}>
                                <Icon icon="lucide:x-circle" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                        </Stack>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </TableContainer>

          <TablePaginationBar
            page={page}
            totalPages={meta.totalPages}
            onPageChange={setPage}
            total={meta.total}
            shown={visibles.length}
            noun="viajes"
            rowsPerPage={limit}
            onRowsPerPageChange={(n) => {
              setLimit(n);
              setPage(1);
            }}
          />
        </>
      )}

      <ViajeCabeceraDialog
        open={dialogo}
        onClose={() => setDialogo(false)}
        onCreado={(creado) => creado?.id && navigate(`/viajes/${creado.id}`)}
      />
      <ViajeCabeceraDialog
        open={!!viajeEditar}
        onClose={() => setViajeEditar(null)}
        viaje={viajeEditar}
      />
      <AnularViajeDialog
        open={!!viajeAnular}
        onClose={() => setViajeAnular(null)}
        viaje={viajeAnular}
      />
    </Box>
  );
}

export default ViajesPage;
