interface Records {
  [key: string]: number;
}

const records: Records = {};
let isEnabled = false;

const isTimingsEnabled = (): boolean => isEnabled;

export const forceEnable = () => {
  isEnabled = true;
};

// Debug: uncomment to enable
// forceEnable();

export const start = (key: string) => {
  // we want to strip all the code out for production builds
  // draw back: can only do timings in dev env (which seems to be fine for now)
  if (process.env.NODE_ENV !== 'production') {
    if (!isTimingsEnabled()) {
      return;
    }
    const now: number = performance.now();

    records[key] = now;
  }
};

interface Style {
  textColor: string;
  symbol: string;
}

export const finish = (key: string) => {
  if (process.env.NODE_ENV !== 'production') {
    if (!isTimingsEnabled()) {
      return;
    }
    const now: number = performance.now();

    const previous: number | null = records[key];

    if (!previous) {
      // eslint-disable-next-line no-console
      console.warn('cannot finish timing as no previous time found', key);
      return;
    }

    const result: number = now - previous;
    const rounded: string = result.toFixed(2);

    const style: Style = (() => {
      if (result < 12) {
        return {
          textColor: 'green',
          symbol: '✅',
        };
      }
      if (result < 40) {
        return {
          textColor: 'orange',
          symbol: '⚠️',
        };
      }
      return {
        textColor: 'red',
        symbol: '❌',
      };
    })();

    // eslint-disable-next-line no-console
    console.log(
      `${style.symbol} %cTiming %c${rounded} %cms %c${key}`,
      // title
      'color: blue; font-weight: bold;',
      // result
      `color: ${style.textColor}; font-size: 1.1em;`,
      // ms
      'color: grey;',
      // key
      'color: purple; font-weight: bold;',
    );
  }
};
