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 IContractInterface {
  addContract: (
    name: string,
    settings: pond.ContractSettings,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.AddContractResponse>>;
  listContracts: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[],
    numerical?: boolean,
    specificUser?: string,
    otherTeam?: string,
  ) => Promise<AxiosResponse<pond.ListContractsResponse>>;
  updateContract: (
    key: string,
    name: string,
    settings: pond.ContractSettings,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.UpdateContractResponse>>;
  removeContract: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveContractResponse>>;
  listContractsByYear: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[],
    numerical?: boolean,
    specificUser?: string,
    contractYear?: string,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.ListContractsByYearResponse>>;
  //list contract page data
  getContractPageData: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.GetContractPageDataResponse>>;
  //for the moment however simply passing the contract from the earlier list is sufficient
}

export const ContractAPIcontext = createContext<IContractInterface>({} as IContractInterface);

interface Props {}

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

  //add
  const addContract = (name: string, settings: pond.ContractSettings, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      return post<pond.AddContractResponse>(
        pondURL("/contracts?name=" + name + "&as=" + view),
        settings
      );
    }
    return post<pond.AddContractResponse>(pondURL("/contracts?name=" + name), settings);
  };
  //list
  const listContracts = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[],
    numerical?: boolean,
    otherTeam?: string
  ) => {
    let asText = "";
    const view = otherTeam ? otherTeam : as
    if (view) asText = "&as=" + view;
    return get<pond.ListContractsResponse>(
      pondURL(
        "/contracts?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + (order ? order : "asc")) +
          ("&by=" + (orderBy ? orderBy : "key")) +
          (numerical ? "&numerical=true" : "") +
          (search ? "&search=" + search : "") +
          (keys ? "&keys=" + keys.toString() : "") +
          (types ? "&types=" + types.toString() : "") +
          asText
      )
    );
  };
  const listContractsByYear = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[],
    numerical?: boolean,
    contractYear?: string,
    otherTeam?: string,
  ) => {
    let asText = "";
    const view = otherTeam ? otherTeam : as
    if (view) asText = "&as=" + view;
    return get<pond.ListContractsByYearResponse>(
      pondURL(
        "/contractsByYear?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + (order ? order : "asc")) +
          ("&by=" + (orderBy ? orderBy : "key")) +
          (numerical ? "&numerical=true" : "") +
          (search ? "&search=" + search : "") +
          (keys ? "&keys=" + keys.toString() : "") +
          (types ? "&types=" + types.toString() : "") +
          (contractYear ? "&year=" + contractYear : "") +
          asText
      )
    );
  };
  //update
  const updateContract = (key: string, name: string, settings: pond.ContractSettings, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      return put<pond.UpdateContractResponse>(
        pondURL("/contracts/" + key + "?as=" + view + "&name=" + name),
        settings
      );
    }
    return put<pond.UpdateContractResponse>(
      pondURL("/contracts/" + key + "?name=" + name),
      settings
    );
  };
  //remove
  const removeContract = (key: string, otherTeam?: string) => {
    const view = otherTeam ? otherTeam : as
    if (view) {
      return del<pond.RemoveContractResponse>(pondURL("/contracts/" + key + "?as=" + view));
    }
    return del<pond.RemoveContractResponse>(pondURL("/contracts/" + key));
  };

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

    return get<pond.GetContractPageDataResponse>(pondURL("/contractsPage/" + key));
  };

  return (
    <ContractAPIcontext.Provider
      value={{
        addContract,
        listContracts,
        listContractsByYear,
        updateContract,
        removeContract,
        getContractPageData
      }}>
      {children}
    </ContractAPIcontext.Provider>
  );
}

export const useContractAPI = () => useContext(ContractAPIcontext);
