/**
 * Utilidades para manejo de cookies
 * Estas funciones proporcionan una interfaz segura para trabajar con cookies
 * tanto en el lado del cliente como del servidor (SSR)
 */

/**
 * Establece una cookie con los parámetros especificados
 * @param {string} name - Nombre de la cookie
 * @param {string} value - Valor de la cookie
 * @param {Object} options - Opciones de la cookie
 * @param {number} options.days - Días hasta la expiración (por defecto 365)
 * @param {string} options.path - Ruta de la cookie (por defecto '/')
 * @param {string} options.sameSite - Política SameSite (por defecto 'Lax')
 * @param {boolean} options.secure - Si la cookie requiere HTTPS (por defecto false en desarrollo)
 */
export const setCookie = (name, value, options = {}) => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return;
  }

  const {
    days = 365,
    path = '/',
    sameSite = 'Lax',
    secure = process.env.NODE_ENV === 'production'
  } = options;

  let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
  
  // Establecer fecha de expiración
  if (days) {
    const date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    cookieString += `; expires=${date.toUTCString()}`;
  }
  
  // Agregar opciones
  cookieString += `; path=${path}`;
  cookieString += `; SameSite=${sameSite}`;
  
  if (secure) {
    cookieString += '; Secure';
  }

  document.cookie = cookieString;
};

// Cache para evitar múltiples accesos a document.cookie
let cookieCache = null;
let cacheTimestamp = 0;
const CACHE_DURATION = 10000; // 1 segundo

/**
 * Obtiene el valor de una cookie por su nombre con cache
 * @param {string} name - Nombre de la cookie
 * @returns {string|null} - Valor de la cookie o null si no existe
 */
export const getCookie = (name) => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return null;
  }

  const now = Date.now();
  
  // Usar cache si es reciente (para evitar múltiples accesos a document.cookie)
  if (cookieCache && (now - cacheTimestamp) < CACHE_DURATION) {
    return cookieCache[name] || null;
  }

  // Actualizar cache
  try {
    const cookies = {};
    const cookieArray = document.cookie.split(';');
    
    for (let cookie of cookieArray) {
      cookie = cookie.trim();
      const [cookieName, cookieValue] = cookie.split('=');
      if (cookieName && cookieValue) {
        cookies[decodeURIComponent(cookieName)] = decodeURIComponent(cookieValue);
      }
    }
    
    cookieCache = cookies;
    cacheTimestamp = now;
    
    return cookies[name] || null;
  } catch (error) {
    console.error('Error reading cookies:', error);
    return null;
  }
};

/**
 * Elimina una cookie estableciendo su fecha de expiración en el pasado
 * @param {string} name - Nombre de la cookie a eliminar
 * @param {string} path - Ruta de la cookie (por defecto '/')
 */
export const deleteCookie = (name, path = '/') => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return;
  }

  document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
};

/**
 * Verifica si las cookies están habilitadas en el navegador
 * @returns {boolean} - true si las cookies están habilitadas
 */
export const areCookiesEnabled = () => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return false;
  }

  try {
    const testCookie = '__cookie_test__';
    setCookie(testCookie, 'test', { days: null });
    const result = getCookie(testCookie) === 'test';
    deleteCookie(testCookie);
    return result;
  } catch (error) {
    return false;
  }
};

/**
 * Obtiene todas las cookies como un objeto
 * @returns {Object} - Objeto con todas las cookies
 */
export const getAllCookies = () => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return {};
  }

  const cookies = {};
  const cookieArray = document.cookie.split(';');
  
  for (let cookie of cookieArray) {
    cookie = cookie.trim();
    const [name, value] = cookie.split('=');
    if (name && value) {
      cookies[decodeURIComponent(name)] = decodeURIComponent(value);
    }
  }
  
  return cookies;
};

/**
 * Funciones específicas para el consentimiento de cookies de Sempreg
 */

// Nombre de la cookie para el consentimiento
const CONSENT_COOKIE_NAME = 'sempreg-cookie-consent';

/**
 * Guarda el consentimiento de cookies
 * @param {boolean} accepted - Si el usuario aceptó las cookies
 * @param {string} type - Tipo de consentimiento ('essential', 'analytics', 'all')
 */
export const saveCookieConsent = (accepted, type = 'all') => {
  const consentData = {
    accepted,
    type,
    timestamp: new Date().toISOString(),
    version: '1.0' // Para futuras actualizaciones de política
  };

  setCookie(CONSENT_COOKIE_NAME, JSON.stringify(consentData), {
    days: 365, // 1 año de duración
    path: '/',
    sameSite: 'Lax'
  });

  // Limpiar cache después de actualizar
  consentCache = consentData;
  consentCacheTimestamp = Date.now();
  cookieCache = null; // Forzar actualización del cache de cookies general
};

// Cache para el consentimiento de cookies
let consentCache = null;
let consentCacheTimestamp = 0;

/**
 * Obtiene el consentimiento de cookies guardado con cache
 * @returns {Object|null} - Datos del consentimiento o null si no existe
 */
export const getCookieConsent = () => {
  const now = Date.now();
  
  // Usar cache si es reciente
  if (consentCache && (now - consentCacheTimestamp) < CACHE_DURATION) {
    return consentCache;
  }

  try {
    const consentString = getCookie(CONSENT_COOKIE_NAME);
    if (consentString) {
      consentCache = JSON.parse(consentString);
      consentCacheTimestamp = now;
      return consentCache;
    } else {
      consentCache = null;
      consentCacheTimestamp = now;
      return null;
    }
  } catch (error) {
    console.error('Error parsing cookie consent:', error);
    consentCache = null;
    consentCacheTimestamp = now;
    return null;
  }
};

/**
 * Elimina el consentimiento de cookies (para resetear)
 */
export const clearCookieConsent = () => {
  deleteCookie(CONSENT_COOKIE_NAME);
};

/**
 * Verifica si el usuario ha dado consentimiento para un tipo específico
 * @param {string} type - Tipo de cookie ('essential', 'analytics', 'all')
 * @returns {boolean} - true si tiene consentimiento
 */
export const hasConsentFor = (type = 'essential') => {
  const consent = getCookieConsent();
  
  if (!consent || !consent.accepted) {
    return false;
  }

  // Si aceptó todo, tiene consentimiento para cualquier tipo
  if (consent.type === 'all') {
    return true;
  }

  // Las cookies esenciales siempre están permitidas
  if (type === 'essential') {
    return true;
  }

  // Para otros tipos, verificar específicamente
  return consent.type === type;
};

// Flag para evitar múltiples migraciones en la misma sesión
let migrationAttempted = false;

/**
 * Migra las preferencias de cookies desde localStorage a cookies reales
 * Esta función es útil para usuarios existentes que ya tenían preferencias guardadas
 * Solo se ejecuta una vez por sesión para evitar consumo excesivo de recursos
 */
export const migrateCookiePreferences = () => {
  // Verificar si estamos en el navegador
  if (typeof window === 'undefined') {
    return false;
  }

  // Si ya se intentó la migración en esta sesión, no volver a intentar
  if (migrationAttempted) {
    return false;
  }

  migrationAttempted = true;

  try {
    // Verificar si ya hay cookies de consentimiento
    const existingConsent = getCookieConsent();
    if (existingConsent) {
      // Ya hay cookies, no es necesario migrar
      return false;
    }

    // Buscar preferencias existentes en localStorage
    const oldConsent = localStorage.getItem('sempreg-cookie-consent');
    
    if (oldConsent) {
      // Si hay preferencias en localStorage pero no en cookies, migrar
      const consentData = JSON.parse(oldConsent);
      
      // Determinar el tipo de consentimiento
      let consentType = 'essential';
      if (consentData.accepted) {
        if (consentData.settings?.analytics) {
          consentType = 'analytics';
        }
        if (consentData.settings?.marketing) {
          consentType = 'all';
        }
      }
      
      // Guardar en cookies
      saveCookieConsent(consentData.accepted, consentType);
      
      // Limpiar localStorage después de la migración exitosa
      localStorage.removeItem('sempreg-cookie-consent');
      
            return true;
    }
    
    return false;
  } catch (error) {
    console.error('Error migrating cookie preferences:', error);
    return false;
  }
};
