/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

import {produce} from 'immer';
import {Actions} from './';
import {SelectionInfo} from '../utils/info';
import {getRenderHostInstance} from 'flipper-frontend-core';

export type TrackingEvent =
  | {
      type: 'WINDOW_FOCUS_CHANGE';
      time: number;
      isFocused: boolean;
    }
  | {
      type: 'SELECTION_CHANGED';
      selectionKey: string | null;
      selection: SelectionInfo | null;
      time: number;
    }
  | {type: 'TIMELINE_START'; time: number; isFocused: boolean};

export type State = {
  timeline: TrackingEvent[];
};
const INITAL_STATE: () => State = () => ({
  timeline: [
    {
      type: 'TIMELINE_START',
      time: Date.now(),
      isFocused: getRenderHostInstance().hasFocus(),
    },
  ],
});

export type Action =
  | {
      type: 'windowIsFocused';
      payload: {isFocused: boolean; time: number};
    }
  | {type: 'CLEAR_TIMELINE'; payload: {time: number; isFocused: boolean}}
  | {
      type: 'SELECTION_CHANGED';
      payload: {selection: SelectionInfo; time: number};
    };

export default function reducer(
  state: State = INITAL_STATE(),
  action: Actions,
): State {
  if (action.type === 'CLEAR_TIMELINE') {
    return {
      ...state,
      timeline: [
        {
          type: 'TIMELINE_START',
          time: action.payload.time,
          isFocused: action.payload.isFocused,
        },
      ],
    };
  } else if (action.type === 'windowIsFocused') {
    return produce(state, (draft) => {
      draft.timeline.push({
        type: 'WINDOW_FOCUS_CHANGE',
        time: action.payload.time,
        isFocused: action.payload.isFocused,
      });
    });
  } else if (action.type === 'SELECTION_CHANGED') {
    const {selection, time} = action.payload;
    return produce(state, (draft) => {
      draft.timeline.push({
        type: 'SELECTION_CHANGED',
        time,
        selectionKey: selection?.plugin ? JSON.stringify(selection) : null,
        selection,
      });
    });
  }
  return state;
}

export function clearTimeline(time: number): Action {
  return {
    type: 'CLEAR_TIMELINE',
    payload: {
      time,
      isFocused: getRenderHostInstance().hasFocus(),
    },
  };
}

export function selectionChanged(payload: {
  selection: SelectionInfo;
  time: number;
}): Action {
  return {
    type: 'SELECTION_CHANGED',
    payload,
  };
}
