import React, { useState, useEffect } from 'react';
import { Dropdown } from 'react-bootstrap';
import SimpleBar from 'simplebar-react';
import { usePage } from '@inertiajs/react';
import ProcessHistoryModal from './ProcessHistoryModal';
import { initializeEcho, hasEchoCredentials } from '../../bootstrap';

function getProcessTypeLabel(tipo: number): string {
    switch (tipo) {
        case 1:
            return 'Integración de Contratos';
        case 2:
            return 'OK Comercial';
        case 3:
            return 'Carga Global Audax';
        case 4:
            return 'Documentación comercializadora';
        default:
            return 'Proceso';
    }
}

interface AudaxErrorFila {
    fila: number;
    errores: string[];
    campos?: string[];
    /** Presente en payload compacto de Pusher (Carga Global Audax). */
    estado?: string;
    error?: string;
}

interface ProcessNotification {
    numeroProceso: string;
    tipoProceso: number;
    timestamp: string;
    read: boolean;
    totalProcesados?: number | string;
    totalExitosos?: number | string;
    totalErrores?: number | string;
    /** Texto listo del backend (ej. "Se tramitaron 23 contrato(s)… de 25 CUPS"). */
    resumen?: string | null;
    /** Detalle por fila Excel (Carga Global Audax vía Echo). */
    erroresFilas?: AudaxErrorFila[];
}

const ProcessNotifications = () => {
    const { auth } = usePage().props as any;
    const [notifications, setNotifications] = useState<ProcessNotification[]>([]);
    const [isDropdownOpen, setIsDropdownOpen] = useState<boolean>(false);
    const [selectedProcess, setSelectedProcess] = useState<string | null>(null);
    const [selectedTipoProceso, setSelectedTipoProceso] = useState<number>(1);
    const [showModal, setShowModal] = useState<boolean>(false);

    useEffect(() => {
        // Solo suscribirse si el usuario está autenticado
        if (!auth?.user?.id) {
            if (import.meta.env.DEV) {
                console.warn('⚠️ Usuario no autenticado');
            }
            return;
        }

        // Verificar si hay credenciales de Pusher antes de intentar inicializar
        if (!hasEchoCredentials()) {
            if (import.meta.env.DEV) {
                console.warn('⚠️ No hay credenciales de Pusher configuradas');
            }
            return;
        }

        const userId = auth.user.id;
        if (import.meta.env.DEV) {
            console.log('👤 Usuario autenticado, ID:', userId);
        }

        // IMPORTANTE: Esperar después del login para asegurar que el token CSRF esté disponible
        // Las notificaciones se inicializan después del login usando una promesa
        const initializeNotifications = async () => {
            // Esperar un momento para asegurar que el token CSRF y la sesión estén disponibles
            await new Promise(resolve => setTimeout(resolve, 1500));
            
            // Inicializar Echo de forma lazy (solo cuando este componente se monta)
            // Esto evita que la conexión WebSocket bloquee la carga inicial de la página
            const echo = initializeEcho();

            if (!echo) {
                if (import.meta.env.DEV) {
                    console.error('❌ No se pudo inicializar Laravel Echo');
                }
                return;
            }

            if (import.meta.env.DEV) {
                console.log('✅ Echo disponible, configurando suscripción...');
                console.log('🔔 Intentando suscribirse al canal:', `private-user.${userId}`);
            }

            try {
            // Configurar listeners de conexión ANTES de suscribirse al canal
            // Escuchar cuando la conexión se establece
            echo.connector.pusher.connection.bind('connected', () => {
                if (import.meta.env.DEV) {
                    console.log('✅ Conexión WebSocket establecida con Pusher');
                }
            });

            // Escuchar errores de conexión
            echo.connector.pusher.connection.bind('error', (error: any) => {
                console.error('❌ Error de conexión WebSocket:', error);
                console.error('Detalles completos del error:', {
                    type: error.type,
                    error: error.error,
                    data: error.data,
                    message: error.message,
                    code: error.code
                });
                
                // Si es un error de autenticación (401), intentar actualizar el token CSRF
                if (error.error && (error.error.code === 401 || error.error.status === 401)) {
                    console.warn('⚠️ Error de autenticación detectado, actualizando token CSRF...');
                    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
                    if (csrfToken && window.axios) {
                        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken;
                    }
                }
            });

            // Escuchar cuando la conexión se desconecta
            echo.connector.pusher.connection.bind('disconnected', () => {
                if (import.meta.env.DEV) {
                    console.warn('⚠️ Conexión WebSocket desconectada');
                }
            });

            // Suscribirse al canal privado del usuario
            const channel = echo.private(`user.${userId}`);

            // Escuchar evento de suscripción exitosa
            channel.subscribed(() => {
                if (import.meta.env.DEV) {
                    console.log('✅ Suscrito exitosamente al canal:', `private-user.${userId}`);
                }
            });

            // Escuchar errores de suscripción
            channel.error((error: any) => {
                console.error('❌ Error al suscribirse al canal:', error);
                console.error('Detalles completos del error:', {
                    type: error.type,
                    error: error.error,
                    status: error.status,
                    message: error.message,
                    code: error.code,
                    data: error.data
                });
                
                // Si es un error 401 (no autorizado), puede ser un problema con el token CSRF
                if (error.status === 401 || (error.error && error.error.status === 401)) {
                    console.warn('⚠️ Error 401 detectado, puede ser un problema con el token CSRF');
                    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
                    console.warn('Token CSRF actual:', csrfToken ? `${csrfToken.substring(0, 10)}...` : 'NO DISPONIBLE');
                    
                    // Intentar actualizar el token y reintentar la suscripción
                    if (csrfToken && window.axios) {
                        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken;
                    }
                }
            });

            // Escuchar cuando la conexión se establece
            echo.connector.pusher.connection.bind('connected', () => {
                if (import.meta.env.DEV) {
                    console.log('✅ Conexión WebSocket establecida con Pusher');
                }
            });

            // Escuchar errores de conexión
            echo.connector.pusher.connection.bind('error', (error: any) => {
                console.error('❌ Error de conexión WebSocket:', error);
                console.error('Detalles completos del error:', {
                    type: error.type,
                    error: error.error,
                    data: error.data,
                    message: error.message,
                    code: error.code
                });
                
                // Si es un error de autenticación (401), intentar actualizar el token CSRF
                if (error.error && (error.error.code === 401 || error.error.status === 401)) {
                    console.warn('⚠️ Error de autenticación detectado, actualizando token CSRF...');
                    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
                    if (csrfToken && window.axios) {
                        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken;
                    }
                }
            });

            // Escuchar cuando la conexión se desconecta
            echo.connector.pusher.connection.bind('disconnected', () => {
                if (import.meta.env.DEV) {
                    console.warn('⚠️ Conexión WebSocket desconectada');
                }
            });

            channel.listen('.process.completed', (event: any) => {
                if (import.meta.env.DEV) {
                    console.log('🎉 Evento process.completed recibido:', event);
                }

                const resumen =
                    typeof event.resumen === 'string' && event.resumen.trim() !== ''
                        ? String(event.resumen).trim()
                        : null;

                const np = String(event.numeroProceso ?? '');
                const tp = Number(event.tipoProceso ?? 1);

                const erroresFilas: AudaxErrorFila[] | undefined = Array.isArray(event.erroresFilas)
                    ? event.erroresFilas
                          .filter((r: any) => r && (typeof r.fila === 'number' || typeof r.fila === 'string'))
                          .map((r: any) => {
                              const fila =
                                  typeof r.fila === 'string' ? parseInt(r.fila, 10) || 0 : Number(r.fila);
                              if (typeof r.error === 'string' && r.error.trim() !== '') {
                                  return {
                                      fila,
                                      errores: [r.error.trim()],
                                      estado: typeof r.estado === 'string' ? r.estado : 'error',
                                      error: r.error.trim(),
                                  } as AudaxErrorFila;
                              }
                              if (Array.isArray(r.errores)) {
                                  return {
                                      fila,
                                      errores: r.errores,
                                      campos: Array.isArray(r.campos) ? r.campos : undefined,
                                  } as AudaxErrorFila;
                              }
                              return null;
                          })
                          .filter((x): x is AudaxErrorFila => x !== null)
                    : undefined;

                const newNotification: ProcessNotification = {
                    numeroProceso: event.numeroProceso,
                    tipoProceso: event.tipoProceso,
                    timestamp: event.timestamp || new Date().toISOString(),
                    read: Boolean(np),
                    totalProcesados: event.totalProcesados,
                    totalExitosos: event.totalExitosos,
                    totalErrores: event.totalErrores,
                    resumen,
                    erroresFilas: erroresFilas && erroresFilas.length > 0 ? erroresFilas : undefined,
                };

                setNotifications((prev) => [newNotification, ...prev]);

                // Abrir el modal de detalle al instante (el usuario no tiene que pulsar la campana)
                if (np) {
                    setSelectedProcess(np);
                    setSelectedTipoProceso(Number.isFinite(tp) ? tp : 1);
                    setShowModal(true);
                    setIsDropdownOpen(false);
                }

                // Mostrar notificación del navegador si está permitido
                if ('Notification' in window && Notification.permission === 'granted') {
                    const title = 'Proceso completado';
                    const body =
                        resumen ||
                        `El proceso ${getProcessTypeLabel(Number(event.tipoProceso))} ha finalizado.`;
                    new Notification(title, {
                        body,
                        icon: '/images/logo-sm.png',
                    });
                }
            });

            // Solicitar permiso para notificaciones del navegador
            if ('Notification' in window && Notification.permission === 'default') {
                Notification.requestPermission();
            }

            if (import.meta.env.DEV) {
                console.log('🎧 Listener configurado para .process.completed');
            }

            // Cleanup al desmontar
            return () => {
                if (import.meta.env.DEV) {
                    console.log('🧹 Limpiando suscripción al canal');
                }
                channel.stopListening('.process.completed');
                echo.leave(`user.${userId}`);
            };
            } catch (error) {
                console.error('❌ Error al configurar Laravel Echo:', error);
            }
        };
        
        // Inicializar las notificaciones después del login
        initializeNotifications();
        
        // Cleanup al desmontar
        return () => {
            if (import.meta.env.DEV) {
                console.log('🧹 Limpiando componente de notificaciones');
            }
        };
    }, [auth?.user?.id]);

    const toggleDropdown = () => {
        setIsDropdownOpen(!isDropdownOpen);
    };

    const handleNotificationClick = (numeroProceso: string, tipoProceso: number) => {
        setSelectedProcess(numeroProceso);
        setSelectedTipoProceso(tipoProceso);
        setShowModal(true);
        setIsDropdownOpen(false);

        // Marcar como leída
        setNotifications((prev) =>
            prev.map((n) =>
                n.numeroProceso === numeroProceso ? { ...n, read: true } : n
            )
        );
    };

    const markAllAsRead = () => {
        setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
    };

    const clearNotifications = () => {
        setNotifications([]);
    };

    const unreadCount = notifications.filter((n) => !n.read).length;

    const getProcessTypeName = (tipo: number): string => getProcessTypeLabel(tipo);

    const formatTimestamp = (timestamp: string): string => {
        const date = new Date(timestamp);
        const now = new Date();
        const diffMs = now.getTime() - date.getTime();
        const diffMins = Math.floor(diffMs / 60000);

        if (diffMins < 1) return 'Justo ahora';
        if (diffMins < 60) return `Hace ${diffMins} min`;
        if (diffMins < 1440) return `Hace ${Math.floor(diffMins / 60)} h`;
        return `Hace ${Math.floor(diffMins / 1440)} días`;
    };

    const getNotificationStatus = (n: ProcessNotification) => {
        const resumenText = typeof n.resumen === 'string' && n.resumen.trim() !== '' ? n.resumen.trim() : '';

        const total = Number(n.totalProcesados);
        const exitosos = Number(n.totalExitosos);
        const errores = Number(n.totalErrores);

        if (resumenText) {
            const totalOk = Number.isFinite(total) && total > 0;
            if (totalOk && Number.isFinite(errores) && errores === total) {
                return {
                    bgClass: 'bg-danger-subtle',
                    textClass: 'text-danger',
                    icon: 'bx bx-x',
                    message: resumenText,
                };
            }
            if (totalOk && exitosos > 0 && exitosos < total) {
                return {
                    bgClass: 'bg-warning-subtle',
                    textClass: 'text-warning',
                    icon: 'bx bx-error',
                    message: resumenText,
                };
            }
            return {
                bgClass: 'bg-success-subtle',
                textClass: 'text-success',
                icon: 'bx bx-check',
                message: resumenText,
            };
        }

        // Si no hay datos detallados, mostrar éxito por defecto (comportamiento anterior)
        if (n.totalProcesados === undefined || n.totalProcesados === null) {
            return {
                bgClass: 'bg-success-subtle',
                textClass: 'text-success',
                icon: 'bx bx-check',
                message: 'Proceso completado exitosamente'
            };
        }

        // Si todos fallaron
        if (total > 0 && errores === total) {
            return {
                bgClass: 'bg-danger-subtle',
                textClass: 'text-danger',
                icon: 'bx bx-x',
                message: 'Error: Todos los registros fallaron'
            };
        }

        // Si hubo errores parciales
        if (exitosos > 0 && exitosos < total) {
            return {
                bgClass: 'bg-warning-subtle',
                textClass: 'text-warning',
                icon: 'bx bx-error',
                message: 'Procesado con algunos errores'
            };
        }

        // Éxito total
        return {
            bgClass: 'bg-success-subtle',
            textClass: 'text-success',
            icon: 'bx bx-check',
            message: 'Proceso completado exitosamente'
        };
    };

    return (
        <>
            <Dropdown
                show={isDropdownOpen}
                onClick={toggleDropdown}
                className="topbar-head-dropdown ms-1 header-item"
            >
                <Dropdown.Toggle
                    as="button"
                    type="button"
                    className="arrow-none btn btn-icon btn-topbar btn-ghost-secondary rounded-circle"
                >
                    <i className="bx bx-task fs-22"></i>
                    {unreadCount > 0 && (
                        <span className="position-absolute topbar-badge fs-10 translate-middle badge rounded-pill bg-success">
                            {unreadCount}
                            <span className="visually-hidden">procesos sin leer</span>
                        </span>
                    )}
                </Dropdown.Toggle>

                <Dropdown.Menu className="dropdown-menu-lg dropdown-menu-end p-0">
                    <div className="p-3 bg-success bg-pattern rounded-top">
                        <div className="row align-items-center">
                            <div className="col">
                                <h6 className="m-0 fs-16 fw-semibold text-white">
                                    Procesos
                                </h6>
                            </div>
                            <div className="col-auto">
                                {unreadCount > 0 && (
                                    <span className="badge bg-light-subtle fs-13 text-body">
                                        {unreadCount} Nuevos
                                    </span>
                                )}
                            </div>
                        </div>
                    </div>

                    {notifications.length === 0 ? (
                        <div className="text-center py-5">
                            <div className="avatar-sm mx-auto mb-3">
                                <span className="avatar-title bg-success-subtle text-success rounded-circle fs-22">
                                    <i className="bx bx-check-circle"></i>
                                </span>
                            </div>
                            <h6 className="fs-15 fw-semibold">No hay notificaciones</h6>
                            <p className="text-muted mb-0">
                                Los procesos completados aparecerán aquí
                            </p>
                        </div>
                    ) : (
                        <>
                            <SimpleBar style={{ maxHeight: '300px' }} className="py-2 px-2">
                                {notifications.map((notification, index) => {
                                    const status = getNotificationStatus(notification);
                                    return (
                                        <div
                                            key={index}
                                            className={`notification-item d-block dropdown-item position-relative ${
                                                !notification.read ? 'bg-light' : ''
                                            }`}
                                            style={{ cursor: 'pointer' }}
                                            onClick={() =>
                                                handleNotificationClick(notification.numeroProceso, notification.tipoProceso)
                                            }
                                        >
                                            <div className="d-flex">
                                                <div className="avatar-xs me-3 flex-shrink-0">
                                                    <span className={`avatar-title ${status.bgClass} ${status.textClass} rounded-circle fs-16`}>
                                                        <i className={status.icon}></i>
                                                    </span>
                                                </div>
                                                <div className="flex-grow-1">
                                                    <h6 className="mt-0 mb-1 fs-13 fw-semibold">
                                                        {getProcessTypeName(notification.tipoProceso)}
                                                    </h6>
                                                    <p className="mb-1 fs-12 text-muted">
                                                        {status.message}
                                                    </p>
                                                    <p className="mb-0 fs-11 fw-medium text-uppercase text-muted">
                                                        <i className="mdi mdi-clock-outline"></i>{' '}
                                                        {formatTimestamp(notification.timestamp)}
                                                    </p>
                                                </div>
                                                {!notification.read && (
                                                    <div className="px-1">
                                                        <span className="badge bg-success rounded-pill">
                                                            Nuevo
                                                        </span>
                                                    </div>
                                                )}
                                            </div>
                                        </div>
                                    );
                                })}
                            </SimpleBar>

                            <div className="p-2 border-top d-flex gap-2">
                                <button
                                    type="button"
                                    className="btn btn-sm btn-soft-success waves-effect w-50"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        markAllAsRead();
                                    }}
                                >
                                    Marcar como leídas
                                </button>
                                <button
                                    type="button"
                                    className="btn btn-sm btn-soft-danger waves-effect w-50"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        clearNotifications();
                                    }}
                                >
                                    Limpiar
                                </button>
                            </div>
                        </>
                    )}
                </Dropdown.Menu>
            </Dropdown>

            {selectedProcess && (
                <ProcessHistoryModal
                    show={showModal}
                    onHide={() => {
                        setShowModal(false);
                        setSelectedProcess(null);
                    }}
                    numeroProceso={selectedProcess}
                    tipoProceso={selectedTipoProceso}
                />
            )}
        </>
    );
};

export default ProcessNotifications;
