import { useHTTP } from "hooks";
import React, { 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 INotificationAPIContext {
  listNotifications: (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string,
    asRoot?: boolean
  ) => Promise<AxiosResponse<pond.ListNotificationsResponse>>;
  hideNotification: (keys: string[]) => Promise<AxiosResponse<pond.HideNotificationResponse>>;
  listObjectNotifications: (
    key: string,
    type: pond.ObjectType,
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => Promise<AxiosResponse<pond.ListObjectNotificationsResponse>>;
}

export const NotificationAPIContext = createContext<INotificationAPIContext>(
  {} as INotificationAPIContext
);

interface Props {}

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

  const listNotifications = (
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string,
    asRoot?: boolean
  ) => {
    const view = otherTeam ? otherTeam : as
    let url = pondURL(
      "/notifications" +
        "?limit=" +
        limit +
        "&offset=" +
        offset +
        ("&order=" + or(order, "asc")) +
        ("&by=" + or(orderBy, "key")) +
        (view ? "&as=" + view : "") +
        (asRoot ? "&asRoot=" + asRoot.toString() : "") +
        (search ? "&search=" + search : "")
    )
    return new Promise<AxiosResponse<pond.ListNotificationsResponse>>((resolve, reject) => {
      get<pond.ListNotificationsResponse>(url).then(resp => {
        resp.data = pond.ListNotificationsResponse.fromObject(resp.data)
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  const listObjectNotifications = (
    key: string,
    type: pond.ObjectType,
    limit: number,
    offset: number,
    order?: "asc" | "desc",
    orderBy?: string,
    search?: string,
    otherTeam?: string
  ) => {
    const view = otherTeam ? otherTeam : as
    let url = pondURL(
      "/object/notifications" +
        "?objectKey=" +
        key +
        "&objectType=" +
        type +
        "&limit=" +
        limit +
        "&offset=" +
        offset +
        ("&order=" + or(order, "asc")) +
        ("&by=" + or(orderBy, "key")) +
        (search ? "&search=" + search : "") +
        (view ? "&as=" + view : "")
    )
    return new Promise<AxiosResponse<pond.ListObjectNotificationsResponse>>((resolve, reject) => {
      get<pond.ListObjectNotificationsResponse>(url).then(resp => {
        resp.data = pond.ListObjectNotificationsResponse.fromObject(resp.data)
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  const hideNotification = (keys: string[]) => {
    let url = pondURL("/notifications/hide")
    return new Promise<AxiosResponse<pond.HideNotificationResponse>>((resolve, reject) => {
      put<pond.HideNotificationResponse>(url,pond.NotificationKeys.create({ keys: keys })).then(resp => {
        resp.data = pond.HideNotificationResponse.fromObject(resp.data)
        return resolve(resp)
      }).catch(err => {
        return reject(err)
      })
    })
  };

  return (
    <NotificationAPIContext.Provider
      value={{
        listNotifications,
        hideNotification,
        listObjectNotifications
      }}>
      {children}
    </NotificationAPIContext.Provider>
  );
}

export const useNotificationAPI = () => useContext(NotificationAPIContext);