import React, { useState, useEffect } from 'react';
import {
  Modal, Box, Typography, TextField, Button, CircularProgress, Alert,
  FormControl, InputLabel, Select, MenuItem
} from '@mui/material';
import type { CrearCierreDto } from '../../../models/dtos/Contables/CrearCierreDto';
import type { CierreCuentaCorrienteDto } from '../../../models/dtos/Contables/CierreCuentaCorrienteDto';
import type { DistribuidorDropdownDto } from '../../../models/dtos/Distribucion/DistribuidorDropdownDto';
import type { EmpresaDropdownDto } from '../../../models/dtos/Distribucion/EmpresaDropdownDto';
import distribuidorService from '../../../services/Distribucion/distribuidorService';
import empresaService from '../../../services/Distribucion/empresaService';

const modalStyle = {
  position: 'absolute' as const,
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  width: { xs: '90%', sm: 600 },
  bgcolor: 'background.paper',
  border: '2px solid #000',
  boxShadow: 24,
  p: 4,
  maxHeight: '90vh',
  overflowY: 'auto'
};

interface NuevoCierreModalProps {
  open: boolean;
  onClose: () => void;
  onSubmit: (data: CrearCierreDto) => Promise<CierreCuentaCorrienteDto>;
  initialIdDistribuidor?: number | null;
  initialIdEmpresa?: number | null;
  errorMessage?: string | null;
  clearErrorMessage: () => void;
}

const todayIso = () => new Date().toISOString().split('T')[0];

const NuevoCierreModal: React.FC<NuevoCierreModalProps> = ({
  open,
  onClose,
  onSubmit,
  initialIdDistribuidor,
  initialIdEmpresa,
  errorMessage,
  clearErrorMessage
}) => {
  const [idDistribuidor, setIdDistribuidor] = useState<number | string>('');
  const [idEmpresa, setIdEmpresa] = useState<number | string>('');
  const [fechaCorte, setFechaCorte] = useState<string>(todayIso());
  const [justificacion, setJustificacion] = useState<string>('');

  const [distribuidores, setDistribuidores] = useState<DistribuidorDropdownDto[]>([]);
  const [empresas, setEmpresas] = useState<EmpresaDropdownDto[]>([]);
  const [loading, setLoading] = useState(false);
  const [loadingDropdowns, setLoadingDropdowns] = useState(false);
  const [localErrors, setLocalErrors] = useState<{ [key: string]: string | null }>({});

  useEffect(() => {
    const fetchDropdownData = async () => {
      setLoadingDropdowns(true);
      try {
        const [distData, empData] = await Promise.all([
          distribuidorService.getAllDistribuidoresDropdown(),
          empresaService.getEmpresasDropdown()
        ]);
        setDistribuidores(distData);
        setEmpresas(empData);
      } catch (err) {
        console.error('Error al cargar dropdowns', err);
        setLocalErrors(prev => ({ ...prev, dropdowns: 'Error al cargar distribuidores o empresas.' }));
      } finally {
        setLoadingDropdowns(false);
      }
    };

    if (open) {
      fetchDropdownData();
      setIdDistribuidor(initialIdDistribuidor ?? '');
      setIdEmpresa(initialIdEmpresa ?? '');
      setFechaCorte(todayIso());
      setJustificacion('');
      setLocalErrors({});
      clearErrorMessage();
    }
  }, [open, initialIdDistribuidor, initialIdEmpresa, clearErrorMessage]);

  const validate = (): boolean => {
    const errors: { [key: string]: string | null } = {};
    if (!idDistribuidor) errors.idDistribuidor = 'Seleccione un distribuidor.';
    if (!idEmpresa) errors.idEmpresa = 'Seleccione una empresa.';
    if (!fechaCorte) {
      errors.fechaCorte = 'La fecha de corte es obligatoria.';
    } else if (new Date(fechaCorte) > new Date(todayIso())) {
      errors.fechaCorte = 'La fecha de corte no puede ser futura.';
    }
    if (justificacion.length > 500) {
      errors.justificacion = 'La justificación no puede superar los 500 caracteres.';
    }

    setLocalErrors(errors);
    return Object.keys(errors).length === 0;
  };

  const handleInputChange = (fieldName: string) => {
    if (localErrors[fieldName]) setLocalErrors(prev => ({ ...prev, [fieldName]: null }));
    if (errorMessage) clearErrorMessage();
  };

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    clearErrorMessage();
    if (!validate()) return;

    const distSeleccionado = distribuidores.find(d => d.idDistribuidor === Number(idDistribuidor));
    const empSeleccionada = empresas.find(e => e.idEmpresa === Number(idEmpresa));
    const confirmMsg = `Estás por cerrar el período hasta ${fechaCorte} para "${distSeleccionado?.nombre ?? ''}" en "${empSeleccionada?.nombre ?? ''}".\n\n` +
      `Después de cerrar no se podrán registrar movimientos, pagos, notas ni ajustes con fecha menor o igual a esta. ¿Continuar?`;
    if (!window.confirm(confirmMsg)) return;

    setLoading(true);
    try {
      const dto: CrearCierreDto = {
        idDistribuidor: Number(idDistribuidor),
        idEmpresa: Number(idEmpresa),
        fechaCorte,
        justificacion: justificacion.trim() || null
      };
      await onSubmit(dto);
      onClose();
    } catch (err) {
      console.error('Error al crear cierre:', err);
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose}>
      <Box sx={modalStyle}>
        <Typography variant="h6" component="h2" gutterBottom>
          Nuevo Cierre de Cuenta Corriente
        </Typography>
        <Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}>
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
            <FormControl fullWidth margin="dense" error={!!localErrors.idDistribuidor} required>
              <InputLabel id="distribuidor-cierre-label">Distribuidor</InputLabel>
              <Select
                labelId="distribuidor-cierre-label"
                label="Distribuidor"
                value={idDistribuidor}
                onChange={(e) => { setIdDistribuidor(e.target.value as number); handleInputChange('idDistribuidor'); }}
                disabled={loading || loadingDropdowns}
              >
                <MenuItem value="" disabled><em>Seleccione</em></MenuItem>
                {distribuidores.map((d) => (
                  <MenuItem key={d.idDistribuidor} value={d.idDistribuidor}>{d.nombre}</MenuItem>
                ))}
              </Select>
              {localErrors.idDistribuidor && <Typography color="error" variant="caption">{localErrors.idDistribuidor}</Typography>}
            </FormControl>

            <FormControl fullWidth margin="dense" error={!!localErrors.idEmpresa} required>
              <InputLabel id="empresa-cierre-label">Empresa</InputLabel>
              <Select
                labelId="empresa-cierre-label"
                label="Empresa"
                value={idEmpresa}
                onChange={(e) => { setIdEmpresa(e.target.value as number); handleInputChange('idEmpresa'); }}
                disabled={loading || loadingDropdowns}
              >
                <MenuItem value="" disabled><em>Seleccione</em></MenuItem>
                {empresas.map((e) => (
                  <MenuItem key={e.idEmpresa} value={e.idEmpresa}>{e.nombre}</MenuItem>
                ))}
              </Select>
              {localErrors.idEmpresa && <Typography color="error" variant="caption">{localErrors.idEmpresa}</Typography>}
            </FormControl>

            <TextField
              label="Fecha de Corte"
              type="date"
              value={fechaCorte}
              required
              onChange={(e) => { setFechaCorte(e.target.value); handleInputChange('fechaCorte'); }}
              margin="dense"
              fullWidth
              error={!!localErrors.fechaCorte}
              helperText={localErrors.fechaCorte || 'No puede ser una fecha futura.'}
              disabled={loading}
              InputLabelProps={{ shrink: true }}
              inputProps={{ max: todayIso() }}
            />

            <Alert severity="info" sx={{ mt: 0.5 }}>
              La fecha de corte es inclusive: los movimientos con fecha igual a la seleccionada se
              incluyen en el cálculo del saldo de cierre.
            </Alert>

            <TextField
              label="Justificación (opcional)"
              value={justificacion}
              onChange={(e) => { setJustificacion(e.target.value); handleInputChange('justificacion'); }}
              margin="dense"
              fullWidth
              multiline
              rows={3}
              disabled={loading}
              error={!!localErrors.justificacion}
              helperText={localErrors.justificacion || `${justificacion.length}/500 caracteres`}
              inputProps={{ maxLength: 500 }}
            />
          </Box>

          <Alert severity="warning" sx={{ mt: 2 }}>
            Una vez creado el cierre, no podrán registrarse, modificarse ni eliminarse pagos, notas, ajustes
            o movimientos cuya fecha de operación sea menor o igual a la fecha de corte.
          </Alert>

          {errorMessage && <Alert severity="error" sx={{ mt: 2, width: '100%' }}>{errorMessage}</Alert>}
          {localErrors.dropdowns && <Alert severity="warning" sx={{ mt: 1 }}>{localErrors.dropdowns}</Alert>}

          <Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end', gap: 1 }}>
            <Button onClick={onClose} color="secondary" disabled={loading}>Cancelar</Button>
            <Button type="submit" variant="contained" disabled={loading || loadingDropdowns}>
              {loading ? <CircularProgress size={24} /> : 'Crear Cierre'}
            </Button>
          </Box>
        </Box>
      </Box>
    </Modal>
  );
};

export default NuevoCierreModal;
