import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  Box, Typography, TextField, Button, Paper, IconButton, Menu, MenuItem, Chip,
  Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination,
  CircularProgress, Alert, FormControl, InputLabel, Select, FormControlLabel, Checkbox
} from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
import SearchIcon from '@mui/icons-material/Search';
import ClearIcon from '@mui/icons-material/Clear';

import stockBobinaService from '../../services/Impresion/stockBobinaService';
import tipoBobinaService from '../../services/Impresion/tipoBobinaService';
import plantaService from '../../services/Impresion/plantaService';
import estadoBobinaService from '../../services/Impresion/estadoBobinaService';

import type { StockBobinaDto } from '../../models/dtos/Impresion/StockBobinaDto';
import type { CreateStockBobinaDto } from '../../models/dtos/Impresion/CreateStockBobinaDto';
import type { UpdateStockBobinaDto } from '../../models/dtos/Impresion/UpdateStockBobinaDto';
import type { CambiarEstadoBobinaDto } from '../../models/dtos/Impresion/CambiarEstadoBobinaDto';
import type { TipoBobinaDto } from '../../models/dtos/Impresion/TipoBobinaDto';
import type { PlantaDto } from '../../models/dtos/Impresion/PlantaDto';
import type { EstadoBobinaDto } from '../../models/dtos/Impresion/EstadoBobinaDto';

import StockBobinaIngresoFormModal from '../../components/Modals/Impresion/StockBobinaIngresoFormModal';
import StockBobinaEditFormModal from '../../components/Modals/Impresion/StockBobinaEditFormModal';
import StockBobinaCambioEstadoModal from '../../components/Modals/Impresion/StockBobinaCambioEstadoModal';

import { usePermissions } from '../../hooks/usePermissions';
import axios from 'axios';

const ID_ESTADO_DISPONIBLE = 1;
const ID_ESTADO_UTILIZADA = 2;
const ID_ESTADO_DANADA = 3;

const GestionarStockBobinasPage: React.FC = () => {
  const [stock, setStock] = useState<StockBobinaDto[]>([]);
  const [loading, setLoading] = useState(false); // No carga al inicio
  const [error, setError] = useState<string | null>(null);
  const [apiErrorMessage, setApiErrorMessage] = useState<string | null>(null);

  // Estados de los filtros
  const [filtroTipoBobina, setFiltroTipoBobina] = useState<number | string>('');
  const [filtroNroBobina, setFiltroNroBobina] = useState('');
  const [filtroPlanta, setFiltroPlanta] = useState<number | string>('');
  const [filtroEstadoBobina, setFiltroEstadoBobina] = useState<number | string>('');
  const [filtroRemito, setFiltroRemito] = useState('');
  const [filtroFechaHabilitado, setFiltroFechaHabilitado] = useState<boolean>(false); // <-- NUEVO
  const [filtroFechaDesde, setFiltroFechaDesde] = useState<string>(new Date().toISOString().split('T')[0]);
  const [filtroFechaHasta, setFiltroFechaHasta] = useState<string>(new Date().toISOString().split('T')[0]);

  // Estados para datos de dropdowns
  const [tiposBobina, setTiposBobina] = useState<TipoBobinaDto[]>([]);
  const [plantas, setPlantas] = useState<PlantaDto[]>([]);
  const [estadosBobina, setEstadosBobina] = useState<EstadoBobinaDto[]>([]);
  const [loadingFiltersDropdown, setLoadingFiltersDropdown] = useState(false);

  // Estados de los modales
  const [ingresoModalOpen, setIngresoModalOpen] = useState(false);
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [cambioEstadoModalOpen, setCambioEstadoModalOpen] = useState(false);

  // Estado para la bobina seleccionada en un modal o menú
  const [selectedBobina, setSelectedBobina] = useState<StockBobinaDto | null>(null);

  // Estados para la paginación y el menú de acciones
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const [selectedBobinaForRowMenu, setSelectedBobinaForRowMenu] = useState<StockBobinaDto | null>(null);

  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVer = isSuperAdmin || tienePermiso("IB001");
  const puedeIngresar = isSuperAdmin || tienePermiso("IB002");
  const puedeCambiarEstado = isSuperAdmin || tienePermiso("IB003");
  const puedeModificarDatos = isSuperAdmin || tienePermiso("IB004");
  const puedeEliminar = isSuperAdmin || tienePermiso("IB005");

  const lastOpenedMenuButtonRef = useRef<HTMLButtonElement | null>(null);

  const fetchFiltersDropdownData = useCallback(async () => {
    setLoadingFiltersDropdown(true);
    try {
      // Asumiendo que estos servicios existen y devuelven los DTOs correctos
      const [tiposData, plantasData, estadosData] = await Promise.all([
        tipoBobinaService.getAllTiposBobina(),
        plantaService.getAllPlantas(),
        estadoBobinaService.getAllEstadosBobina()
      ]);
      setTiposBobina(tiposData);
      setPlantas(plantasData);
      setEstadosBobina(estadosData);
    } catch (err) {
      console.error("Error cargando datos para filtros:", err);
      setError("Error al cargar opciones de filtro.");
    } finally {
      setLoadingFiltersDropdown(false);
    }
  }, []);

  useEffect(() => {
    fetchFiltersDropdownData();
  }, [fetchFiltersDropdownData]);

  const cargarStock = useCallback(async () => {
    if (!puedeVer) {
      setError("No tiene permiso para ver esta sección.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorMessage(null);
    try {
      const params = {
        idTipoBobina: filtroTipoBobina ? Number(filtroTipoBobina) : null,
        nroBobinaFilter: filtroNroBobina || null,
        idPlanta: filtroPlanta ? Number(filtroPlanta) : null,
        idEstadoBobina: filtroEstadoBobina ? Number(filtroEstadoBobina) : null,
        remitoFilter: filtroRemito || null,
        fechaDesde: filtroFechaHabilitado ? filtroFechaDesde : null,
        fechaHasta: filtroFechaHabilitado ? filtroFechaHasta : null,
      };
      const data = await stockBobinaService.getAllStockBobinas(params);
      setStock(data);
      if (data.length === 0) {
        setError("No se encontraron resultados con los filtros aplicados.");
      }
    } catch (err) {
      console.error(err);
      setError('Error al cargar el stock de bobinas.');
    } finally {
      setLoading(false);
    }
  }, [puedeVer, filtroTipoBobina, filtroNroBobina, filtroPlanta, filtroEstadoBobina, filtroRemito, filtroFechaHabilitado, filtroFechaDesde, filtroFechaHasta]);

  const handleBuscarClick = () => {
    setPage(0); // Resetear la paginación al buscar
    cargarStock();
  };

  const handleLimpiarFiltros = () => {
    setFiltroTipoBobina('');
    setFiltroNroBobina('');
    setFiltroPlanta('');
    setFiltroEstadoBobina('');
    setFiltroRemito('');
    setFiltroFechaHabilitado(false);
    setFiltroFechaDesde(new Date().toISOString().split('T')[0]);
    setFiltroFechaHasta(new Date().toISOString().split('T')[0]);
    setStock([]); // Limpiar los resultados actuales
    setError(null);
  };

  const handleOpenIngresoModal = () => { setApiErrorMessage(null); setIngresoModalOpen(true); };
  const handleCloseIngresoModal = () => setIngresoModalOpen(false);
  const handleSubmitIngresoModal = async (data: CreateStockBobinaDto) => {
    setApiErrorMessage(null);
    try { await stockBobinaService.ingresarBobina(data); cargarStock(); }
    catch (err: any) { const msg = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al ingresar bobina.'; setApiErrorMessage(msg); throw err; }
  };

  const handleOpenEditModal = (bobina: StockBobinaDto | null) => {
    if (!bobina) return;
    setSelectedBobina(bobina);
    setApiErrorMessage(null);
    setEditModalOpen(true);
  };
  const handleCloseEditModal = () => {
    setEditModalOpen(false);
    setSelectedBobina(null);
    if (lastOpenedMenuButtonRef.current) {
      setTimeout(() => { lastOpenedMenuButtonRef.current?.focus(); }, 0);
    }
  };
  const handleSubmitEditModal = async (idBobina: number, data: UpdateStockBobinaDto) => {
    setApiErrorMessage(null);
    try { await stockBobinaService.updateDatosBobinaDisponible(idBobina, data); cargarStock(); }
    catch (err: any) { const msg = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al actualizar bobina.'; setApiErrorMessage(msg); throw err; }
  };

  const handleOpenCambioEstadoModal = (bobina: StockBobinaDto | null) => {
    if (!bobina) return;
    setSelectedBobina(bobina);
    setApiErrorMessage(null);
    setCambioEstadoModalOpen(true);
  };
  const handleCloseCambioEstadoModal = () => setCambioEstadoModalOpen(false);
  const handleSubmitCambioEstadoModal = async (idBobina: number, data: CambiarEstadoBobinaDto) => {
    setApiErrorMessage(null);
    try { await stockBobinaService.cambiarEstadoBobina(idBobina, data); cargarStock(); }
    catch (err: any) { const msg = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al cambiar estado.'; setApiErrorMessage(msg); throw err; }
  };

  const handleDeleteBobina = async (bobina: StockBobinaDto | null) => {
    if (!bobina) return;
    if (bobina.idEstadoBobina !== ID_ESTADO_DISPONIBLE && bobina.idEstadoBobina !== ID_ESTADO_DANADA) {
      alert("Solo se pueden eliminar bobinas en estado 'Disponible' o 'Dañada'.");
      handleMenuClose();
      return;
    }
    if (window.confirm(`¿Seguro de eliminar este ingreso de bobina (ID: ${bobina.idBobina})?`)) {
      setApiErrorMessage(null);
      try { await stockBobinaService.deleteIngresoBobina(bobina.idBobina); cargarStock(); }
      catch (err: any) { const msg = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al eliminar.'; setApiErrorMessage(msg); }
    }
    handleMenuClose();
  };

  const handleMenuOpen = (event: React.MouseEvent<HTMLButtonElement>, bobina: StockBobinaDto) => {
    setAnchorEl(event.currentTarget);
    setSelectedBobinaForRowMenu(bobina);
    lastOpenedMenuButtonRef.current = event.currentTarget;
  };
  const handleMenuClose = () => {
    setAnchorEl(null);
    setSelectedBobinaForRowMenu(null);
    if (lastOpenedMenuButtonRef.current) {
      setTimeout(() => { lastOpenedMenuButtonRef.current?.focus(); }, 0);
    }
  };

  const handleChangePage = (_event: unknown, newPage: number) => setPage(newPage);
  const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
    setRowsPerPage(parseInt(event.target.value, 10)); setPage(0);
  };
  const displayData = stock.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
  const formatDate = (dateString?: string | null) => {
    if (!dateString) return '-';
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return '-';

    const options: Intl.DateTimeFormatOptions = {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      timeZone: 'UTC'
    };
    return new Intl.DateTimeFormat('es-AR', options).format(date);
  };

  if (!puedeVer) return <Box sx={{ p: 2 }}><Alert severity="error">{error || "Acceso denegado."}</Alert></Box>;

  return (
    <Box sx={{ p: 1 }}>
      <Typography variant="h5" gutterBottom>Stock de Bobinas</Typography>
      <Paper sx={{ p: 2, mb: 2 }}>
        <Typography variant="h6" gutterBottom>Filtros</Typography>
        <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
          <FormControl size="small" sx={{ minWidth: 180, flexGrow: 1 }}>
            <InputLabel>Tipo Bobina</InputLabel>
            <Select value={filtroTipoBobina} label="Tipo Bobina" onChange={(e) => setFiltroTipoBobina(e.target.value)} disabled={loadingFiltersDropdown}>
              <MenuItem value=""><em>Todos</em></MenuItem>
              {tiposBobina.map(t => <MenuItem key={t.idTipoBobina} value={t.idTipoBobina}>{t.denominacion}</MenuItem>)}
            </Select>
          </FormControl>
          <TextField label="Nro. Bobina" size="small" value={filtroNroBobina} onChange={(e) => setFiltroNroBobina(e.target.value)} sx={{ minWidth: 150, flexGrow: 1 }} />
          <FormControl size="small" sx={{ minWidth: 180, flexGrow: 1 }}>
            <InputLabel>Planta</InputLabel>
            <Select value={filtroPlanta} label="Planta" onChange={(e) => setFiltroPlanta(e.target.value)} disabled={loadingFiltersDropdown}>
              <MenuItem value=""><em>Todas</em></MenuItem>
              {plantas.map(p => <MenuItem key={p.idPlanta} value={p.idPlanta}>{p.nombre}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl size="small" sx={{ minWidth: 180, flexGrow: 1 }}>
            <InputLabel>Estado</InputLabel>
            <Select value={filtroEstadoBobina} label="Estado" onChange={(e) => setFiltroEstadoBobina(e.target.value)} disabled={loadingFiltersDropdown}>
              <MenuItem value=""><em>Todos</em></MenuItem>
              {estadosBobina.map(e => <MenuItem key={e.idEstadoBobina} value={e.idEstadoBobina}>{e.denominacion}</MenuItem>)}
            </Select>
          </FormControl>
          <TextField label="Remito" size="small" value={filtroRemito} onChange={(e) => setFiltroRemito(e.target.value)} sx={{ minWidth: 150, flexGrow: 1 }} />
        </Box>
        <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
          <FormControlLabel
            control={<Checkbox checked={filtroFechaHabilitado} onChange={(e) => setFiltroFechaHabilitado(e.target.checked)} />}
            label="Filtrar por Fechas de Remitos"
          />
          <TextField label="Fecha Desde" type="date" size="small" value={filtroFechaDesde} onChange={(e) => setFiltroFechaDesde(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170 }} disabled={!filtroFechaHabilitado} />
          <TextField label="Fecha Hasta" type="date" size="small" value={filtroFechaHasta} onChange={(e) => setFiltroFechaHasta(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170 }} disabled={!filtroFechaHabilitado} />
        </Box>
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            flexWrap: 'wrap',
            gap: 2,
            mb: 2,
            justifyContent: 'flex-end'
          }}
        >
          <Button variant="contained" startIcon={<SearchIcon />} onClick={handleBuscarClick} disabled={loading}>Buscar</Button>
          <Button variant="outlined" startIcon={<ClearIcon />} onClick={handleLimpiarFiltros} disabled={loading}>Limpiar Filtros</Button>
        </Box>
        {puedeIngresar && (<Button variant="contained" startIcon={<AddIcon />} onClick={handleOpenIngresoModal} sx={{ ml: 'auto' }}>Ingresar Bobina</Button>)}

      </Paper>

      {loading && <Box sx={{ display: 'flex', justifyContent: 'center', my: 2 }}><CircularProgress /></Box>}
      {error && !loading && <Alert severity="warning" sx={{ my: 2 }}>{error}</Alert>}
      {apiErrorMessage && <Alert severity="error" sx={{ my: 2 }}>{apiErrorMessage}</Alert>}

      {!loading && !error && (
        <TableContainer component={Paper}>
          <Table size="small">
            <TableHead><TableRow>
              <TableCell>Nro. Bobina</TableCell><TableCell>Tipo</TableCell><TableCell>Peso (Kg)</TableCell>
              <TableCell>Planta</TableCell><TableCell>Estado</TableCell><TableCell>Remito</TableCell>
              <TableCell>F. Remito</TableCell><TableCell>F. Estado</TableCell>
              <TableCell>Publicación</TableCell><TableCell>Sección</TableCell>
              <TableCell>Obs.</TableCell>
              {(puedeModificarDatos || puedeCambiarEstado || puedeEliminar) && <TableCell align="right">Acciones</TableCell>}
            </TableRow></TableHead>
            <TableBody>
              {displayData.length === 0 ? (
                <TableRow><TableCell colSpan={(puedeModificarDatos || puedeCambiarEstado || puedeEliminar) ? 12 : 11} align="center">No se encontraron bobinas con los filtros aplicados. Haga clic en "Buscar" para iniciar una consulta.</TableCell></TableRow>
              ) : (
                displayData.map((b) => (
                  <TableRow key={b.idBobina} hover>
                    <TableCell>{b.nroBobina}</TableCell><TableCell>{b.nombreTipoBobina}</TableCell>
                    <TableCell align="right">{b.peso}</TableCell><TableCell>{b.nombrePlanta}</TableCell>
                    <TableCell><Chip label={b.nombreEstadoBobina} size="small" color={
                      b.idEstadoBobina === ID_ESTADO_DISPONIBLE ? "success" : b.idEstadoBobina === ID_ESTADO_UTILIZADA ? "primary" : b.idEstadoBobina === ID_ESTADO_DANADA ? "error" : "default"
                    } /></TableCell>
                    <TableCell>{b.remito}</TableCell><TableCell>{formatDate(b.fechaRemito)}</TableCell>
                    <TableCell>{formatDate(b.fechaEstado)}</TableCell>
                    <TableCell>{b.nombrePublicacion || '-'}</TableCell><TableCell>{b.nombreSeccion || '-'}</TableCell>
                    <TableCell>{b.obs || '-'}</TableCell>
                    {(puedeModificarDatos || puedeCambiarEstado || puedeEliminar) && (
                      <TableCell align="right">
                        <IconButton onClick={(e) => handleMenuOpen(e, b)}
                          disabled={
                            !(b.idEstadoBobina === ID_ESTADO_DISPONIBLE && puedeModificarDatos) &&
                            !(puedeCambiarEstado) &&
                            !((b.idEstadoBobina === ID_ESTADO_DISPONIBLE || b.idEstadoBobina === ID_ESTADO_DANADA) && puedeEliminar)
                          }
                        ><MoreVertIcon /></IconButton>
                      </TableCell>
                    )}
                  </TableRow>
                )))}
            </TableBody>
          </Table>
          <TablePagination
            rowsPerPageOptions={[25, 50, 100]} component="div" count={stock.length}
            rowsPerPage={rowsPerPage} page={page} onPageChange={handleChangePage}
            onRowsPerPageChange={handleChangeRowsPerPage} labelRowsPerPage="Filas por página:"
          />
        </TableContainer>
      )}

      <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
        {selectedBobinaForRowMenu && puedeModificarDatos && selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DISPONIBLE && (
          <MenuItem onClick={() => { handleOpenEditModal(selectedBobinaForRowMenu); handleMenuClose(); }}>
            <EditIcon fontSize="small" sx={{ mr: 1 }} /> Editar Datos
          </MenuItem>
        )}
        {selectedBobinaForRowMenu && puedeCambiarEstado && (
          <MenuItem onClick={() => { handleOpenCambioEstadoModal(selectedBobinaForRowMenu); handleMenuClose(); }}>
            <SwapHorizIcon fontSize="small" sx={{ mr: 1 }} /> Cambiar Estado
          </MenuItem>
        )}
        {selectedBobinaForRowMenu && puedeEliminar &&
          (selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DISPONIBLE || selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DANADA) && (
            <MenuItem onClick={() => handleDeleteBobina(selectedBobinaForRowMenu)}>
              <DeleteIcon fontSize="small" sx={{ mr: 1 }} /> Eliminar Ingreso
            </MenuItem>
          )}
        {selectedBobinaForRowMenu &&
          !((selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DISPONIBLE && puedeModificarDatos)) &&
          !(puedeCambiarEstado) &&
          !(((selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DISPONIBLE || selectedBobinaForRowMenu.idEstadoBobina === ID_ESTADO_DANADA) && puedeEliminar)) &&
          <MenuItem disabled>Sin acciones disponibles</MenuItem>
        }
      </Menu>

      {/* Modales sin cambios */}
      <StockBobinaIngresoFormModal
        open={ingresoModalOpen} onClose={handleCloseIngresoModal} onSubmit={handleSubmitIngresoModal}
        errorMessage={apiErrorMessage} clearErrorMessage={() => setApiErrorMessage(null)}
      />
      {editModalOpen && selectedBobina &&
        <StockBobinaEditFormModal
          open={editModalOpen} onClose={handleCloseEditModal} onSubmit={handleSubmitEditModal}
          initialData={selectedBobina} errorMessage={apiErrorMessage}
          clearErrorMessage={() => setApiErrorMessage(null)}
        />
      }
      {cambioEstadoModalOpen && selectedBobina &&
        <StockBobinaCambioEstadoModal
          open={cambioEstadoModalOpen} onClose={handleCloseCambioEstadoModal} onSubmit={handleSubmitCambioEstadoModal}
          bobinaActual={selectedBobina} errorMessage={apiErrorMessage}
          clearErrorMessage={() => setApiErrorMessage(null)}
        />
      }
    </Box>
  );
};

export default GestionarStockBobinasPage;