import * as React from 'react';

import { LatencyTrackerContext } from 'mweb/common/latency/withLatencyTracker';
import { CustomLatencyEvent } from 'mweb/common/latency/latencyReporter';
import {
  contextTypeValidator,
  ContextTypes,
} from 'mweb/common/utils/contextTypeValidator';
import { getComponentName } from 'mweb/common/utils/getComponentName';

interface CustomLatencyContext
  extends Pick<LatencyTrackerContext, 'latencyReporter'> {}

export type ReportCustomLatency = (event: CustomLatencyEvent) => () => void;

export interface CustomLatencyProps {
  reportLatencyEvent: ReportCustomLatency;
}

export function withCustomLatency<P extends CustomLatencyProps>(
  WrappedComponent: React.ComponentType<P>,
): React.ComponentType<ObjectDiff<P, CustomLatencyProps>> {
  return class CustomLatencyComponent extends React.Component<
    ObjectDiff<P, CustomLatencyProps>
  > {
    static displayName: string = `CustomLatency(${getComponentName(
      WrappedComponent,
    )})`;

    static contextTypes: ContextTypes<CustomLatencyContext> = {
      latencyReporter: contextTypeValidator,
    };

    context: CustomLatencyContext;

    reportLatencyEvent: ReportCustomLatency = (
      event: CustomLatencyEvent,
    ) => () => {
      if (this.context.latencyReporter) {
        this.context.latencyReporter[event]();
      }
    };

    render(): JSX.Element {
      return (
        <WrappedComponent
          {...this.props}
          reportLatencyEvent={this.reportLatencyEvent}
        />
      );
    }
  };
}
