import {hotjar} from "react-hotjar";
import Amplitude from 'amplitude-js';
import Pixel from 'react-facebook-pixel';
// @ts-ignore
import queryString from 'query-string';
import { enums } from '@optimizely/react-sdk';
import { localStorageService } from '../services/local_storage.service';

interface configType {
  REACT_APP_SHORT_ONBOARDING_URL: string;
  REACT_APP_OPTIMIZELY_API_KEY: string;
  REACT_APP_HOTJAR_ID: string;
  REACT_APP_HOTJAR_VERSION: string;
  REACT_FB_PIXEL_API_KEY: string;
  REACT_APP_AMPLITUDE_API_KEY: string;
  REACT_APP_VERSION: string;
}

const USER_ID_KEY = 'userID';

declare global {
  interface Window {
    optimizely: any;
    hj: any;
    fbq: any;
  }
}

export class AnalyticsBase {
  config: configType = {
    REACT_APP_SHORT_ONBOARDING_URL: '',
    REACT_APP_OPTIMIZELY_API_KEY: '',
    REACT_APP_HOTJAR_ID: '',
    REACT_APP_HOTJAR_VERSION: '',
    REACT_FB_PIXEL_API_KEY: '',
    REACT_APP_AMPLITUDE_API_KEY: '',
    REACT_APP_VERSION: '',
  }

  private useLog: boolean =
    window.location.origin.includes('signup-dev') && window.location.origin.includes('localhost');
  public amplitude = Amplitude.getInstance();
  //@ts-ignore
  public optimizely: any;
  //@ts-ignore
  get userId(): string {
    const value = localStorageService.getItem(USER_ID_KEY);
    if (value) return value;

    return (this.userId = Math.random().toString(36).substring(2, 15));
  }
  //@ts-ignore
  set userId(value) {
    localStorageService.setItem(USER_ID_KEY, value);
  }

  private setAmplitudeUserId(userId: any) {
    this.amplitude.setUserId(userId);
  }

  private initHotjar() {
      hotjar.initialize(
          Number(this.config.REACT_APP_HOTJAR_ID),
          Number(this.config.REACT_APP_HOTJAR_VERSION)
      );
    setTimeout(() => {
      if (window.hj) {
        window.hj('identify', this.userId, {
          'Web User ID': this.userId,
          'user_id': this.userId,
        });
      }
    }, 500);
  }

  private initFbx() {
    Pixel.init(this.config.REACT_FB_PIXEL_API_KEY as string);
    window.fbq('init', this.config.REACT_FB_PIXEL_API_KEY as string, {
      extern_id: localStorageService.getItem('userID'),
    });
  }

  private initAmplitudeAndOptimizely() {
    this.amplitude.init(
      this.config.REACT_APP_AMPLITUDE_API_KEY as string,
      this.userId,
      {
        includeUtm: true,
        includeGclid: true,
        includeReferrer: true,
        userId: this.userId,
      },
      async () => {
        const { ACTIVATE } = enums.NOTIFICATION_TYPES;
        const {
          screen: { width, height },
        } = window;

        this.setAmplitudeUserId(this.userId);
        this.amplitude.setUserProperties({
          ReleaseVersion: this.config.REACT_APP_VERSION,
        });
        this.amplitude.setUserProperties({ UserMurchantAccount: 'UK' });
        this.amplitude.setUserProperties({ UserScreenWidth: width });
        this.amplitude.setUserProperties({ UserScreenHeight: height });
        this.amplitude.setUserProperties({ OnboardingVersion: 2 });
        this.amplitude.setUserProperties({
          UserScreenSize: `${width} x ${height}`,
        });

        await this.optimizely?.onReady();

        this.optimizely.notificationCenter.addNotificationListener(ACTIVATE, (event: any = {}) => {
          if (localStorageService.getItem(event.experiment?.id)) {
            return;
          }

          const parsed = queryString.parse(window.location.search);

          setTimeout(() => {
            if (window.hj) {
              window.hj('lf', this.userId, {
                experimentId: event.experiment?.id,
                experimentName: event.experiment?.key,
                variationId: event.variation?.id,
                variationName: event.variation?.key,
                country: localStorageService.getItem('utm_country'),
                utm_source: parsed.utm_source,
              });
            }
          }, 500);

          this.baseEvent('OptimizelyExperimentViewed', {
            experimentId: event.experiment?.id,
            experimentName: event.experiment?.key,
            variationId: event.variation?.id,
            variationName: event.variation?.key,
          });

          localStorageService.setItem(event.experiment?.id, 'true');
        });
      }
    );
  }

  public baseEvent(name: string, params = {}) {
    const data = this.parseEventData(params);
    this.logEvent(name, data);
    try {
      this.amplitude.logEvent(name, data);

      Pixel.trackCustom(name, data);
    } catch (e) {
      console.log(e);
    }

    return { data };
  }

  private parseEventData(params: any) {
    return Object.entries(params).reduce((d, [key, value]) => {
      if (!value) return d;

      let _value = value;

      switch (typeof _value) {
        case 'object': {
          _value = JSON.stringify(_value);
          break;
        }
      }

      return { ...d, [key]: _value };
    }, {});
  }
  private logEvent(name: string, data = {}) {
    if (this.useLog) return;

    console.log(' ');
    console.log(
      `%c[FIRED CLIENT EVENT] ${name}`,
      'color:orange; font-size: 16px; text-transform: capitalize;'
    );
    console.table({
      'EVENT NAME': name,
      'EVENT DATA': Object.keys(data).length ? JSON.stringify(data) : '-',
    });
    console.log(' ');
  }

  constructor({optymizelyInstance, ...config} : configType & { optymizelyInstance: any }) {
    this.optimizely = optymizelyInstance
    this.config = config
    this.initAmplitudeAndOptimizely();
    this.initFbx();
    this.initHotjar()
  }
}