/// <reference path="./definition.d.ts" />

import * as React from 'react';
import { getDefaultValue } from '../util/date';
import assign from 'object-assign';

class EventTracking extends React.Component<TspComponentEventTrackingProps, any> {
  constructor(props: TspComponentEventTrackingProps, state: any) {
    super(props, state);

    this.onUnload = this.onUnload.bind(this);
  }

  public static defaultProps: TspComponentEventTrackingProps = {
    options: []
  };
  /**
   * 父页面记录
   */
  public static parentPage: string[] = [];
  public observers: TspComponentEventTrackingObservers = [];
  public mutationObserver: MutationObserver;
  /**
   * 行为数据统计
   */
  public data: any = {};
  /**
   * 当前时间
   */
  public time: number = new Date().getTime();
  /**
   * 是否被销毁
   */
  public isDestory: boolean = false;
  /**
   * 配置观察选项:
   */
  public observeConfig: any = { attributes: true, attributeOldValue: true, attributeFilter: ['data-trackid'] };
  /**
   * 请求发送的参数
   */
  public sendParams: any = [];

  public shouldComponentUpdate(): boolean {
    return false;
  }

  public componentDidMount(): void {
    // Firefox和Chrome早期版本中带有前缀
    this.mutationObserver = window['MutationObserver'] || window['WebKitMutationObserver'];
    if (this.mutationObserver) {
      const length = this.props.options.length;

      for (let i = 0; i < length; i++) {
        const target = document.getElementById(this.props.options[i].id);
        if (target && this.props.options[i].enable) {
          const field = this.props.options[i].id;
          this.data[field] = [];
          // 创建观察者对象
          const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
              if (this.props.options[i].trigger !== 'destroy') {
                this.onMutation(field, target, this.props.options[i]);
              }
            });
          });
          // 传入目标节点和观察选项
          observer.observe(target, this.observeConfig);
          this.observers.push({
            observer,
            field
          });
        }
      }
    }

    window.addEventListener('unload', this.onUnload, false);
  }

  public componentWillReceiveProps(nextProps: TspComponentEventTrackingProps): void {
    if (this.mutationObserver) {
      const length = nextProps.options.length;

      for (let i = 0; i < length; i++) {
        const target = document.getElementById(nextProps.options[i].id);
        const field = nextProps.options[i].id;
        if (target && this.props.options[i].enable === false && nextProps.options[i].enable === true) {
          this.data[field] = [];
          // 创建观察者对象
          const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
              if (mutation.oldValue && nextProps.options[i].trigger !== 'destroy') {
                this.onMutation(field, target, nextProps.options[i]);
              }
            });
          });
          // 传入目标节点和观察选项
          observer.observe(target, this.observeConfig);
          this.observers.push({
            observer,
            field
          });
        }
      }
    }
  }

  public componentWillUnmount(): void {
    this.onDestroy();
    window.removeEventListener('unload', this.onUnload);
  }

  /**
   * 添加数据
   */
  public dataPush(params: TspComponentEventTrackingDataPushParams, isDestory: boolean): void {
    const field = params.id;
    const dataset = params.target.dataset;
    const datasetTime = parseInt(dataset.time);
    const dataLength = this.data[field].length;
    const pageHistory = EventTracking.parentPage;
    let parentPage;
    let stopSeconds;

    if (params.trigger === 'once') {
      parentPage = pageHistory[pageHistory.length - 2];
    } else {
      parentPage = pageHistory[pageHistory.length - 1];
    }

    if (params.time) {
      if (params.trigger === 'once') {
        stopSeconds = params.time - this.time;
      } else {
        stopSeconds = params.time - datasetTime;
      }
    } else {
      stopSeconds = dataLength ? datasetTime - new Date(this.data[field][dataLength - 1].createTime).getTime() : datasetTime - this.time;
    }

    this.data[field].push({
      //id: this.isDestory ? dataset.trackid : dataset.prevtrackid,
      buildingProjectId: this.props.buildingProjectId,
      houseId: this.props.houseId,
      topModule: this.props.topModule,
      secondaryModule: this.props.secondaryModule,
      actionName: params.actionName,
      behaviorName: params.behaviorName,
      mainType: params.mainType,
      subType: params.subType,
      createTime: getDefaultValue(datasetTime, 'string'),
      detailedData: this.getDetailedData(params.type, dataset),
      parentPage,
      //nowPage: pageHistory[pageHistory.length - 1],
      //pageHistory,
      stopSeconds
    });
  }

  /**
   * 销毁时触发
   */
  public onDestroy(noRequest?: boolean): void {
    const length = this.props.options.length;
    const time = new Date().getTime();
    this.isDestory = true;
    console.log('销毁时：');
    for (let i = 0; i < length; i++) {
      const target = document.getElementById(this.props.options[i].id);
      const field = this.props.options[i].id;
      const destroyTrigger = this.props.options[i].destroyTrigger;
      const trigger = this.props.options[i].trigger;
      if ((destroyTrigger || trigger  === 'once') && target) {
        if (!this.data[field]) {
          this.data[field] = [];
        }
        if ((!this.data[field].length && trigger === 'once') || destroyTrigger) {
          this.dataPush({
            id: field,
            target,
            time,
            type: this.props.options[i].type,
            actionName: this.props.options[i].actionName,
            behaviorName: this.props.options[i].behaviorName,
            mainType: this.props.options[i].mainType,
            subType: this.props.options[i].subType,
            trigger: this.props.options[i].trigger
          }, true);
        }
      }
      if (this.observers[i]) {
        this.observers[i].observer.disconnect();
      }
    }

    if (!noRequest) {
      console.log(this.data)
      this.props.request(assign({}, this.props.api, { params: {
        dataStr: JSON.stringify(this.data)
      }}));
    }
  }

  /**
   * 页面被卸载时触发
   */
  public onUnload(): void {
    if (!this.isDestory) {
      this.onDestroy(true);
      if (navigator && navigator.sendBeacon) {
        navigator.sendBeacon(this.props.host + this.props.api.api, JSON.stringify({ dataStr: JSON.stringify(this.data) }));
      }
    }
  }

  /**
   * Mutation监听事件
   */
  public onMutation(field: string, target: HTMLElement, options: TspComponentEventTrackingOption): void {
    console.log('动作触发时：');
    this.dataPush({
      actionName: options.actionName,
      behaviorName: options.behaviorName,
      mainType: options.mainType,
      subType: options.subType,
      id: field,
      target,
      type: options.type,
      trigger: options.trigger
    }, false);
    console.log(this.data)
  }

  /**
   * 得出详情数据记录
   */
  public getDetailedData(type: string, dataset: any): any {
    const id = this.isDestory ? dataset.trackid : dataset.prevtrackid;

    switch (type) {
      default: return { value: dataset.trackvalue ? dataset.trackvalue : undefined, id };
    }
  }

  public render(): JSX.Element {
    return (
      <div />
    );
  }
}

export default EventTracking;