/**
 * Metric Service для Яндекс Метрики и Google Analytics
 * 
 * Паттерн идентичен aura-webapp/src/services/metric/metricService.ts
 * 
 * Основные методы:
 * - setUserID: установить ID пользователя (для YM и GA)
 * - userParams: отправить параметры ПОСЕТИТЕЛЯ (sessionId, email, age, gender и т.д.)
 * - params: отправить параметры ВИЗИТА (AB тест варианты, источник и т.д.)
 * - reachGoal: достижение цели
 */

/**
 * Параметры посетителя (постоянные характеристики)
 * Передаются через window.ym(counterId, "userParams", {...})
 * 
 * Эти данные привязываются к ClientID и распространяются
 * на всю историю визитов пользователя
 */
interface IUserParams {
  UserID?: string | number;
  sessionId?: string;
  email?: string;
  gender?: string;
  age?: number;
  partnerGender?: string;
  partnerAge?: number;
}

/**
 * Параметры визита (временные данные о визите)
 * Передаются через window.ym(counterId, "params", {...})
 * 
 * Эти данные привязываются к конкретному визиту
 */
interface IVisitParams {
  email?: string;
  userId?: string | number;
  sessionId?: string;
  gaId?: string; // Google Analytics Measurement ID (e.g., G-XXXXXXXXXX)
  gaClientId?: string; // Google Analytics Client ID from _ga cookie
  ymClientId?: string; // Yandex Metrika Client ID from _ym_uid cookie
  funnelId?: string;
  selectedProductId?: string;
  [key: string]: string | number | boolean | undefined;
}

const checkIsAvailableYandexMetric = (): boolean => {
  if (typeof window === 'undefined') return false;
  
  if (typeof window.ym === 'undefined' || !window.__YM_COUNTER_ID__) {
    console.warn('[MetricService] Yandex Metrika not initialized');
    return false;
  }
  
  return true;
};

const checkIsAvailableGoogleAnalytics = (): boolean => {
  if (typeof window === 'undefined') return false;
  
  if (typeof window.gtag === 'undefined') {
    console.warn('[MetricService] Google Analytics not initialized');
    return false;
  }
  
  return true;
};

/**
 * Установить ID пользователя
 * Вызывается после авторизации
 */
const setUserID = (userId: string | number): void => {
  console.log('[MetricService] setUserID:', userId);
  
  // Yandex Metrika
  if (checkIsAvailableYandexMetric() && window.__YM_COUNTER_ID__) {
    window.ym(window.__YM_COUNTER_ID__, 'setUserID', String(userId));
    console.log('✅ [Yandex Metrika] setUserID:', userId);
  }
  
  // Google Analytics
  if (checkIsAvailableGoogleAnalytics()) {
    window.gtag('config', 'GA_MEASUREMENT_ID', {
      user_id: String(userId),
    });
    console.log('✅ [Google Analytics] setUserID:', userId);
  }
};

/**
 * Отправить параметры ПОСЕТИТЕЛЯ
 * 
 * Эти параметры привязываются к ClientID и распространяются
 * на всю историю визитов пользователя
 * 
 * Примеры:
 * - userParams({ sessionId: 'abc123' }) - при создании сессии
 * - userParams({ email: 'user@example.com', UserID: 123 }) - после авторизации
 * - userParams({ gender: 'female', age: 25 }) - после ввода данных
 */
const userParams = (parameters: Partial<IUserParams>): void => {
  console.log('[MetricService] userParams:', parameters);
  
  // Yandex Metrika
  if (checkIsAvailableYandexMetric() && window.__YM_COUNTER_ID__) {
    window.ym(window.__YM_COUNTER_ID__, 'userParams', parameters);
    console.log('✅ [Yandex Metrika] userParams sent:', parameters);
  }
  
  // Google Analytics
  if (checkIsAvailableGoogleAnalytics()) {
    window.gtag('config', 'GA_MEASUREMENT_ID', {
      send_page_view: false,
      ...parameters,
    });
    console.log('✅ [Google Analytics] config sent:', parameters);
  }
};

/**
 * Отправить параметры ВИЗИТА
 * 
 * Эти параметры привязываются к конкретному визиту
 * 
 * Примеры:
 * - params({ ab_test_button: 'v1' }) - AB тест вариант
 * - params({ source: 'facebook' }) - источник трафика
 */
const params = (parameters: IVisitParams): void => {
  console.log('[MetricService] params:', parameters);
  
  // Yandex Metrika
  if (checkIsAvailableYandexMetric() && window.__YM_COUNTER_ID__) {
    window.ym(window.__YM_COUNTER_ID__, 'params', parameters);
    console.log('✅ [Yandex Metrika] params sent:', parameters);
  }
};

/**
 * Достижение цели
 */
const reachGoal = (goal: string, params?: Record<string, unknown>): void => {
  console.log('[MetricService] reachGoal:', goal, params);
  
  // Yandex Metrika
  if (checkIsAvailableYandexMetric() && window.__YM_COUNTER_ID__) {
    window.ym(window.__YM_COUNTER_ID__, 'reachGoal', goal, params);
    console.log('✅ [Yandex Metrika] reachGoal sent:', goal);
  }
  
  // Google Analytics
  if (checkIsAvailableGoogleAnalytics()) {
    window.gtag('event', goal, params);
    console.log('✅ [Google Analytics] event sent:', goal);
  }
};

/**
 * Отправляет данные из sessionData в userParams
 * Использует те же данные что собираются через registrationFieldKey
 * Дополнительно вычисляет age из birthdate полей
 */
const sendSessionDataToMetrics = (sessionData: Record<string, unknown>): void => {
  if (Object.keys(sessionData).length === 0) return;
  
  const metrics: Record<string, string | number> = {};
  
  // Рекурсивная функция для извлечения всех полей
  const extractFields = (obj: Record<string, unknown>, prefix = ''): void => {
    Object.entries(obj).forEach(([key, value]) => {
      const fieldKey = prefix ? `${prefix}.${key}` : key;
      
      if (value && typeof value === 'object' && !Array.isArray(value)) {
        // Рекурсивно обрабатываем вложенные объекты
        extractFields(value as Record<string, unknown>, fieldKey);
      } else if (typeof value === 'string' || typeof value === 'number') {
        // Для birthdate полей вычисляем age
        if (key === 'birthdate' && typeof value === 'string') {
          const age = calculateAge(value);
          if (age) {
            const ageKey = prefix ? `${prefix.split('.').pop()}Age` : 'age';
            metrics[ageKey] = age;
          }
        }
        // Добавляем все остальные поля как есть
        metrics[key] = value;
      }
    });
  };
  
  extractFields(sessionData);
  
  // Отправляем только если есть данные
  if (Object.keys(metrics).length > 0) {
    userParams(metrics as Partial<IUserParams>);
  }
};

/**
 * Вычисляет возраст из даты рождения
 * @param birthdate - дата в формате YYYY-MM-DD HH:mm
 */
const calculateAge = (birthdate: string): number | undefined => {
  try {
    const date = new Date(birthdate);
    if (isNaN(date.getTime())) return undefined;
    
    const today = new Date();
    let age = today.getFullYear() - date.getFullYear();
    const monthDiff = today.getMonth() - date.getMonth();
    
    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < date.getDate())) {
      age--;
    }
    
    return age > 0 && age < 150 ? age : undefined;
  } catch {
    return undefined;
  }
};

/**
 * Извлекает Google Analytics Client ID из куки _ga
 * Формат куки: GA1.1.XXXXXXXXXX.YYYYYYYYYY
 * Возвращает: XXXXXXXXXX.YYYYYYYYYY
 */
const getGoogleAnalyticsClientId = (): string | undefined => {
  if (typeof window === 'undefined' || typeof document === 'undefined') {
    return undefined;
  }
  
  try {
    const gaCookie = document.cookie
      .split('; ')
      .find(row => row.startsWith('_ga='));
    
    if (!gaCookie) return undefined;
    
    const cookieValue = gaCookie.split('=')[1];
    // Формат: GA1.1.XXXXXXXXXX.YYYYYYYYYY
    // Извлекаем последние две части
    const parts = cookieValue.split('.');
    if (parts.length >= 3) {
      return parts.slice(2).join('.');
    }
    
    return undefined;
  } catch {
    return undefined;
  }
};

/**
 * Извлекает Yandex Metrika Client ID из куки _ym_uid
 * Возвращает значение напрямую
 */
const getYandexMetrikaClientId = (): string | undefined => {
  if (typeof window === 'undefined' || typeof document === 'undefined') {
    return undefined;
  }
  
  try {
    const ymCookie = document.cookie
      .split('; ')
      .find(row => row.startsWith('_ym_uid='));
    
    if (!ymCookie) return undefined;
    
    return ymCookie.split('=')[1];
  } catch {
    return undefined;
  }
};

/**
 * Отправляет контекст визита в Яндекс Метрику
 * Это параметры визита (params), а не посетителя (userParams)
 * 
 * Вызывается при:
 * - Создании сессии (sessionId, funnelId, gaId, gaClientId)
 * - Авторизации (email, userId)
 * - Выборе продукта на экране оплаты (selectedProductId)
 */
const sendVisitContext = (context: Partial<IVisitParams>): void => {
  // Автоматически добавляем GA Client ID и YM Client ID если их нет в контексте
  const gaClientId = context.gaClientId || getGoogleAnalyticsClientId();
  const ymClientId = context.ymClientId || getYandexMetrikaClientId();
  
  const contextWithClientIds = {
    ...context,
    ...(gaClientId ? { gaClientId } : {}),
    ...(ymClientId ? { ymClientId } : {}),
  };
  
  console.log('[MetricService] sendVisitContext:', contextWithClientIds);
  
  // Фильтруем undefined значения
  const filteredContext = Object.entries(contextWithClientIds).reduce((acc, [key, value]) => {
    if (value !== undefined) {
      acc[key] = value;
    }
    return acc;
  }, {} as IVisitParams);
  
  if (Object.keys(filteredContext).length > 0) {
    params(filteredContext);
  }
};

export const metricService = {
  setUserID,
  userParams,
  params,
  reachGoal,
  sendSessionDataToMetrics,
  sendVisitContext,
};
