import * as React from 'react';

import {
  withLatencyTracker,
  LatencyTrackedPropsComponent,
  LatencyTrackerContext,
} from 'mweb/common/latency/withLatencyTracker';
import { LatencyTracker } from 'mweb/common/latency/latencyTracker';
import { RouterProps } from 'mweb/common/router';
import {
  contextTypeValidator,
  ContextTypes,
} from 'mweb/common/utils/contextTypeValidator';

interface TrackedRouterClass
  extends React.ExtendableComponentClass<
      RouterProps,
      LatencyTrackedPropsComponent
    > {
  displayName: string;
}

export interface RouterLatencyTrackerChildContext
  extends Pick<
      LatencyTrackerContext,
      'latencyTracker' | 'latencyPageCounter'
    > {}

export function withRouterLatencyTracker(
  RouterClass: TrackedRouterClass,
): React.ComponentClass<RouterProps> {
  if (!process.env.BROWSER) {
    return RouterClass;
  }

  return class TrackedRouter extends withLatencyTracker(RouterClass) {
    static childContextTypes: ContextTypes<RouterLatencyTrackerChildContext> = {
      latencyTracker: contextTypeValidator,
      latencyPageCounter: contextTypeValidator,
    };

    latencyTracker: LatencyTracker;

    componentWillUpdate(
      nextProps: RouterProps,
      nextState: any,
      nextContext: any,
    ): void {
      if (super.componentWillUpdate) {
        super.componentWillUpdate(nextProps, nextState, nextContext);
      }

      if (this.props.location !== nextProps.location) {
        this.latencyTracker.resetForNextPage();
      }
    }

    getChildContext = (): RouterLatencyTrackerChildContext => {
      return {
        latencyTracker: this.latencyTracker,
        latencyPageCounter: LatencyTracker.pageCounter,
      };
    };
  };
}
