import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  Modal, Box, Typography, TextField, Button, CircularProgress, Alert,
  FormControl, InputLabel, Select, MenuItem, Stepper, Step, StepLabel,
  Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton, Divider,
  InputAdornment, Tooltip
} from '@mui/material';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import EditIcon from '@mui/icons-material/Edit';
import CloseIcon from '@mui/icons-material/Close';

import type { StockBobinaDto } from '../../../models/dtos/Impresion/StockBobinaDto';
import type { CreateStockBobinaLoteDto } from '../../../models/dtos/Impresion/CreateStockBobinaLoteDto';
import type { BobinaLoteDetalleDto } from '../../../models/dtos/Impresion/BobinaLoteDetalleDto';
import type { PlantaDto } from '../../../models/dtos/Impresion/PlantaDto';
import type { TipoBobinaDto } from '../../../models/dtos/Impresion/TipoBobinaDto';
import stockBobinaService from '../../../services/Impresion/stockBobinaService';
import plantaService from '../../../services/Impresion/plantaService';
import tipoBobinaService from '../../../services/Impresion/tipoBobinaService';


const modalStyle = {
  position: 'absolute' as 'absolute',
  top: '50%', left: '50%',
  transform: 'translate(-50%, -50%)',
  width: { xs: '95%', sm: '80%', md: '900px' },
  bgcolor: 'background.paper',
  border: '2px solid #000', boxShadow: 24, p: 3,
  maxHeight: '90vh', overflowY: 'auto', display: 'flex', flexDirection: 'column'
};

interface NuevaBobinaState extends BobinaLoteDetalleDto {
  idTemporal: string;
}

interface StockBobinaLoteFormModalProps {
  open: boolean;
  onClose: (refrescar: boolean) => void;
}

const steps = ['Datos del Remito', 'Ingreso de Bobinas'];

const StockBobinaLoteFormModal: React.FC<StockBobinaLoteFormModalProps> = ({ open, onClose }) => {
  const [activeStep, setActiveStep] = useState(0);
  const [loading, setLoading] = useState(false);
  const [apiError, setApiError] = useState<string | null>(null);

  // Step 1 State
  const [idPlanta, setIdPlanta] = useState<number | ''>('');
  const [remito, setRemito] = useState('');
  const [fechaRemito, setFechaRemito] = useState(new Date().toISOString().split('T')[0]);
  const [headerErrors, setHeaderErrors] = useState<{ [key: string]: string }>({});
  const [isVerifying, setIsVerifying] = useState(false);
  const [remitoStatusMessage, setRemitoStatusMessage] = useState<string | null>(null);
  const [remitoStatusSeverity, setRemitoStatusSeverity] = useState<'success' | 'info'>('info');
  const [isDateAutocompleted, setIsDateAutocompleted] = useState(false);

  // Step 2 State
  const [bobinasExistentes, setBobinasExistentes] = useState<StockBobinaDto[]>([]);
  const [nuevasBobinas, setNuevasBobinas] = useState<NuevaBobinaState[]>([]);
  const [detalleErrors, setDetalleErrors] = useState<{ [key: string]: string }>({});

  // Dropdowns data
  const [plantas, setPlantas] = useState<PlantaDto[]>([]);
  const [tiposBobina, setTiposBobina] = useState<TipoBobinaDto[]>([]);
  const [loadingDropdowns, setLoadingDropdowns] = useState(true);
  const tableContainerRef = useRef<HTMLDivElement>(null);

  const resetState = useCallback(() => {
    setActiveStep(0); setLoading(false); setApiError(null);
    setIdPlanta(''); setRemito(''); setFechaRemito(new Date().toISOString().split('T')[0]);
    setHeaderErrors({}); setBobinasExistentes([]); setNuevasBobinas([]); setDetalleErrors({});
    setRemitoStatusMessage(null);
    setIsDateAutocompleted(false);
  }, []);

  useEffect(() => {
    const fetchDropdowns = async () => {
      setLoadingDropdowns(true);
      try {
        const [plantasData, tiposData] = await Promise.all([
          plantaService.getAllPlantas(),
          tipoBobinaService.getAllTiposBobina()
        ]);
        setPlantas(plantasData);
        setTiposBobina(tiposData);
      } catch (error) {
        setApiError("Error al cargar datos necesarios (plantas, tipos).");
      } finally {
        setLoadingDropdowns(false);
      }
    };
    if (open) {
      fetchDropdowns();
    } else {
      resetState();
    }
  }, [open, resetState]);

  useEffect(() => {
    const verificarRemitoParaAutocompletar = async () => {
      setRemitoStatusMessage(null);
      if (remito.trim() && idPlanta) {
        setIsVerifying(true);
        try {
          const existentes = await stockBobinaService.verificarRemitoExistente(Number(idPlanta), remito.trim());
          if (existentes.length > 0) {
            setFechaRemito(existentes[0].fechaRemito.split('T')[0]);
            setRemitoStatusMessage("Remito existente. Se autocompletó la fecha.");
            setRemitoStatusSeverity('info');
            setIsDateAutocompleted(true);
          } else {
            setRemitoStatusMessage("Este es un remito nuevo.");
            setRemitoStatusSeverity('success');
            setIsDateAutocompleted(false);
          }
        } catch (error) {
          console.error("Fallo la verificación automática de remito: ", error);
          setRemitoStatusMessage("No se pudo verificar el remito.");
          setRemitoStatusSeverity('info');
        } finally {
          setIsVerifying(false);
        }
      }
    };
    const handler = setTimeout(() => {
      verificarRemitoParaAutocompletar();
    }, 500);

    return () => {
      clearTimeout(handler);
    };
  }, [idPlanta, remito]);

  const handleClose = () => onClose(false);

  const handleNext = async () => {
    const errors: { [key: string]: string } = {};
    if (!remito.trim()) errors.remito = "El número de remito es obligatorio.";
    if (!idPlanta) errors.idPlanta = "Seleccione una planta.";
    if (!fechaRemito) errors.fechaRemito = "La fecha es obligatoria.";

    if (Object.keys(errors).length > 0) {
      setHeaderErrors(errors);
      return;
    }

    setLoading(true); setApiError(null);
    try {
      const existentes = await stockBobinaService.verificarRemitoExistente(Number(idPlanta), remito, fechaRemito);
      setBobinasExistentes(existentes);
      setActiveStep(1);
    } catch (error: any) {
      const message = error.response?.data?.message || "Error al verificar el remito.";
      setApiError(message);
    } finally {
      setLoading(false);
    }
  };

  const handleBack = () => setActiveStep(0);

  const handleAddBobina = () => {
    setNuevasBobinas(prev => [...prev, {
      idTemporal: crypto.randomUUID(), idTipoBobina: 0, nroBobina: '', peso: 0
    }]);
    setTimeout(() => {
      tableContainerRef.current?.scrollTo({ top: tableContainerRef.current.scrollHeight, behavior: 'smooth' });
    }, 100);
  };

  const handleRemoveBobina = (idTemporal: string) => {
    setNuevasBobinas(prev => prev.filter(b => b.idTemporal !== idTemporal));
  };

  const handleBobinaChange = (idTemporal: string, field: keyof NuevaBobinaState, value: any) => {
    setNuevasBobinas(prev => prev.map(b => b.idTemporal === idTemporal ? { ...b, [field]: value } : b));
  };

  const handleSubmit = async () => {
    const errors: { [key: string]: string } = {};
    if (nuevasBobinas.length === 0) {
      setApiError("Debe agregar al menos una nueva bobina para guardar.");
      return;
    }

    const todosNrosBobina = new Set(bobinasExistentes.map(b => b.nroBobina));
    nuevasBobinas.forEach(b => {
      if (!b.idTipoBobina) errors[b.idTemporal + '_tipo'] = "Requerido";
      if (!b.nroBobina.trim()) errors[b.idTemporal + '_nro'] = "Requerido";
      if ((b.peso || 0) <= 0) errors[b.idTemporal + '_peso'] = "Inválido";
      if (todosNrosBobina.has(b.nroBobina.trim())) errors[b.idTemporal + '_nro'] = "Duplicado";
      todosNrosBobina.add(b.nroBobina.trim());
    });

    if (Object.keys(errors).length > 0) {
      setDetalleErrors(errors);
      return;
    }

    setLoading(true); setApiError(null);
    try {
      const lote: CreateStockBobinaLoteDto = {
        idPlanta: Number(idPlanta),
        remito: remito.trim(),
        fechaRemito,
        bobinas: nuevasBobinas.map(({ idTipoBobina, nroBobina, peso }) => ({
          idTipoBobina: Number(idTipoBobina), nroBobina: nroBobina.trim(), peso: Number(peso)
        }))
      };
      await stockBobinaService.ingresarLoteBobinas(lote);
      onClose(true);
    } catch (error: any) {
      const message = error.response?.data?.message || "Error al guardar el lote de bobinas.";
      setApiError(message);
    } finally {
      setLoading(false);
    }
  };


  const renderStepContent = (step: number) => {
    switch (step) {
      case 0:
        return (
          <Box sx={{ p: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>
            <Typography variant="h6">Datos de Cabecera</Typography>
            <TextField label="Número de Remito" value={remito}
              onChange={e => {
                setRemito(e.target.value);
                setIsDateAutocompleted(false);
              }}
              required error={!!headerErrors.remito} helperText={headerErrors.remito} disabled={loading} autoFocus
            />
            <FormControl fullWidth error={!!headerErrors.idPlanta}>
              <InputLabel id="planta-label" required>Planta de Destino</InputLabel>
              <Select labelId="planta-label" value={idPlanta} label="Planta de Destino"
                onChange={e => {
                  setIdPlanta(e.target.value as number);
                  setIsDateAutocompleted(false);
                }}
                disabled={loading || loadingDropdowns}
                endAdornment={isVerifying && (<InputAdornment position="end" sx={{ mr: 2 }}><CircularProgress size={20} /></InputAdornment>)}
              >
                {plantas.map(p => <MenuItem key={p.idPlanta} value={p.idPlanta}>{p.nombre}</MenuItem>)}
              </Select>
              {headerErrors.idPlanta && <Typography color="error" variant="caption">{headerErrors.idPlanta}</Typography>}
            </FormControl>
            <TextField
              label="Fecha de Remito"
              type="date"
              value={fechaRemito}
              onChange={e => setFechaRemito(e.target.value)}
              InputLabelProps={{ shrink: true }}
              required
              error={!!headerErrors.fechaRemito}
              helperText={headerErrors.fechaRemito}
              disabled={loading || isDateAutocompleted}
              InputProps={{
                endAdornment: (
                  isDateAutocompleted && (
                    <InputAdornment position="end">
                      <Tooltip title="Editar fecha">
                        <IconButton onClick={() => setIsDateAutocompleted(false)} edge="end">
                          <EditIcon />
                        </IconButton>
                      </Tooltip>
                    </InputAdornment>
                  )
                )
              }}
            />

            <Box sx={{ minHeight: 48, mt: 1 }}>
              {remitoStatusMessage && !isVerifying && (
                <Alert severity={remitoStatusSeverity} icon={false} variant="outlined">
                  {remitoStatusMessage}
                </Alert>
              )}
            </Box>
          </Box>
        );
      case 1:
        return (
          <Box sx={{ p: 2, flexGrow: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
            {bobinasExistentes.length > 0 && (
              <>
                <Typography variant="subtitle1" gutterBottom>Bobinas ya ingresadas para este remito:</Typography>
                <TableContainer component={Paper} variant="outlined" sx={{ maxHeight: '150px', mb: 2 }}>
                  <Table size="small" stickyHeader>
                    <TableHead><TableRow><TableCell>Nro. Bobina</TableCell><TableCell>Tipo</TableCell><TableCell align="right">Peso (Kg)</TableCell></TableRow></TableHead>
                    <TableBody>
                      {bobinasExistentes.map(b => (
                        <TableRow key={b.idBobina}><TableCell>{b.nroBobina}</TableCell><TableCell>{b.nombreTipoBobina}</TableCell><TableCell align="right">{b.peso}</TableCell></TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </>
            )}
            <Typography variant="h6">Nuevas Bobinas a Ingresar</Typography>
            <TableContainer component={Paper} variant="outlined" sx={{ flexGrow: 1, my: 1, minHeight: '150px' }} ref={tableContainerRef}>
              <Table size="small" stickyHeader>
                <TableHead><TableRow><TableCell sx={{ minWidth: 200 }}>Tipo Bobina</TableCell><TableCell>Nro. Bobina</TableCell><TableCell>Peso (Kg)</TableCell><TableCell></TableCell></TableRow></TableHead>
                <TableBody>
                  {nuevasBobinas.map(bobina => (
                    <TableRow key={bobina.idTemporal}>
                      <TableCell><FormControl fullWidth size="small" error={!!detalleErrors[bobina.idTemporal + '_tipo']}><Select value={bobina.idTipoBobina} onChange={e => handleBobinaChange(bobina.idTemporal, 'idTipoBobina', e.target.value)} disabled={loadingDropdowns}><MenuItem value={0} disabled>Seleccione</MenuItem>{tiposBobina.map(t => <MenuItem key={t.idTipoBobina} value={t.idTipoBobina}>{t.denominacion}</MenuItem>)}</Select></FormControl></TableCell>
                      <TableCell><TextField fullWidth size="small" value={bobina.nroBobina} onChange={e => handleBobinaChange(bobina.idTemporal, 'nroBobina', e.target.value)} error={!!detalleErrors[bobina.idTemporal + '_nro']} helperText={detalleErrors[bobina.idTemporal + '_nro']} /></TableCell>
                      <TableCell><TextField fullWidth size="small" type="number" value={bobina.peso || ''} onChange={e => handleBobinaChange(bobina.idTemporal, 'peso', e.target.value)} error={!!detalleErrors[bobina.idTemporal + '_peso']} helperText={detalleErrors[bobina.idTemporal + '_peso']} /></TableCell>
                      <TableCell><IconButton size="small" color="error" onClick={() => handleRemoveBobina(bobina.idTemporal)}><DeleteOutlineIcon /></IconButton></TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </TableContainer>
            <Button startIcon={<AddCircleOutlineIcon />} onClick={handleAddBobina} sx={{ mt: 1 }}>Agregar Bobina</Button>
          </Box>
        );
      default:
        return null;
    }
  };

  return (
    <Modal open={open} onClose={handleClose}>
      <Box sx={modalStyle}>
        <IconButton
          aria-label="close"
          onClick={handleClose}
          sx={{
            position: 'absolute',
            right: 8,
            top: 8,
            color: (theme) => theme.palette.grey[500],
          }}
        >
          <CloseIcon />
        </IconButton>

        <Typography variant="h5" component="h2" gutterBottom>Ingreso de Bobinas por Lote</Typography>

        <Stepper activeStep={activeStep} sx={{ mb: 2 }}>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>

        <Box sx={{ flexGrow: 1, overflowY: 'auto' }}>
          {loadingDropdowns && activeStep === 0 ? <Box sx={{ display: 'flex', justifyContent: 'center', my: 5 }}><CircularProgress /></Box> : renderStepContent(activeStep)}
        </Box>

        {apiError && <Alert severity="error" sx={{ mt: 2, flexShrink: 0 }}>{apiError}</Alert>}

        <Divider sx={{ my: 2, flexShrink: 0 }} />

        <Box sx={{ display: 'flex', justifyContent: 'space-between', pt: 1, flexShrink: 0 }}>
          <Button color="inherit" disabled={activeStep === 0 || loading} onClick={handleBack}>
            Atrás
          </Button>
          <Box>
            {activeStep === 0 && <Button onClick={handleNext} variant="contained" disabled={loading || loadingDropdowns}>{loading ? <CircularProgress size={24} /> : 'Verificar y Continuar'}</Button>}
            {activeStep === 1 && <Button onClick={handleSubmit} variant="contained" color="success" disabled={loading}>{loading ? <CircularProgress size={24} /> : 'Guardar Lote'}</Button>}
          </Box>
        </Box>
      </Box>
    </Modal>
  );
};

export default StockBobinaLoteFormModal;