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

export interface ITagAPIContext {
  addTag: (tag: pond.TagSettings) => Promise<any>;
  updateTag: (tagID: string, tag: pond.TagSettings) => Promise<any>;
  removeTag: (tagID: string) => Promise<any>;
  getTag: (tagID: string) => Promise<any>;
  listTags: (
    limit?: number,
    offset?: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    asRoot?: boolean,
    keys?: string[],
    types?: string[]
  ) => Promise<any>;
}

export const TagAPIContext = createContext<ITagAPIContext>({} as ITagAPIContext);

interface Props {}

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

  const addTag = (tag: pond.TagSettings) => {
    let keys = getContextKeys()
    let types = getContextTypes()
    let url = "/tags"
    if (keys.includes(as)) {
      url += "?keys=" + keys + "&types=" + types
    } else {
      url += "?as=" + as + "&keys=" + keys + "&types=" + types
    }
    return new Promise<AxiosResponse>((resolve, reject) => {
      post(pondURL(url), tag).then(resp => {
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  const updateTag = (tagID: string, tag: pond.TagSettings) => {
    return new Promise<AxiosResponse>((resolve, reject) => {
      put(pondURL("/tags/" + tagID), tag).then(resp => {
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  const removeTag = (tagID: string) => {
    return new Promise<AxiosResponse>((resolve, reject) => {
      del(pondURL("/tags/" + tagID)).then(resp => {
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  const getTag = (tagID: string) => {
    return new Promise<AxiosResponse>((resolve, reject)=>{
      get(pondURL("/tags/" + tagID)).then(resp => {
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  // const listTags = () => {

  //   return get(pondURL("/tags"));
  // };

  const listTags = (
    limit?: number,
    offset?: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    asRoot?: boolean,
    keys?: string[],
    types?: string[]
  ) => {
    limit = limit ? limit : 100
    // if (!keys) keys = getContextKeys()
    // if (!types) types = getContextTypes()  
    const url = pondURL(
      "/tags" +
        "?limit=" +
        limit +
        "&offset=" +
        offset +
        ("&order=" + (order ? order : "asc")) +
        ("&by=" + (orderBy ? orderBy : "deviceId")) +
        (search ? "&search=" + search : "") +
        (asRoot ? "&asRoot=" + asRoot.toString() : "") +
        (as && !(types && types.length > 0 && types[0] === "team") ? "&as=" + as : "") +
        (keys ? "&keys=" + keys.toString() : "") +
        (types ? "&types=" + types.toString() : "")
    );
    return new Promise<AxiosResponse<pond.ListTagsResponse>>((resolve, reject) => {
      get<pond.ListTagsResponse>(url).then(resp => {
        resp.data = pond.ListTagsResponse.fromObject(resp.data)
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  return (
    <TagAPIContext.Provider
      value={{
        addTag,
        updateTag,
        removeTag,
        getTag,
        listTags
      }}>
      {children}
    </TagAPIContext.Provider>
  );
}

export const useTagAPI = () => useContext(TagAPIContext);
