import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { trackEvent, trackPageView, getStoredAnalytics } from '../utils/analytics';
import { protectedApiRequest, API_CONFIG } from '../config/api';
import { getCookieConsent as getCookieConsentFromCookies } from '../utils/cookies';

// Cache para evitar recálculos innecesarios
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutos
const REFRESH_INTERVAL = 30 * 1000; // 30 segundos para auto-refresh

const useAnalytics = () => {
  const [analytics, setAnalytics] = useState({
    totalVisits: 0,
    uniqueVisitors: 0,
    pageViews: 0,
    sessions: 0,
    averageSessionDuration: 0,
    bounceRate: 0,
    todayVisits: 0,
    thisWeekVisits: 0,
    thisMonthVisits: 0, // Nueva métrica
    topPages: [],
    topReferrers: [],
    userAgents: [],
    referrers: [],
    events: [],
    browserStats: [],
    deviceStats: [], // Nueva métrica
    visitHistory: [],
    cookieConsent: null,
    loading: true,
    error: null,
    lastUpdated: null, // Timestamp de última actualización
    growthRate: null, // Tasa de crecimiento
    peakHours: [], // Horas pico de tráfico
    geographicData: [] // Datos geográficos si están disponibles
  });

  const [isAdmin, setIsAdmin] = useState(false);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const cacheRef = useRef({ data: null, timestamp: null });
  const abortControllerRef = useRef(null);
  const refreshIntervalRef = useRef(null);

  const accessToken = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null;

  // Función mejorada para procesamiento de datos
  const processVisitData = useCallback((visits) => {
    if (!visits || !Array.isArray(visits)) return {};

    const now = new Date();
    const today = now.toISOString().split('T')[0];
    const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
    const monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
    
    // Usar Map para mejor performance
    const uniqueVisitorsByDay = new Map();
    const pageVisitsMap = new Map();
    const referrerVisitsMap = new Map();
    const browserMap = new Map();
    const deviceMap = new Map();
    const hourlyVisits = new Array(24).fill(0);
    
    let todayUniqueCount = 0;
    let weekUniqueCount = 0;
    let monthUniqueCount = 0;

    visits.forEach(visit => {
      const visitDate = visit.date || new Date(visit.timestamp).toISOString().split('T')[0];
      const sessionKey = visit.sessionId || visit.ip || 'unknown';
      const dayKey = `${sessionKey}-${visitDate}`;
      
      // Conteo de visitantes únicos por día
      if (!uniqueVisitorsByDay.has(dayKey)) {
        uniqueVisitorsByDay.set(dayKey, true);
        
        const visitDateObj = new Date(visitDate);
        if (visitDate === today) todayUniqueCount++;
        if (visitDateObj >= weekAgo) weekUniqueCount++;
        if (visitDateObj >= monthAgo) monthUniqueCount++;
      }
      
      // Páginas más visitadas
      const path = visit.path || '/';
      pageVisitsMap.set(path, (pageVisitsMap.get(path) || 0) + 1);
      
      // Referrers
      if (visit.referrer && !visit.referrer.includes('localhost')) {
        referrerVisitsMap.set(visit.referrer, (referrerVisitsMap.get(visit.referrer) || 0) + 1);
      }
      
      // Estadísticas de navegador
      const browser = detectBrowser(visit.userAgent);
      if (browser) {
        browserMap.set(browser, (browserMap.get(browser) || 0) + 1);
      }
      
      // Estadísticas de dispositivo
      const device = detectDevice(visit.userAgent);
      if (device) {
        deviceMap.set(device, (deviceMap.get(device) || 0) + 1);
      }
      
      // Horas pico
      if (visit.timestamp) {
        const hour = new Date(visit.timestamp).getHours();
        hourlyVisits[hour]++;
      }
    });

    // Convertir Maps a arrays ordenados
    const topPages = Array.from(pageVisitsMap.entries())
      .map(([page, views]) => ({ page, views }))
      .sort((a, b) => b.views - a.views)
      .slice(0, 10);

    const topReferrers = Array.from(referrerVisitsMap.entries())
      .map(([referrer, visits]) => ({ referrer, visits }))
      .sort((a, b) => b.visits - a.visits)
      .slice(0, 10);

    const browserStats = Array.from(browserMap.entries())
      .map(([browser, count]) => ({
        browser,
        count,
        percentage: ((count / visits.length) * 100).toFixed(1)
      }))
      .sort((a, b) => b.count - a.count);

    const deviceStats = Array.from(deviceMap.entries())
      .map(([device, count]) => ({
        device,
        count,
        percentage: ((count / visits.length) * 100).toFixed(1)
      }))
      .sort((a, b) => b.count - a.count);

    // Identificar horas pico
    const peakHours = hourlyVisits
      .map((count, hour) => ({ hour, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 5)
      .map(item => ({
        hour: `${item.hour}:00`,
        visits: item.count
      }));

    return {
      totalVisits: uniqueVisitorsByDay.size,
      uniqueVisitors: new Set(visits.map(v => v.sessionId || v.ip)).size,
      pageViews: visits.length,
      todayVisits: todayUniqueCount,
      thisWeekVisits: weekUniqueCount,
      thisMonthVisits: monthUniqueCount,
      topPages,
      topReferrers,
      browserStats,
      deviceStats,
      peakHours,
      visitHistory: visits.slice(-50).reverse()
    };
  }, []);

  // Detectar navegador mejorado
  const detectBrowser = (userAgent) => {
  if (!userAgent) return 'Desconocido';
  
  // Edge debe ser detectado primero
  if (userAgent.includes('Edg/')) return 'Edge';  // Edge moderno usa "Edg/"
  if (userAgent.includes('Edge')) return 'Edge';  // Edge antiguo
  if (userAgent.includes('Chrome')) return 'Chrome';
  if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) return 'Safari';
  if (userAgent.includes('Firefox')) return 'Firefox';
  if (userAgent.includes('Opera') || userAgent.includes('OPR')) return 'Opera';
  
  return 'Otro';
};

  // Detectar tipo de dispositivo
  const detectDevice = useCallback((userAgent) => {
    if (!userAgent) return 'Desconocido';
    
    if (/Mobile|Android|iPhone/i.test(userAgent)) return 'Móvil';
    if (/Tablet|iPad/i.test(userAgent)) return 'Tablet';
    return 'Desktop';
  }, []);

  // Calcular tasa de crecimiento
  const calculateGrowthRate = useCallback((current, previous) => {
    if (!previous || previous === 0) return 0;
    return ((current - previous) / previous * 100).toFixed(1);
  }, []);

  // Función principal de carga con caché
  const loadAnalytics = useCallback(async () => {
  try {
    // Inicializar estado de carga
    setAnalytics(prev => ({ 
      ...prev, 
      loading: true, 
      error: null 
    }));

    // Obtener datos de consentimiento de cookies
    const cookieConsentData = getCookieConsentFromCookies();
    
    // Estructura base de datos de analytics
    let analyticsData = {
      cookieConsent: cookieConsentData,
      totalVisits: 0,
      uniqueVisitors: 0,
      pageViews: 0,
      todayVisits: 0,
      thisWeekVisits: 0,
      thisMonthVisits: 0,
      topPages: [],
      topReferrers: [],
      browserStats: [],
      deviceStats: [],
      visitHistory: [],
      bounceRate: 0,
      averageSessionDuration: '0m 0s',
      events: [],
      growth: {
        visits: 0,
        visitors: 0
      },
      lastUpdated: new Date().toISOString()
    };

    try {
      // Intentar cargar datos detallados
      const detailedMetrics = await protectedApiRequest(
        API_CONFIG.ENDPOINTS.DETAILED_METRICS,
        accessToken
      );

      if (detailedMetrics?.success) {
        // Procesar datos del backend de forma segura
        analyticsData = {
          ...analyticsData,
          // Métricas principales
          totalVisits: detailedMetrics.totalVisits || 0,
          uniqueVisitors: detailedMetrics.uniqueVisitors || 0,
          pageViews: detailedMetrics.totalResults || 0,
          
          // Métricas temporales
          todayVisits: detailedMetrics.todayVisits || 0,
          thisWeekVisits: detailedMetrics.thisWeekVisits || 0,
          thisMonthVisits: detailedMetrics.thisMonthVisits || 0,
          
          // Arrays de datos estructurados
          topPages: Array.isArray(detailedMetrics.topPages) 
            ? detailedMetrics.topPages 
            : [],
          topReferrers: Array.isArray(detailedMetrics.topReferrers) 
            ? detailedMetrics.topReferrers 
            : [],
          browserStats: Array.isArray(detailedMetrics.browserStats) 
            ? detailedMetrics.browserStats 
            : [],
          deviceStats: Array.isArray(detailedMetrics.deviceStats) 
            ? detailedMetrics.deviceStats 
            : [],
          visitHistory: Array.isArray(detailedMetrics.visits) 
            ? detailedMetrics.visits 
            : [],
          events: Array.isArray(detailedMetrics.events) 
            ? detailedMetrics.events 
            : [],
          
          // Métricas de comportamiento
          bounceRate: detailedMetrics.bounces || 0,
          averageSessionDuration: detailedMetrics.avgSessionDuration || '0m 0s',
          
          // Calcular crecimiento de forma segura
          growth: {
            visits: detailedMetrics.previousWeekVisits > 0 
              ? calculateGrowthRate(
                  detailedMetrics.thisWeekVisits || 0, 
                  detailedMetrics.previousWeekVisits
                )
              : 0,
            visitors: 0 // Implementar cuando tengas datos históricos
          }
        };

        // Actualizar caché con datos válidos
        cacheRef.current = {
          data: analyticsData,
          timestamp: Date.now()
        };
      }

    } catch (apiError) {
      console.warn('⚠️ Error cargando detailed metrics, intentando fallback:', apiError);
      
      // Fallback a métricas simples
      try {
        const simpleMetrics = await protectedApiRequest(
          API_CONFIG.ENDPOINTS.METRICS,
          accessToken
        );

        if (simpleMetrics?.success) {
          // Combinar datos simples con estructura base
          analyticsData = {
            ...analyticsData,
            ...simpleMetrics,
            // Asegurar que los arrays estén definidos
            topPages: Array.isArray(simpleMetrics.topPages) 
              ? simpleMetrics.topPages 
              : analyticsData.topPages,
            visitHistory: Array.isArray(simpleMetrics.visits) 
              ? simpleMetrics.visits 
              : analyticsData.visitHistory
          };
          
                  }

      } catch (fallbackError) {
        console.error('❌ Ambos endpoints fallaron:', fallbackError);
        
        // Último recurso: datos locales
        const localData = getStoredAnalytics();
        if (localData) {
          const processedData = processVisitData(localData.visits || []);
          
          analyticsData = {
            ...analyticsData,
            ...processedData,
            events: Array.isArray(localData.events) 
              ? localData.events 
              : analyticsData.events,
            error: 'Usando datos locales (API no disponible)'
          };
          
                  }
      }
    }

    // Actualizar estado con datos procesados
    setAnalytics(prev => ({
      ...prev,
      ...analyticsData,
      loading: false,
      error: null
    }));

  } catch (error) {
    console.error('❌ Error crítico loading analytics:', error);
    
    setAnalytics(prev => ({
      ...prev,
      loading: false,
      error: error.message || 'Error al cargar analytics'
    }));
  } finally {
    // Limpiar referencia del controlador
    abortControllerRef.current = null;
  }
}, [isAdmin, accessToken, calculateGrowthRate, processVisitData]);


  // Auto-refresh
  useEffect(() => {
    if (autoRefresh && isAdmin) {
      refreshIntervalRef.current = setInterval(() => {
        loadAnalytics(true);
      }, REFRESH_INTERVAL);

      return () => {
        if (refreshIntervalRef.current) {
          clearInterval(refreshIntervalRef.current);
        }
      };
    }
  }, [autoRefresh, isAdmin, loadAnalytics]);

  // Verificar estado de admin
  useEffect(() => {
    const checkAdminStatus = async () => {
      try {
        const userData = JSON.parse(localStorage.getItem('userData') || '{}');
        const isAdminUser = userData && accessToken && userData.typeuser === 2;
        setIsAdmin(isAdminUser);
        
        if (!isAdminUser) {
          setAnalytics(prev => ({ ...prev, loading: false }));
        }
      } catch (error) {
        console.error('Error checking admin status:', error);
        setIsAdmin(false);
        setAnalytics(prev => ({ 
          ...prev, 
          loading: false, 
          error: 'Error de autenticación' 
        }));
      }
    };

    checkAdminStatus();
  }, [accessToken]);

  // Cargar analytics cuando cambia el estado de admin
  useEffect(() => {
    if (isAdmin) {
      loadAnalytics();
    }
  }, [isAdmin, loadAnalytics]);

  // Función mejorada para exportar con más formatos
  const exportMetrics = async (type = 'all', format = 'json') => {
    try {
      const exportData = prepareExportData(type);
      const filename = `analytics-${type}-${new Date().toISOString().split('T')[0]}`;

      switch (format) {
        case 'json':
          downloadJSON(exportData, filename);
          break;
        case 'csv':
          downloadCSV(exportData, filename, type);
          break;
        case 'excel':
          await downloadExcel(exportData, filename, type);
          break;
        default:
          throw new Error('Formato no soportado');
      }
    } catch (error) {
      console.error('Error exporting metrics:', error);
      throw error;
    }
  };

  // Preparar datos para exportación
  const prepareExportData = (type) => {
    switch (type) {
      case 'visits':
        return {
          summary: {
            totalVisits: analytics.totalVisits,
            uniqueVisitors: analytics.uniqueVisitors,
            todayVisits: analytics.todayVisits,
            thisWeekVisits: analytics.thisWeekVisits,
            thisMonthVisits: analytics.thisMonthVisits
          },
          topPages: analytics.topPages,
          topReferrers: analytics.topReferrers,
          visitHistory: analytics.visitHistory
        };
      case 'performance':
        return {
          browserStats: analytics.browserStats,
          deviceStats: analytics.deviceStats,
          peakHours: analytics.peakHours,
          bounceRate: analytics.bounceRate,
          avgSessionDuration: analytics.averageSessionDuration
        };
      case 'events':
        return { events: analytics.events };
      case 'all':
      default:
        return analytics;
    }
  };

  // Descargar como JSON
  const downloadJSON = (data, filename) => {
    const blob = new Blob([JSON.stringify(data, null, 2)], { 
      type: 'application/json' 
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${filename}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  // Descargar como CSV mejorado
  const downloadCSV = (data, filename, type) => {
    let csv = '';
    
    // Generar CSV según el tipo de datos
    if (type === 'visits' && data.topPages) {
      csv = 'Página,Visitas,Porcentaje\n';
      csv += data.topPages.map(page => 
        `"${page.page}",${page.views},${((page.views / analytics.totalVisits) * 100).toFixed(1)}%`
      ).join('\n');
    } else if (type === 'performance' && data.browserStats) {
      csv = 'Navegador,Cantidad,Porcentaje\n';
      csv += data.browserStats.map(browser => 
        `"${browser.browser}",${browser.count},${browser.percentage}%`
      ).join('\n');
      csv += '\n\nDispositivo,Cantidad,Porcentaje\n';
      csv += (data.deviceStats || []).map(device => 
        `"${device.device}",${device.count},${device.percentage}%`
      ).join('\n');
    } else {
      // CSV genérico
      csv = Object.entries(data)
        .filter(([key, value]) => typeof value !== 'object')
        .map(([key, value]) => `"${key}","${value}"`)
        .join('\n');
    }

    const blob = new Blob(['\uFEFF' + csv], { 
      type: 'text/csv;charset=utf-8;' 
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${filename}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  // Descargar como Excel (requiere biblioteca externa como SheetJS)
  const downloadExcel = async (data, filename, type) => {
    // Aquí podrías implementar la exportación a Excel usando SheetJS
        // Por ahora, fallback a CSV
    downloadCSV(data, filename, type);
  };

  // Limpiar analytics locales mejorado
  const clearLocalAnalytics = useCallback(() => {
    const keysToRemove = [
      'sempreg-analytics',
      'sempreg-custom-events',
      'sempreg-page-views',
      'sempreg-visits'
    ];

    keysToRemove.forEach(key => {
      try {
        localStorage.removeItem(key);
      } catch (error) {
        console.error(`Error removing ${key}:`, error);
      }
    });

    // Limpiar caché
    cacheRef.current = { data: null, timestamp: null };

    // Recargar si es admin
    if (isAdmin) {
      setTimeout(() => loadAnalytics(true), 500);
    }
  }, [isAdmin, loadAnalytics]);

  // Funciones de tracking mejoradas
  const trackCustomEvent = useCallback((eventName, eventData = {}) => {
    trackEvent(eventName, {
      ...eventData,
      timestamp: new Date().toISOString(),
      sessionId: sessionStorage.getItem('sessionId') || generateSessionId()
    });

    // Actualizar en tiempo real si es admin
    if (isAdmin && autoRefresh) {
      setTimeout(() => loadAnalytics(true), 1000);
    }
  }, [isAdmin, autoRefresh, loadAnalytics]);

  const trackPage = useCallback((page, title = '') => {
    trackPageView(page, title);

    if (isAdmin && autoRefresh) {
      setTimeout(() => loadAnalytics(true), 1000);
    }
  }, [isAdmin, autoRefresh, loadAnalytics]);

  // Generar ID de sesión
  const generateSessionId = () => {
    const id = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    sessionStorage.setItem('sessionId', id);
    return id;
  };

  // Funciones de utilidad memoizadas
  const summaryStats = useMemo(() => ({
    totalPageViews: analytics.pageViews,
    avgPagesPerVisit: analytics.totalVisits > 0 
      ? (analytics.pageViews / analytics.totalVisits).toFixed(1) 
      : 0,
    topBrowser: analytics.browserStats[0]?.browser || 'N/A',
    topDevice: analytics.deviceStats[0]?.device || 'N/A',
    peakHour: analytics.peakHours[0]?.hour || 'N/A',
    growthTrend: analytics.growthRate > 0 ? 'up' : analytics.growthRate < 0 ? 'down' : 'stable'
  }), [analytics]);

  return {
    // Datos principales
    analytics,
    metrics: analytics, // Alias para compatibilidad
    
    // Estado
    isAdmin,
    loading: analytics.loading,
    error: analytics.error,
    lastUpdated: analytics.lastUpdated,
    
    // Funciones principales
    refreshAnalytics: () => loadAnalytics(true),
    refreshMetrics: () => loadAnalytics(true), // Alias
    loadMetrics: loadAnalytics, // Alias
    clearLocalAnalytics,
    exportMetrics,
    
    // Tracking
    trackEvent: trackCustomEvent,
    trackPageView: trackPage,
    
    // Configuración
    autoRefresh,
    setAutoRefresh,
    
    // Estadísticas resumidas
    summaryStats
  };
};

export default useAnalytics;