import React, { useState, useEffect, useCallback } from 'react';
import { Box, Typography, Button, Paper, CircularProgress, Alert, Select, MenuItem, FormControl, InputLabel, Table, TableContainer, TableHead, TableRow, TableCell, TableBody, Chip, IconButton, Menu, ListItemIcon, ListItemText } from '@mui/material';
import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline';
import DownloadIcon from '@mui/icons-material/Download';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import PaymentIcon from '@mui/icons-material/Payment';
import EmailIcon from '@mui/icons-material/Email';
import UploadFileIcon from '@mui/icons-material/UploadFile';
import { styled } from '@mui/material/styles';
import facturacionService from '../../services/Suscripciones/facturacionService';
import { usePermissions } from '../../hooks/usePermissions';
import axios from 'axios';
import type { FacturaDto } from '../../models/dtos/Suscripciones/FacturaDto';
import PagoManualModal from '../../components/Modals/Suscripciones/PagoManualModal';
import type { CreatePagoDto } from '../../models/dtos/Suscripciones/CreatePagoDto';

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' }
];

const VisuallyHiddenInput = styled('input')({
    clip: 'rect(0 0 0 0)', clipPath: 'inset(50%)', height: 1, overflow: 'hidden',
    position: 'absolute', bottom: 0, left: 0, whiteSpace: 'nowrap', width: 1,
});

const FacturacionPage: React.FC = () => {
    const [selectedAnio, setSelectedAnio] = useState<number>(new Date().getFullYear());
    const [selectedMes, setSelectedMes] = useState<number>(new Date().getMonth() + 1);
    const [loading, setLoading] = useState(false);
    const [loadingArchivo, setLoadingArchivo] = useState(false);
    const [loadingProceso, setLoadingProceso] = useState(false);
    const [apiMessage, setApiMessage] = useState<string | null>(null);
    const [apiError, setApiError] = useState<string | null>(null);
    const [facturas, setFacturas] = useState<FacturaDto[]>([]);
    const { tienePermiso, isSuperAdmin } = usePermissions();
    const puedeGenerarFacturacion = isSuperAdmin || tienePermiso("SU006");
    const puedeGenerarArchivo = isSuperAdmin || tienePermiso("SU007");
    const puedeRegistrarPago = isSuperAdmin || tienePermiso("SU008");
    const puedeEnviarEmail = isSuperAdmin || tienePermiso("SU009");
    const [pagoModalOpen, setPagoModalOpen] = useState(false);
    const [selectedFactura, setSelectedFactura] = useState<FacturaDto | null>(null);
    const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
    const [archivoSeleccionado, setArchivoSeleccionado] = useState<File | null>(null);

    const cargarFacturasDelPeriodo = useCallback(async () => {
        if (!puedeGenerarFacturacion) return;
        setLoading(true);
        try {
            const data = await facturacionService.getFacturasPorPeriodo(selectedAnio, selectedMes);
            setFacturas(data);
        } catch (err) {
            setFacturas([]);
            console.error(err);
        } finally {
            setLoading(false);
        }
    }, [selectedAnio, selectedMes, puedeGenerarFacturacion]);

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

    const handleGenerarFacturacion = async () => {
        if (!window.confirm(`¿Está seguro de que desea generar la facturación para ${meses.find(m => m.value === selectedMes)?.label} de ${selectedAnio}? Este proceso creará registros de cobro para todas las suscripciones activas.`)) {
            return;
        }
        setLoading(true);
        setApiMessage(null);
        setApiError(null);
        try {
            const response = await facturacionService.generarFacturacionMensual(selectedAnio, selectedMes);
            setApiMessage(`${response.message}. Se generaron ${response.facturasGeneradas} facturas.`);
            await cargarFacturasDelPeriodo();
        } catch (err: any) {
            const message = axios.isAxiosError(err) && err.response?.data?.message
                ? err.response.data.message
                : 'Ocurrió un error al generar la facturación.';
            setApiError(message);
        } finally {
            setLoading(false);
        }
    };

    const handleGenerarArchivo = async () => {
        if (!window.confirm(`Se generará el archivo de débito para las facturas del período ${meses.find(m => m.value === selectedMes)?.label}/${selectedAnio} que estén en estado 'Pendiente de Cobro'. ¿Continuar?`)) {
            return;
        }
        setLoadingArchivo(true);
        setApiMessage(null);
        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);
            setApiMessage(`Archivo "${fileName}" generado y descargado exitosamente.`);
            cargarFacturasDelPeriodo();
        } catch (err: any) {
            let message = 'Ocurrió un error al generar el archivo.';
            if (axios.isAxiosError(err) && err.response) {
                const errorText = await err.response.data.text();
                try {
                    const errorJson = JSON.parse(errorText);
                    message = errorJson.message || message;
                } catch { message = errorText || message; }
            }
            setApiError(message);
        } finally {
            setLoadingArchivo(false);
        }
    };

    const handleMenuOpen = (event: React.MouseEvent<HTMLElement>, factura: FacturaDto) => {
        setAnchorEl(event.currentTarget);
        setSelectedFactura(factura);
    };

    const handleMenuClose = () => {
        setAnchorEl(null);
        setSelectedFactura(null);
    };

    const handleOpenPagoModal = () => {
        setPagoModalOpen(true);
        handleMenuClose();
    };

    const handleClosePagoModal = () => {
        setPagoModalOpen(false);
    };

    const handleSubmitPagoModal = async (data: CreatePagoDto) => {
        setApiError(null);
        try {
            await facturacionService.registrarPagoManual(data);
            setApiMessage(`Pago para la factura #${data.idFactura} registrado exitosamente.`);
            cargarFacturasDelPeriodo();
        } catch (err: any) {
            const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al registrar el pago.';
            setApiError(message);
            throw err;
        }
    };

    const handleSendEmail = async (idFactura: number) => {
        if (!window.confirm(`¿Está seguro de enviar la notificación de la factura #${idFactura} por email?`)) return;
        setApiMessage(null);
        setApiError(null);
        try {
            await facturacionService.enviarFacturaPorEmail(idFactura);
            setApiMessage(`El email para la factura #${idFactura} ha sido enviado a la cola de procesamiento.`);
        } catch (err: any) {
            setApiError(err.response?.data?.message || 'Error al intentar enviar el email.');
        } finally {
            handleMenuClose();
        }
    };

    const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        if (event.target.files && event.target.files.length > 0) {
            setArchivoSeleccionado(event.target.files[0]);
            setApiMessage(null);
            setApiError(null);
        }
    };

    const handleProcesarArchivo = async () => {
        if (!archivoSeleccionado) {
            setApiError("Por favor, seleccione un archivo de respuesta para procesar.");
            return;
        }
        setLoadingProceso(true);
        setApiMessage(null);
        setApiError(null);
        try {
            const response = await facturacionService.procesarArchivoRespuesta(archivoSeleccionado);
            setApiMessage(response.mensajeResumen);
            if (response.errores?.length > 0) {
                setApiError(`Se encontraron los siguientes problemas durante el proceso:\n${response.errores.join('\n')}`);
            }
            cargarFacturasDelPeriodo(); // Recargar para ver los estados finales
        } catch (err: any) {
            const message = axios.isAxiosError(err) && err.response?.data?.mensajeResumen
                ? err.response.data.mensajeResumen
                : 'Ocurrió un error crítico al procesar el archivo.';
            setApiError(message);
        } finally {
            setLoadingProceso(false);
            setArchivoSeleccionado(null);
        }
    };

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

    return (
        <Box sx={{ p: 1 }}>
            <Typography variant="h5" gutterBottom>Facturación y Débito Automático</Typography>
            <Paper sx={{ p: 2, mb: 2 }}>
                <Typography variant="h6">1. Generación de Facturación</Typography>
                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                    Este proceso calcula los importes a cobrar para todas las suscripciones activas en el período seleccionado.
                </Typography>
                <Box sx={{ display: 'flex', gap: 2, mb: 2, alignItems: 'center' }}>
                    <FormControl sx={{ minWidth: 120 }} 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>
                </Box>
                <Button variant="contained" color="primary" startIcon={loading ? <CircularProgress size={20} color="inherit" /> : <PlayCircleOutlineIcon />} onClick={handleGenerarFacturacion} disabled={loading || loadingArchivo}>Generar Facturación del Período</Button>
            </Paper>
            <Paper sx={{ p: 2, mb: 2 }}>
                <Typography variant="h6">2. Generación de Archivo para Banco</Typography>
                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>Crea el archivo de texto para enviar a "Pago Directo Galicia" con todas las facturas del período que estén listas para el cobro.</Typography>
                <Button variant="contained" color="secondary" startIcon={loadingArchivo ? <CircularProgress size={20} color="inherit" /> : <DownloadIcon />} onClick={handleGenerarArchivo} disabled={loading || loadingArchivo || !puedeGenerarArchivo}>Generar Archivo de Débito</Button>
            </Paper>

            <Paper sx={{ p: 2, mb: 2 }}>
                <Typography variant="h6">3. Procesar Respuesta del Banco</Typography>
                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                    Suba aquí el archivo de respuesta de Galicia para actualizar automáticamente el estado de las facturas a "Pagada" o "Rechazada".
                </Typography>
                <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
                    <Button
                        component="label"
                        role={undefined}
                        variant="outlined"
                        tabIndex={-1}
                        startIcon={<UploadFileIcon />}
                        disabled={loadingProceso}
                    >
                        Seleccionar Archivo
                        <VisuallyHiddenInput type="file" onChange={handleFileChange} accept=".txt, text/plain" />
                    </Button>
                    {archivoSeleccionado && <Typography variant="body2">{archivoSeleccionado.name}</Typography>}
                </Box>
                {archivoSeleccionado && (
                    <Button
                        variant="contained"
                        color="success"
                        sx={{ mt: 2 }}
                        onClick={handleProcesarArchivo}
                        disabled={loadingProceso}
                        startIcon={loadingProceso ? <CircularProgress size={20} color="inherit" /> : <PlayCircleOutlineIcon />}
                    >
                        Procesar Archivo de Respuesta
                    </Button>
                )}
            </Paper>

            {apiError && <Alert severity="error" sx={{ my: 2 }}>{apiError}</Alert>}
            {apiMessage && <Alert severity="success" sx={{ my: 2 }}>{apiMessage}</Alert>}

            <Typography variant="h6" sx={{ mt: 4 }}>Facturas del Período</Typography>
            <TableContainer component={Paper}>
                <Table size="small">
                    <TableHead>
                        <TableRow>
                            <TableCell>ID</TableCell><TableCell>Suscriptor</TableCell><TableCell>Publicación</TableCell>
                            <TableCell align="right">Importe</TableCell><TableCell>Estado</TableCell><TableCell>Nro. Factura</TableCell>
                            <TableCell align="right" sx={{ fontWeight: 'bold' }}>Acciones</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {loading ? (<TableRow><TableCell colSpan={7} align="center"><CircularProgress /></TableCell></TableRow>)
                            : facturas.length === 0 ? (<TableRow><TableCell colSpan={7} align="center">No hay facturas para el período seleccionado.</TableCell></TableRow>)
                                : (facturas.map(f => (
                                    <TableRow key={f.idFactura} hover>
                                        <TableCell>{f.idFactura}</TableCell>
                                        <TableCell>{f.nombreSuscriptor}</TableCell>
                                        <TableCell>{f.nombrePublicacion}</TableCell>
                                        <TableCell align="right">${f.importeFinal.toFixed(2)}</TableCell>
                                        <TableCell><Chip label={f.estado} size="small" color={f.estado === 'Pagada' ? 'success' : (f.estado === 'Rechazada' ? 'error' : 'default')} /></TableCell>
                                        <TableCell>{f.numeroFactura || '-'}</TableCell>
                                        <TableCell align="right">
                                            <IconButton onClick={(e) => handleMenuOpen(e, f)} disabled={f.estado === 'Pagada' || f.estado === 'Anulada'}>
                                                <MoreVertIcon />
                                            </IconButton>
                                        </TableCell>
                                    </TableRow>
                                )))}
                    </TableBody>
                </Table>
            </TableContainer>
            <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
                {selectedFactura && puedeRegistrarPago && (
                    <MenuItem onClick={handleOpenPagoModal}>
                        <ListItemIcon><PaymentIcon fontSize="small" /></ListItemIcon>
                        <ListItemText>Registrar Pago Manual</ListItemText>
                    </MenuItem>
                )}
                {selectedFactura && puedeEnviarEmail && (
                    <MenuItem
                        onClick={() => handleSendEmail(selectedFactura.idFactura)}
                        disabled={!selectedFactura.numeroFactura}
                    >
                        <ListItemIcon><EmailIcon fontSize="small" /></ListItemIcon>
                        <ListItemText>Enviar Email</ListItemText>
                    </MenuItem>
                )}
            </Menu>
            <PagoManualModal open={pagoModalOpen} onClose={handleClosePagoModal} onSubmit={handleSubmitPagoModal} factura={selectedFactura} errorMessage={apiError} clearErrorMessage={() => setApiError(null)} />
        </Box>
    );
};

export default FacturacionPage;