
import { App } from "antd"
import React, { type ReactNode } from "react"
import { useContext, createContext } from "react"
import type { DefaultResponse } from "../types/responses"
import { type IHttpService, type IRequestParams } from "../services"

interface HttpContextType {
  request: IHttpService
  queryParams: Record<string, string>
  getModel: (params: { url: string, id?: number | string, params?: IRequestParams }) => Promise<DefaultResponse<any>>
  postModel: <T = any>(url: string, body: T, onSuccess?: (data: any) => void, notifySuccess?: boolean) => Promise<DefaultResponse<T>>
  getModels: (url: string, params?: IRequestParams, updateQueryParams?: boolean) => Promise<DefaultResponse<any>>
  deleteModel: <T = any>(url: string, body: T, onSuccess?: (data: any) => void, notifySuccess?: boolean) => Promise<DefaultResponse<any>>
  isLoading: boolean
}

const HttpContext = createContext<HttpContextType>({
  request: {} as IHttpService,
  queryParams: {},
  getModel: async () => { throw new Error("getModel not implemented") },
  postModel: async () => { throw new Error("postModel not implemented") },
  getModels: async () => { throw new Error("getModels not implemented") },
  deleteModel: async () => { throw new Error("deleteModel not implemented") },
  isLoading: false,
});

export function HttpProvider({ children, request }: { children: ReactNode, request: IHttpService }) {
  const [isLoading, setIsLoading] = React.useState(false);
  const [queryParams, setQueryParams] = React.useState({});
  // const { notification } = App.useApp();

  

  async function getModel<T = any>({ url, id, params }: { url: string, id?: number | string, params?: IRequestParams }): Promise<DefaultResponse<any>> {
    setIsLoading(true);
    try {
      let _params = { ...params }
      if (id) {
        _params.id = id;
      }
      const response = await request.get(url, _params, false);
      return response as DefaultResponse<T>;
    } finally {
      setIsLoading(false);
    }
  }

  async function getModels(url: string, params: IRequestParams = {}, updateQueryParams: boolean = false): Promise<DefaultResponse<any>> {
    setIsLoading(true);
    try {
      const response = await request.get(url, params, updateQueryParams);
      return response as DefaultResponse<any>;
    } finally {
      setIsLoading(false);
    }
  }

  async function postModel<T = any>(url: string, body: T, onSuccess?: (data: any) => void, notifySuccess: boolean = true): Promise<DefaultResponse<T>> {
    setIsLoading(true);
    try {
      const response = await request.post(url, body);
      console.log(response)
      if (response.status !== 200) {
        // notification.error({
        //   message: "Error",
        //   description: response?.mensaje
        // });
        return response as DefaultResponse<any>;
      }

      if (notifySuccess && !response.isError) {
        // notification.success({
        //   message: response?.mensaje
        // });
      }
      if (onSuccess && !response.isError && response.status === 200) {
        onSuccess(response);
      }
      return response as DefaultResponse<T>;
    } finally {
      setIsLoading(false);
    }
  }

  async function deleteModel<T = any>(url: string, body: T, onSuccess?: (data: any) => void, notifySuccess: boolean = true): Promise<DefaultResponse<any>> {
    setIsLoading(true);
    try {
      const response = await request.delete<T>(url, body);

      if (response.status !== 200) {
        // notification.error({
        //   message: "Error",
        //   description: response?.mensaje
        // });
        return response as DefaultResponse<any>;
      }

      if (notifySuccess) {
        // notification.success({
        //   message: response?.mensaje
        // });
      }

      if (onSuccess && response.status === 200) {
        onSuccess(response);
      }

      return response as DefaultResponse<any>;
    } finally {
      setIsLoading(false);
    }
  }

  React.useEffect(() => {
    const search = window.location.search;
    const params = new URLSearchParams(search);
    const query: Record<string, string> = {};
    for (const [key, value] of params) {
      query[key] = value;
    }
    setQueryParams(query);
  }, []);

  return (
    <HttpContext.Provider value={{
      queryParams,
      request,
      getModel,
      getModels,
      postModel,
      deleteModel,
      isLoading
    }}>
      {children}
    </HttpContext.Provider>
  );
}

export function useHttp() {
  const context = useContext(HttpContext);

  if (!context) {
    throw new Error('useHttp must be used within a HttpProvider');
  }

  return context;
}
