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 IDevicePresetInterface {
  //add
  addDevicePreset: (
    name: string,
    settings: pond.DevicePresetSettings,
    parentKey?: string,
    parentTypes?: string
  ) => Promise<AxiosResponse<pond.AddDevicePresetResponse>>;
  //list
  listDevicePresets: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[]
  ) => Promise<AxiosResponse<pond.ListDevicePresetResponse>>;
  //update
  updateDevicePreset: (
    key: string,
    name: string,
    settings: pond.DevicePresetSettings
  ) => Promise<AxiosResponse<pond.UpdateDevicePresetResponse>>;

  //remove
  removeDevicePreset: (key: string) => Promise<AxiosResponse<pond.DeleteDevicePresetResponse>>;

  //get
  getDevicePreset: (key: string) => Promise<AxiosResponse<pond.GetDevicePresetResponse>>;
}

export const DevicePresetAPIcontext = createContext<IDevicePresetInterface>(
  {} as IDevicePresetInterface
);

interface Props {}

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

  //add
  const addDevicePreset = (
    name: string,
    settings: pond.DevicePresetSettings,
    parentKey?: string,
    parentType?: string
  ) => {
    let key = "";
    let type = "";
    if (parentKey && parentType) {
      key = "&parentKey=" + parentKey;
      type = "&parentType=" + parentType;
    }
    if (as) {
      return post<pond.AddDevicePresetResponse>(
        pondURL("/devicePreset?name=" + name + "&as=" + as + key + type),
        settings
      );
    }
    return post<pond.AddDevicePresetResponse>(
      pondURL("/devicePreset?name=" + name + key + type),
      settings
    );
  };
  //list
  const listDevicePresets = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    keys?: string[],
    types?: string[]
  ) => {
    let asText = "";
    if (as) asText = "&as=" + as;
    return get<pond.ListDevicePresetResponse>(
      pondURL(
        "/devicePresets?limit=" +
          limit +
          "&offset=" +
          offset +
          ("&order=" + (order ? order : "asc")) +
          ("&by=" + (orderBy ? orderBy : "key")) +
          (search ? "&search=" + search : "") +
          (keys ? "&keys=" + keys.toString() : "") +
          (types ? "&types=" + types.toString() : "") +
          asText
      )
    );
  };
  //update
  const updateDevicePreset = (key: string, name: string, settings: pond.DevicePresetSettings) => {
    if (as) {
      return put<pond.UpdateDevicePresetResponse>(
        pondURL("/devicePreset/" + key + "?as=" + as + "&name=" + name),
        settings
      );
    }
    return put<pond.UpdateDevicePresetResponse>(
      pondURL("/devicePreset/" + key + "?name=" + name),
      settings
    );
  };

  //remove
  const removeDevicePreset = (key: string) => {
    if (as) {
      return del<pond.DeleteDevicePresetResponse>(pondURL("/devicePreset/" + key + "?as=" + as));
    }
    return del<pond.DeleteDevicePresetResponse>(pondURL("/devicePreset/" + key + "?as=" + as));
  };

  //get
  const getDevicePreset = (key: string) => {
    if (as) {
      return del<pond.GetDevicePresetResponse>(pondURL("/devicePreset/" + key + "?as=" + as));
    }
    return del<pond.GetDevicePresetResponse>(pondURL("/devicePreset/" + key + "?as=" + as));
  };
  return (
    <DevicePresetAPIcontext.Provider
      value={{
        //add
        addDevicePreset,
        //list
        listDevicePresets,
        //update
        updateDevicePreset,
        //remove
        removeDevicePreset,
        //get
        getDevicePreset
      }}>
      {children}
    </DevicePresetAPIcontext.Provider>
  );
}

export const useDevicePresetAPI = () => useContext(DevicePresetAPIcontext);
