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

export interface IHarvestPlanAPIContext {
  addHarvestPlan: (harvestPlan: pond.HarvestPlanSettings) => Promise<any>;
  getHarvestPlan: (harvestPlanId: string) => Promise<any>;
  listHarvestPlans: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    as?: string,
    asRoot?: boolean
  ) => Promise<AxiosResponse<pond.ListHarvestPlansResponse>>;
  listHistory: (
    id: string,
    limit: number,
    offset: number
  ) => Promise<AxiosResponse<pond.ListHarvestPlanHistoryResponse>>;
  removeHarvestPlan: (
    harvestPlanId: string
  ) => Promise<AxiosResponse<pond.RemoveHarvestPlanResponse>>;
  updateHarvestPlan: (
    key: string,
    harvestPlan: pond.HarvestPlanSettings,
    asRoot?: true
  ) => Promise<AxiosResponse<pond.UpdateHarvestPlanResponse>>;
}

export const HarvestPlanAPIContext = createContext<IHarvestPlanAPIContext>(
  {} as IHarvestPlanAPIContext
);

interface Props {}

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

  const addHarvestPlan = (harvestPlan: pond.HarvestPlanSettings) => {
    if (as) return post(pondURL("/harvestPlans?as=" + as), harvestPlan);
    return post(pondURL("/harvestPlans"), harvestPlan);
  };

  const getHarvestPlan = (harvestPlanId: string) => {
    if (as) return get(pondURL("/harvestPlans/" + harvestPlanId + "?as=" + as));
    return get(pondURL("/harvestPlans/" + harvestPlanId));
  };

  const removeHarvestPlan = (key: string) => {
    if (as)
      return del<pond.RemoveHarvestPlanResponse>(pondURL("/harvestPlans/" + key + "?as=" + as));
    return del<pond.RemoveHarvestPlanResponse>(pondURL("/harvestPlans/" + key));
  };

  const listHarvestPlans = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    as?: string,
    asRoot?: boolean
  ) => {
    return get<pond.ListHarvestPlansResponse>(
      pondURL(
        "/harvestPlans" +
          "?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + or(order, "asc")) +
          ("&by=" + or(orderBy, "key")) +
          (asRoot ? "&asRoot=" + asRoot.toString() : "") +
          (search ? "&search=" + search : "") +
          (as ? "&as=" + as : "")
      )
    );
  };

  const listHistory = (id: string, limit: number, offset: number) => {
    return get<pond.ListHarvestPlanHistoryResponse>(
      pondURL("/harvestPlans/" + id + "/history?limit=" + limit + "&offset=" + offset)
    );
  };

  const updateHarvestPlan = (
    key: string,
    harvestPlan: pond.HarvestPlanSettings,
    asRoot?: boolean
  ) => {
    if (as)
      return put<pond.UpdateHarvestPlanResponse>(
        pondURL(
          "/harvestPlans/" +
            key +
            (as ? "?as=" + as : "") +
            (asRoot ? "&asRoot=" + asRoot.toString() : "")
        ),
        harvestPlan
      );
    return put<pond.UpdateHarvestPlanResponse>(
      pondURL("/harvestPlans/" + key + (asRoot ? "?asRoot=" + asRoot.toString() : "")),
      harvestPlan
    );
  };

  return (
    <HarvestPlanAPIContext.Provider
      value={{
        addHarvestPlan,
        getHarvestPlan,
        removeHarvestPlan,
        listHarvestPlans,
        listHistory,
        updateHarvestPlan
      }}>
      {children}
    </HarvestPlanAPIContext.Provider>
  );
}

export const useHarvestPlanAPI = () => useContext(HarvestPlanAPIContext);
