import axios, { AxiosResponse } from 'axios';
import { apiToken } from './constants';

type Pagination = {
  page: number;
  pageSize: number;
  pageCount: number;
  total: number;
};

type AxiosGetFullResponse<T> = {
  data: T;
  pagination: Pagination | null;
};
type DataType = Record<string, any> | Array<any> | null;

export const normalize = (data: DataType): DataType => {
  const isObject = (data: any): data is Record<string, any> => typeof data === 'object' && !Array.isArray(data) && data !== null;
  const isArray = Array.isArray;

  const flatten = (data: Record<string, any>): Record<string, any> => ({
    id: data.id,
    ...data.attributes,
  });

  if (isArray(data)) {
    return data.map(normalize);
  }

  if (isObject(data)) {
    const { data: nestedData, attributes, ...rest } = data;

    if (isArray(nestedData)) {
      return nestedData.map(normalize);
    }

    if (isObject(nestedData)) {
      return normalize(flatten(nestedData));
    }

    if (nestedData === null) {
      return null;
    }

    return Object.fromEntries(
      Object.entries({ ...flatten(data), ...rest }).map(([key, value]) => [key, normalize(value)])
    );
  }

  return data;
};



export const axiosGetFull = async <T>(
  url: string,
  query: string,
  token: string | boolean= apiToken
): Promise<AxiosGetFullResponse<T>> => {
  try {
    const res: AxiosResponse<any> = await axios.get(`${url}?${query}`, {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    const data = normalize(res?.data?.data || []) as T;
    const pagination = res?.data?.meta?.pagination || null;

    return { data, pagination };
  } catch (error) {
    return { data: [] as T, pagination: null };
  }
};

export const axiosGet = async <T>(
  url: string,
  query: string,
  token: string | boolean= apiToken
): Promise<T | null> => {
  try {
    const res: AxiosResponse<any> = await axios.get(`${url}?${query}`, {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    return normalize(res?.data?.data || []) as T;
  } catch (error) {
    return null;
  }
};

export const axiosPost = async (url: string, query: any) => {
  const response = await axios
    .post(url, query, {
      headers: {
        Authorization: `Bearer ${apiToken}`,
      },
    })
    .then((response) => {
      return response.data.data;
    })
    .catch((error) => {
      return error;
    });
  return response;
};
