import { useHTTP } from "hooks";
import { createContext, PropsWithChildren, useContext } from "react";
import { pond } from "protobuf-ts/pond";
import { pondURL } from "./pond";
import { AxiosResponse } from "axios";
import { useGlobalState } from "providers";

export interface ITerminalAPIContext {
  addTerminal: (
    name: string,
    terminal: pond.TerminalSettings,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.AddTerminalResponse>>;
  listTerminals: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.ListTerminalsResponse>>;
  listTerminalsAndGates: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.ListTerminalsAndGatesResponse>>;
  updateTerminal: (
    key: string,
    name: string,
    settings: pond.TerminalSettings,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.UpdateTerminalResponse>>;
  removeTerminal: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveTerminalResponse>>;
}

export const TerminalAPIContext = createContext<ITerminalAPIContext>({} as ITerminalAPIContext);

interface Props {}

export default function TerminalProvider(props: PropsWithChildren<Props>) {
  const { children } = props;
  const { get, del, post, put } = useHTTP();
  const [{ as }] = useGlobalState();

  const addTerminal = (name: string, terminal: pond.TerminalSettings, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view)
      return post<pond.AddTerminalResponse>(
        pondURL("/terminals?name=" + name + "&as=" + view),
        terminal
      );
    return post<pond.AddTerminalResponse>(pondURL("/terminals?name=" + name), terminal);
  };

  const listTerminals = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => {
    const view = otherTeam ? otherTeam : as
    if (view)
      return get<pond.ListTerminalsResponse>(
        pondURL(
          "/terminals?as=" +
            view +
            "&limit=" +
            limit +
            "&offset=" +
            offset +
            ("&order=" + (order ? order : "asc")) +
            ("&by=" + (orderBy ? orderBy : "key")) +
            (search ? "&search=" + search : "")
        )
      );
    return get<pond.ListTerminalsResponse>(
      pondURL(
        "/terminals?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + (order ? order : "asc")) +
          ("&by=" + (orderBy ? orderBy : "key")) +
          (search ? "&search=" + search : "")
      )
    );
  };

  const listTerminalsAndGates = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => {
    const view = otherTeam ? otherTeam : as
    if (view)
      return get<pond.ListTerminalsAndGatesResponse>(
        pondURL(
          "/terminalsAndGates?as=" +
            view +
            "&limit=" +
            limit +
            "&offset=" +
            offset +
            ("&order=" + (order ? order : "asc")) +
            ("&by=" + (orderBy ? orderBy : "key")) +
            (search ? "&search=" + search : "")
        )
      );
    return get<pond.ListTerminalsAndGatesResponse>(
      pondURL(
        "/terminalsAndGates?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + (order ? order : "asc")) +
          ("&by=" + (orderBy ? orderBy : "key")) +
          (search ? "&search=" + search : "")
      )
    );
  };

  const updateTerminal = (key: string, name: string, settings: pond.TerminalSettings, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      return put<pond.UpdateTerminalResponse>(
        pondURL("/terminals/" + key + "?as=" + view + "&name=" + name),
        settings
      );
    }
    return put<pond.UpdateTerminalResponse>(
      pondURL("/terminals/" + key + "?name=" + name),
      settings
    );
  };

  const removeTerminal = (key: string, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      return del<pond.RemoveTerminalResponse>(pondURL("/terminals/" + key + "?as=" + view));
    }
    return del<pond.RemoveTerminalResponse>(pondURL("/terminals/" + key));
  };

  return (
    <TerminalAPIContext.Provider
      value={{
        addTerminal,
        listTerminals,
        updateTerminal,
        removeTerminal,
        listTerminalsAndGates
      }}>
      {children}
    </TerminalAPIContext.Provider>
  );
}

export const useTerminalAPI = () => useContext(TerminalAPIContext);
