import React, { useState, useEffect, useCallback } from 'react';
import { Box, Typography, Paper, Alert, Button, CircularProgress, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Chip, Select, MenuItem, FormControl, InputLabel, Tabs, Tab } from '@mui/material';
import facturacionService from '../../services/Suscripciones/facturacionService';
import type { LoteDeEnvioHistorialDto, LoteDeEnvioResumenDto } from '../../models/dtos/Comunicaciones/LoteDeEnvioDto';
import ResultadoEnvioModal from '../../components/Modals/Suscripciones/ResultadoEnvioModal';
import { usePermissions } from '../../hooks/usePermissions';
import type { ProcesamientoLoteResponseDto } from '../../models/dtos/Suscripciones/ProcesamientoLoteResponseDto';

const anios = Array.from({ length: 10 }, (_, i) => new Date().getFullYear() - i);
const meses = [
    { value: 1, label: 'Enero' }, { value: 2, label: 'Febrero' }, { value: 3, label: 'Marzo' },
    { value: 4, label: 'Abril' }, { value: 5, label: 'Mayo' }, { value: 6, label: 'Junio' },
    { value: 7, label: 'Julio' }, { value: 8, label: 'Agosto' }, { value: 9, label: 'Septiembre' },
    { value: 10, label: 'Octubre' }, { value: 11, label: 'Noviembre' }, { value: 12, label: 'Diciembre' }
];

// --- Sub-componente para renderizar la Pestaña de Historial ---
const TabHistorial: React.FC<{ 
    puedeConsultar: boolean;
    onVerDetalles: (lote: LoteDeEnvioHistorialDto) => void;
    formatDate: (date: string) => string;
}> = ({ puedeConsultar, onVerDetalles, formatDate }) => {
    const [historial, setHistorial] = useState<LoteDeEnvioHistorialDto[]>([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [filtroAnio, setFiltroAnio] = useState<number>(new Date().getFullYear());
    const [filtroMes, setFiltroMes] = useState<number>(new Date().getMonth() + 1);

    const cargarHistorial = useCallback(async () => {
        if (!puedeConsultar) { setLoading(false); return; }
        setLoading(true); setError(null);
        try {
            const data = await facturacionService.getHistorialLotesEnvio(filtroAnio, filtroMes);
            setHistorial(data);
        } catch (error) {
            setError("No se pudo cargar el historial de cierres.");
        } finally {
            setLoading(false);
        }
    }, [puedeConsultar, filtroAnio, filtroMes]);

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

    return (
        <Box>
            <Paper sx={{ p: 2, mb: 2 }}>
                <Typography variant="subtitle1" gutterBottom>Filtrar Historial</Typography>
                <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
                    <FormControl sx={{ minWidth: 150 }} size="small"><InputLabel>Mes</InputLabel><Select value={filtroMes} label="Mes" onChange={(e) => setFiltroMes(e.target.value as number)}>{meses.map(m => <MenuItem key={m.value} value={m.value}>{m.label}</MenuItem>)}</Select></FormControl>
                    <FormControl sx={{ minWidth: 120 }} size="small"><InputLabel>Año</InputLabel><Select value={filtroAnio} label="Año" onChange={(e) => setFiltroAnio(e.target.value as number)}>{anios.map(a => <MenuItem key={a} value={a}>{a}</MenuItem>)}</Select></FormControl>
                </Box>
            </Paper>

            {error && <Alert severity="error">{error}</Alert>}

            <TableContainer component={Paper}>
                <Table size="small">
                    <TableHead>
                        <TableRow>
                            <TableCell sx={{ fontWeight: 'bold' }}>Período</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }}>Fecha Proceso</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }}>Usuario</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }} align="center">Total Correos</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }} align="center">Enviados</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }} align="center">Fallidos</TableCell>
                            <TableCell sx={{ fontWeight: 'bold' }}>Acciones</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {loading ? (
                            <TableRow><TableCell colSpan={7} align="center"><CircularProgress /></TableCell></TableRow>
                        ) : historial.length === 0 ? (
                            <TableRow><TableCell colSpan={7} align="center">No hay registros para el período seleccionado.</TableCell></TableRow>
                        ) : (
                            historial.map(lote => (
                                <TableRow key={lote.idLoteDeEnvio} hover>
                                    <TableCell sx={{ fontWeight: 'bold' }}>{lote.periodo}</TableCell>
                                    <TableCell>{formatDate(lote.fechaInicio)}</TableCell>
                                    <TableCell>{lote.nombreUsuarioDisparo}</TableCell>
                                    <TableCell align="center">{lote.totalCorreos}</TableCell>
                                    <TableCell align="center"><Chip label={lote.totalEnviados} color="success" size="small" variant="outlined" /></TableCell>
                                    <TableCell align="center"><Chip label={lote.totalFallidos} color={lote.totalFallidos > 0 ? 'error' : 'default'} size="small" variant="outlined" /></TableCell>
                                    <TableCell>
                                        <Button size="small" onClick={() => onVerDetalles(lote)}>Detalles</Button>
                                    </TableCell>
                                </TableRow>
                            ))
                        )}
                    </TableBody>
                </Table>
            </TableContainer>
        </Box>
    );
};

const CierreYProcesosPage: React.FC = () => {
    const [activeTab, setActiveTab] = useState(0);
    const [selectedAnio, setSelectedAnio] = useState<number>(new Date().getFullYear());
    const [selectedMes, setSelectedMes] = useState<number>(new Date().getMonth() + 1);
    const [loadingCierre, setLoadingCierre] = useState(false);
    const [apiMessage, setApiMessage] = useState<string | null>(null);
    const [apiError, setApiError] = useState<string | null>(null);
    const [loadingArchivoDebito, setLoadingArchivoDebito] = useState(false);
    const [selectedFile, setSelectedFile] = useState<File | null>(null);
    const [loadingRespuesta, setLoadingRespuesta] = useState(false);
    const [respuestaProceso, setRespuestaProceso] = useState<ProcesamientoLoteResponseDto | null>(null);
    const [ultimoResultadoEnvio, setUltimoResultadoEnvio] = useState<LoteDeEnvioResumenDto | null>(null);
    const [modalOpen, setModalOpen] = useState(false);
    const [selectedLoteId, setSelectedLoteId] = useState<number | null>(null);
    const [selectedLotePeriodo, setSelectedLotePeriodo] = useState("");

    const { tienePermiso, isSuperAdmin } = usePermissions();
    const puedeGestionarCierre = isSuperAdmin || tienePermiso("SU006");
    const puedeGestionarDebitos = isSuperAdmin || tienePermiso("SU007");

    const handleGenerarCierre = async () => {
        if (!window.confirm(`¿Está seguro de que desea generar el cierre y la facturación para ${meses.find(m => m.value === selectedMes)?.label} de ${selectedAnio}? Esta acción no se puede deshacer y enviará avisos por email.`)) return;
        setLoadingCierre(true);
        setApiMessage(null);
        setApiError(null);
        setUltimoResultadoEnvio(null);
        try {
            const { message, resultadoEnvio } = await facturacionService.generarFacturacionMensual(selectedAnio, selectedMes);
            setApiMessage(message);
            if (resultadoEnvio) {
                setUltimoResultadoEnvio(resultadoEnvio);
            }
        } catch (err: any) {
            setApiError(err.response?.data?.message || 'Error al generar el cierre del período.');
        } finally {
            setLoadingCierre(false);
        }
    };

    const handleGenerarArchivoDebito = async () => {
        setLoadingArchivoDebito(true);
        setApiError(null);
        try {
            const { fileContent, fileName } = await facturacionService.generarArchivoDebito(selectedAnio, selectedMes);
            const url = window.URL.createObjectURL(new Blob([fileContent]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', fileName);
            document.body.appendChild(link);
            link.click();
            link.parentNode?.removeChild(link);
            window.URL.revokeObjectURL(url);
        } catch (err: any) {
            setApiError(err.response?.data?.message || 'Error al generar el archivo de débito.');
        } finally {
            setLoadingArchivoDebito(false);
        }
    };

    const handleProcesarRespuesta = async () => {
        if (!selectedFile) {
            setApiError("Por favor, seleccione un archivo de respuesta.");
            return;
        }
        setLoadingRespuesta(true);
        setApiError(null);
        setRespuestaProceso(null);
        try {
            const data = await facturacionService.procesarArchivoRespuesta(selectedFile);
            setRespuestaProceso(data);
            setApiMessage("Archivo de respuesta procesado exitosamente.");
        } catch (err: any) {
            const message = err.response?.data?.message || 'Error al procesar el archivo.';
            setApiError(message);
            if (err.response?.data) {
                setRespuestaProceso(err.response.data);
            }
        } finally {
            setLoadingRespuesta(false);
        }
    };

    const handleOpenModal = (lote: LoteDeEnvioHistorialDto) => {
        setSelectedLoteId(lote.idLoteDeEnvio);
        setSelectedLotePeriodo(lote.periodo);
        setModalOpen(true);
    };

    const formatDisplayDateTime = (dateString: string): string => {
        if (!dateString) return '';
        const date = new Date(dateString);
        return date.toLocaleString('es-AR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
    };

    if (!puedeGestionarCierre && !puedeGestionarDebitos) {
        return <Alert severity="error">No tiene permiso para acceder a esta sección.</Alert>;
    }

    return (
        <Box sx={{ p: { xs: 1, sm: 2 } }}>
            <Typography variant="h5" gutterBottom>Cierre de Período y Procesos Mensuales</Typography>
            
            <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}>
                <Tabs value={activeTab} onChange={(_event, newValue) => setActiveTab(newValue)}>
                    <Tab label="Procesos Mensuales" />
                    <Tab label="Historial de Cierres" />
                </Tabs>
            </Box>

            {activeTab === 0 && (
                <Box>
                    {apiError && <Alert severity="error" sx={{ mb: 2 }} onClose={() => setApiError(null)}>{apiError}</Alert>}
                    {apiMessage && <Alert severity="success" sx={{ mb: 2 }} onClose={() => setApiMessage(null)}>{apiMessage}</Alert>}

                    {puedeGestionarCierre && (
                        <Paper sx={{ p: 2, mb: 3 }}>
                            <Typography variant="h6">1. Generación de Cierre Mensual</Typography>
                            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                                Este proceso calcula las deudas, aplica ajustes y promociones, y envía los avisos de vencimiento por email.
                            </Typography>
                            <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
                                <FormControl sx={{ minWidth: 150 }} size="small"><InputLabel>Mes</InputLabel><Select value={selectedMes} label="Mes" onChange={(e) => setSelectedMes(e.target.value as number)}>{meses.map(m => <MenuItem key={m.value} value={m.value}>{m.label}</MenuItem>)}</Select></FormControl>
                                <FormControl sx={{ minWidth: 120 }} size="small"><InputLabel>Año</InputLabel><Select value={selectedAnio} label="Año" onChange={(e) => setSelectedAnio(e.target.value as number)}>{anios.map(a => <MenuItem key={a} value={a}>{a}</MenuItem>)}</Select></FormControl>
                                <Button onClick={handleGenerarCierre} variant="contained" disabled={loadingCierre}>{loadingCierre ? <CircularProgress size={24} /> : 'Generar Cierre del Período'}</Button>
                            </Box>
                            {ultimoResultadoEnvio && (
                                <Alert severity={ultimoResultadoEnvio.totalFallidos > 0 ? "warning" : "success"} sx={{ mt: 2 }}>
                                    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                        <Box>
                                            <Typography variant="subtitle1" component="div" sx={{ fontWeight: 'bold' }}>
                                                Resultado del envío de correos para {ultimoResultadoEnvio.periodo}
                                            </Typography>
                                            <Typography variant="body2">
                                                {ultimoResultadoEnvio.totalEnviados} enviados exitosamente, {ultimoResultadoEnvio.totalFallidos} fallidos.
                                            </Typography>
                                        </Box>
                                        <Button size="small" variant="outlined" color="inherit" onClick={() => {
                                            setSelectedLoteId(ultimoResultadoEnvio.idLoteDeEnvio);
                                            setSelectedLotePeriodo(ultimoResultadoEnvio.periodo);
                                            setModalOpen(true);
                                        }}>Ver Detalles</Button>
                                    </Box>
                                </Alert>
                            )}
                        </Paper>
                    )}

                    {puedeGestionarDebitos && (
                        <>
                            <Paper sx={{ p: 2, mb: 3 }}>
                                <Typography variant="h6">2. Generación de Archivo para Banco</Typography>
                                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                                    Genere el archivo de texto para procesar los débitos automáticos del período seleccionado.
                                </Typography>
                                <Button onClick={handleGenerarArchivoDebito} variant="contained" color="secondary" disabled={loadingArchivoDebito}>{loadingArchivoDebito ? <CircularProgress size={24} /> : 'Generar Archivo de Débito'}</Button>
                            </Paper>
                            <Paper sx={{ p: 2, mb: 3 }}>
                                <Typography variant="h6">3. Procesar Respuesta del Banco</Typography>
                                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                                    Suba el archivo de respuesta del banco para actualizar automáticamente el estado de los pagos.
                                </Typography>
                                <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
                                    <Button variant="outlined" component="label">
                                        Seleccionar Archivo
                                        <input type="file" hidden onChange={(e) => setSelectedFile(e.target.files ? e.target.files[0] : null)} />
                                    </Button>
                                    {selectedFile && <Typography variant="body2">{selectedFile.name}</Typography>}
                                    <Button onClick={handleProcesarRespuesta} variant="contained" color="secondary" disabled={loadingRespuesta || !selectedFile}>{loadingRespuesta ? <CircularProgress size={24} /> : 'Procesar Archivo'}</Button>
                                </Box>
                                {respuestaProceso && (
                                    <Alert severity={respuestaProceso.errores.length > 0 ? "warning" : "info"} sx={{ mt: 2 }}>
                                        {respuestaProceso.mensajeResumen}
                                        {respuestaProceso.errores.length > 0 && (
                                            <ul>{respuestaProceso.errores.map((e: string, i: number) => <li key={i}>{e}</li>)}</ul>
                                        )}
                                    </Alert>
                                )}
                            </Paper>
                        </>
                    )}
                </Box>
            )}

            {activeTab === 1 && (
                <TabHistorial 
                    puedeConsultar={puedeGestionarCierre}
                    onVerDetalles={handleOpenModal}
                    formatDate={formatDisplayDateTime}
                />
            )}

            <ResultadoEnvioModal
                open={modalOpen}
                onClose={() => setModalOpen(false)}
                loteId={selectedLoteId}
                periodo={selectedLotePeriodo}
            />
        </Box>
    );
};

export default CierreYProcesosPage;