import React from "react";
import axiosInstanceServer from "@/utils/axios";
import Page404 from "../ErrorPages/Page404";
import Page403 from "../ErrorPages/Page403";
import Page500 from "../ErrorPages/Page500";
import Page400 from "../ErrorPages/Page400";
import Page429 from "../ErrorPages/Page429";
import UseAuthorizationErrorServer from "@/hooks/UseAuthorizationErrorServer";

interface SingleRequest {
  url: string;
  params?: Record<string, any>;
}

interface MultiRequest {
  requests: Array<{
    url: string;
    key: string;
    params?: Record<string, any>;
  }>;
}

type GeneralServerAxiosProps = SingleRequest | MultiRequest;

function isMultiRequest(props: GeneralServerAxiosProps): props is MultiRequest {
  return "requests" in props;
}

export default async function GeneralServerAxios({
  children,
  ...props
}: GeneralServerAxiosProps & {
  children: (data: any, meta?: any) => React.ReactNode;
}) {
  try {
    if (isMultiRequest(props)) {
      const responses = await Promise.all(
        props.requests.map(({ url, params }) => {
          const fullUrl = addQueryParams(url, params);
          return axiosInstanceServer.get(fullUrl);
        }),
      );

      const data = responses.reduce(
        (acc, response, index) => ({
          ...acc,
          [props.requests[index].key]: response.data.data,
        }),
        {},
      );
      const meta = responses.reduce(
        (acc, response, index) => ({
          ...acc,
          [props.requests[index].key]: response.data.meta,
        }),
        {},
      );
      return <>{children(data, meta)}</>;
    } else {
      const { url, params } = props;
      const fullUrl = addQueryParams(url, params);
      const { data } = await axiosInstanceServer.get(fullUrl);
      return <>{children(data.data, data.data.meta)}</>;
    }
  } catch (error: any) {
    return (
      <>
        {error?.response?.status === 401 && (
          <UseAuthorizationErrorServer showError={true} />
        )}
        {error?.response?.status === 400 && <Page400 />}
        {error?.response?.status === 404 && <Page404 />}
        {error?.response?.status === 500 && <Page500 />}
        {error?.response?.status === 403 && <Page403 />}
        {error?.response?.status === 429 && <Page429 />}
      </>
    );
  }
}

function addQueryParams(url: string, params?: Record<string, any>): string {
  if (!params) return url;
  const query = new URLSearchParams(params as any).toString();
  return query ? `${url}?${query}` : url;
}
