// services/activities/GatherClientSessionEnvironmentInfo.ts
import Activity from '../activities/Activity';
import Locator from '../services/Locator';
import { ANALYTICS_EVENTS } from '../services';

/**
 * Collects client environment details (browser, OS, device, platform)
 * and sends them as a single analytics event on session start.
 */
export default class GatherClientSessionEnvironmentInfo extends Activity {
  constructor() {
    super('GatherClientSessionEnvironmentInfo');
  }

  override async execute(): Promise<void> {
    const payload = this.collectEnvironmentInfo();
    Locator.analytics.track(ANALYTICS_EVENTS.SESSION_ENVIRONMENT_INFO, payload);
  }

  private collectEnvironmentInfo() {
    const ua = navigator.userAgent;
    const platform = this.detectPlatform(ua);
    const browser = this.detectBrowser(ua);
    const os = this.detectOS(ua);

    // Unified safe access to platform/device
    const uaData = (navigator as any).userAgentData;
    const device =
      uaData?.platform ??
      (uaData?.brands ? uaData.brands.map((b: any) => b.brand).join(', ') : undefined) ??
      'Unknown';

    return {
      browser: browser.name,
      browserVersion: browser.version,
      os: os.name,
      osVersion: os.version,
      device,
      platform,
    };
  }

  private detectPlatform(ua: string): 'desktop' | 'mobile' | 'tablet' {
    if (/ipad|tablet/i.test(ua)) return 'tablet';
    if (/mobile|iphone|android/i.test(ua)) return 'mobile';
    return 'desktop';
  }

  private detectBrowser(ua: string): { name: string; version: string } {
    if (/chrome|crios|crmo/i.test(ua))
      return { name: 'Chrome', version: this.extractVersion(ua, /(?:chrome|crios|crmo)\/([\d.]+)/i) };
    if (/firefox|fxios/i.test(ua))
      return { name: 'Firefox', version: this.extractVersion(ua, /(?:firefox|fxios)\/([\d.]+)/i) };
    if (/safari/i.test(ua) && !/chrome|crios/i.test(ua))
      return { name: 'Safari', version: this.extractVersion(ua, /version\/([\d.]+)/i) };
    return { name: 'Unknown', version: '0' };
  }

  private detectOS(ua: string): { name: string; version?: string } {
    if (/windows/i.test(ua)) return { name: 'Windows' };
    if (/android/i.test(ua)) return { name: 'Android' };
    if (/iphone|ipad|ipod/i.test(ua)) return { name: 'iOS' };
    if (/mac os/i.test(ua)) return { name: 'MacOS' };
    return { name: 'Unknown' };
  }

  private extractVersion(ua: string, regex: RegExp): string {
    const match = ua.match(regex);
    return match ? match[1] : '0';
  }
}
