import { createContext, useContext, useReducer, Dispatch } from "react";
// import { User } from "../models";
import { pond } from "protobuf-ts/pond";
import { User } from "../models/user";
import { Team } from "../models/team";
import { Firmware } from "models";

export interface GlobalState {
//   tags: Tag[];
  user: User;
  team: Team;
  as: string;
  firmware: Map<string, Firmware>;
//   newStructure: boolean;
  showErrors: boolean;
  userTeamPermissions: pond.Permission[];
  backgroundTasksComplete: boolean;
}

export interface GlobalStateAction {
  key: keyof GlobalState;
  value: GlobalState[keyof GlobalState];
}

export const StateContext = createContext<[GlobalState, Dispatch<GlobalStateAction>]>([
  {} as GlobalState,
  {} as Dispatch<GlobalStateAction>
]);

interface StateProviderProps {
  state: GlobalState;
  reducer: (ctx: GlobalState, action: GlobalStateAction) => GlobalState;
//   user: User;
  children?: any;
}

export const StateProvider = (props: StateProviderProps) => {
  return (
    <StateContext.Provider value={useReducer(props.reducer, props.state)}>
      {props.children}
    </StateContext.Provider>
  );
};

//-------------State container usage-------------

// a) Functional Components (hook)
export const useGlobalState = () => useContext(StateContext);
/*
  1. Import the hook:
    import { useGlobalState } from "providers";

  2. Access the context members by binding it (x is an example context member);
    const [{x}, dispatch] = useGlobalState();
*/

// b) Class Components (context)
/*
  1. Import state context:
    import { StateContext } from "providers";

  2. Add the context to the beginning of the class component:
    static contextType = StateContext;
    context!: React.ContextType<typeof StateContext>;

  3. Access the context where x is a key of context:
    const [{x}, dispatch] = this.context;
*/
