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

export interface IBinYardAPIContext {
  addBinYard: (bin: pond.BinYardSettings, otherTeam?: string) => Promise<AxiosResponse<pond.AddBinYardResponse>>;
  updateBinYard: (
    key: string,
    binYard: pond.BinYardSettings,
    asRoot?: true,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.UpdateBinYardResponse>>;
  removeBinYard: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveBinYardResponse>>;
  getBinYard: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.BinYard>>;
  listBinYards: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    asRoot?: boolean,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.ListBinYardsResponse>>;
}

export const BinYardAPIContext = createContext<IBinYardAPIContext>({} as IBinYardAPIContext);

interface Props {}

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

  const addBinYard = (binYard: pond.BinYardSettings, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (as) return post<pond.AddBinYardResponse>(pondURL(`/binyard?as=${view}`), binYard);
    return post<pond.AddBinYardResponse>(pondURL("/binyard"), binYard);
  };

  const updateBinYard = (key: string, binYard: pond.BinYardSettings, asRoot?: boolean, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      if (asRoot) {
        return put<pond.UpdateBinYardResponse>(
          pondURL(
            "/binyards/" + key + (asRoot ? "?asRoot=" + asRoot.toString() : "") + "&as=" + view
          ),
          binYard
        );
      }
      return put<pond.UpdateBinYardResponse>(pondURL("/binyards/" + key + "?as=" + view), binYard);
    }
    return put<pond.UpdateBinYardResponse>(
      pondURL("/binyards/" + key + (asRoot ? "?asRoot=" + asRoot.toString() : "")),
      binYard
    );
  };

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

  const getBinYard = (key: string, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) return get<pond.BinYard>(pondURL("/binYard/" + key + "?as=" + view));
    return get<pond.BinYard>(pondURL("/binYard/" + key));
  };

  const listBinYards = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    asRoot?: boolean,
    otherTeam?: string
  ) => {
    let asText = ""
    const view = otherTeam ? otherTeam : as
    if (view) asText = "&as=" + view;
    return get<pond.ListBinYardsResponse>(
      pondURL(
        "/binYards" +
          "?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + or(order, "asc")) +
          ("&by=" + or(orderBy, "key")) +
          (search ? "&search=" + search : "") +
          (asRoot ? "&asRoot=" + asRoot.toString() : "") +
          asText
      )
    );
  };

  return (
    <BinYardAPIContext.Provider
      value={{
        addBinYard,
        removeBinYard,
        getBinYard,
        listBinYards,
        updateBinYard
      }}>
      {children}
    </BinYardAPIContext.Provider>
  );
}

export const useBinYardAPI = () => useContext(BinYardAPIContext);
