// src/pages/Impresion/GestionarStockBobinasPage.tsx
import React, { useState, useEffect, useCallback } from 'react';
import {
  Box, Typography, TextField, Button, Paper, IconButton, Menu, MenuItem, Chip,
  Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination,
  CircularProgress, Alert, FormControl, InputLabel, Select
} 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 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(true);
  const [error, setError] = useState<string | null>(null);
  const [apiErrorMessage, setApiErrorMessage] = useState<string | null>(null);

  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 [filtroFechaDesde, setFiltroFechaDesde] = useState<string>(new Date().toISOString().split('T')[0]);
  const [filtroFechaHasta, setFiltroFechaHasta] = useState<string>(new Date().toISOString().split('T')[0]);

  const [tiposBobina, setTiposBobina] = useState<TipoBobinaDto[]>([]);
  const [plantas, setPlantas] = useState<PlantaDto[]>([]);
  const [estadosBobina, setEstadosBobina] = useState<EstadoBobinaDto[]>([]);
  const [loadingFiltersDropdown, setLoadingFiltersDropdown] = useState(false);

  const [ingresoModalOpen, setIngresoModalOpen] = useState(false);
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [cambioEstadoModalOpen, setCambioEstadoModalOpen] = useState(false);

  const [selectedBobina, setSelectedBobina] = useState<StockBobinaDto | null>(null); // Para los modales

  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const [selectedBobinaForRowMenu, setSelectedBobinaForRowMenu] = useState<StockBobinaDto | null>(null); // Para el menú contextual

  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 fetchFiltersDropdownData = useCallback(async () => {
    setLoadingFiltersDropdown(true);
    try {
      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: filtroFechaDesde || null,
        fechaHasta: filtroFechaHasta || null,
      };
      const data = await stockBobinaService.getAllStockBobinas(params);
      setStock(data);
    } catch (err) {
      console.error(err); setError('Error al cargar el stock de bobinas.');
    } finally { setLoading(false); }
  }, [puedeVer, filtroTipoBobina, filtroNroBobina, filtroPlanta, filtroEstadoBobina, filtroRemito, filtroFechaDesde, filtroFechaHasta]);

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

  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);
    // Devolver el foco al botón que abrió el menú (si el modal se abrió desde el menú)
    if (lastOpenedMenuButtonRef.current) {
        setTimeout(() => { // setTimeout puede ayudar
            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); setSelectedBobina(null); };
  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;
    // Permitir eliminar si está Disponible (1) o Dañada (3)
    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 lastOpenedMenuButtonRef = React.useRef<HTMLButtonElement | null>(null);

  const handleMenuOpen = (event: React.MouseEvent<HTMLButtonElement>, bobina: StockBobinaDto) => {
    setAnchorEl(event.currentTarget);
    setSelectedBobinaForRowMenu(bobina);
    lastOpenedMenuButtonRef.current = event.currentTarget; // Guardar el botón que abrió el menú
  };

  const handleMenuClose = () => {
    setAnchorEl(null);
    // No es estrictamente necesario limpiar selectedBobinaForRowMenu aquí,
    // ya que se actualiza en el siguiente handleMenuOpen.
    // Pero se puede ser explícito:
    setSelectedBobinaForRowMenu(null);

    // Devolver el foco al botón que abrió el menú si existe
    if (lastOpenedMenuButtonRef.current) {
      setTimeout(() => { // Pequeño retraso para asegurar que el menú se haya cerrado visualmente
        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) => dateString ? new Date(dateString + 'T00:00:00Z').toLocaleDateString('es-AR') : '-';

  if (!loading && !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 }}>
        {/* ... (Filtros sin cambios) ... */}
        <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 }} />
          <TextField label="Fecha Desde" type="date" size="small" value={filtroFechaDesde} onChange={(e) => setFiltroFechaDesde(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170, flexGrow: 1 }} />
          <TextField label="Fecha Hasta" type="date" size="small" value={filtroFechaHasta} onChange={(e) => setFiltroFechaHasta(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170, flexGrow: 1 }} />
        </Box>
        {puedeIngresar && (<Button variant="contained" startIcon={<AddIcon />} onClick={handleOpenIngresoModal} sx={{ mt: 2 }}>Ingresar Bobina</Button>)}
      </Paper>

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

      {!loading && !error && puedeVer && (
        <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>
              {/* Mostrar columna de acciones si tiene algún permiso de acción */}
              {(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.</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)}
                          // El botón de menú se deshabilita si no hay NINGUNA acción posible para esa fila
                          disabled={
                            !(b.idEstadoBobina === ID_ESTADO_DISPONIBLE && puedeModificarDatos) &&
                            !(puedeCambiarEstado) && // Siempre se puede intentar cambiar estado (el modal lo validará)
                            !((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>
        )}
        {/* --- CAMBIO: Permitir cambiar estado incluso si está Dañada --- */}
        {selectedBobinaForRowMenu && puedeCambiarEstado && (
          <MenuItem onClick={() => { handleOpenCambioEstadoModal(selectedBobinaForRowMenu); handleMenuClose(); }}>
            <SwapHorizIcon fontSize="small" sx={{ mr: 1 }} /> Cambiar Estado
          </MenuItem>
        )}
        {/* --- CAMBIO: Permitir eliminar si está Disponible o Dañada --- */}
        {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>
          )}

        {/* Lógica para el MenuItem "Sin acciones" */}
        {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>

      <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;