import { Action } from '@ngrx/store';
import { type } from '../utils/type';

const CATEGORY:string = 'LoopUser';
/**
 * For each action type in an action group, make a simple
 * enum object for all of this group's action types.
 *
 * The 'type' utility function coerces strings into string
 * literal types and runs a simple check to guarantee all
 * action types in the application are unique.
 */
export interface ILoopUserActions {
  AUTH: string;
  RESET_AUTH: string;
  ENTRIES: string;
  RESET_ENTRIES: string;
  TOGGLE_SELECTED: string;
  RESET_SELECTED_ENTRIES: string;
}

export const ActionTypes: ILoopUserActions = {
  AUTH:                   type(`[${CATEGORY}] Auth`),
  RESET_AUTH:             type(`[${CATEGORY}] Reset Auth`),
  ENTRIES:                type(`[${CATEGORY}] Entries`),
  RESET_ENTRIES:          type(`[${CATEGORY}] Reset Entries`),
  TOGGLE_SELECTED:        type(`[${CATEGORY}] Toggle Selected`),
  RESET_SELECTED_ENTRIES: type(`[${CATEGORY}] Reset Selected Entries`)
};

/**
 * Every action is comprised of at least a type and an optional
 * payload. Expressing actions as classes enables powerful
 * type checking in reducer functions.
 *
 * See Discriminated Unions: https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions
 */
export class AuthAction implements Action {
  type = ActionTypes.AUTH;

  constructor(public payload: any) { }
}

export class ResetAuthAction implements Action {
  type = ActionTypes.RESET_AUTH;

  constructor(public payload: any = undefined) { }
}

export class EntriesAction implements Action {
  type = ActionTypes.ENTRIES;

  constructor(public payload: any[]) { }
}

export class ResetEntriesAction implements Action {
  type = ActionTypes.RESET_ENTRIES;

  constructor(public payload: any[] = []) { }
}

export class ToggleSelectedAction implements Action {
  type = ActionTypes.TOGGLE_SELECTED;

  constructor(public payload: any) { }
}

export class ResetSelectedEntriesAction implements Action {
  type = ActionTypes.RESET_SELECTED_ENTRIES;

  constructor(public payload: any = []) { }
}

/**
 * Export a type alias of all actions in this action group
 * so that reducers can easily compose action types
 */
export type Actions
  = AuthAction
  | ResetAuthAction
  | EntriesAction
  | ResetEntriesAction
  | ToggleSelectedAction
  | ResetSelectedEntriesAction;
