import type { DataProvider, HttpError } from "@refinedev/core";

const API_URL = "/api/v1";

export const dataProvider: DataProvider = {
  getOne: async ({ resource, id, meta }) => {
    const response = id !== "" ? await fetch(`${API_URL}/${resource}/${id}`) : await fetch(`${API_URL}/${resource}`);
    if (response.status < 200 || response.status > 299) {
      if (response.status == 405) {
          const error: HttpError = {
              message: "Resource is not ready",
              statusCode: 405,
          };
          return Promise.reject(error);
      }
      throw response;
    }

    const data = await response.json();

    return {
      data
    };
  },
  update: async ({ resource, id, variables }) => {
    const response = await fetch(`${API_URL}/${resource}/${id}`, {
      method: "PUT",
      body: JSON.stringify(variables),
      headers: {
        "Content-Type": "application/json",
      },
    });

    if (response.status < 200 || response.status > 299) {
      if (response.status == 405) {
          const error: HttpError = {
              message: "Resource is not ready",
              statusCode: 405,
          };
          return Promise.reject(error);
      }
      throw response;
    }
    const data = await response.json();

    return { data };
  },
  getList: async ({ resource, pagination, filters, sorters, meta }) => {
    const params = new URLSearchParams();

    const serverPagination = pagination && pagination.mode =="server";
    if (serverPagination) {
      params.append("page", String(pagination.current));
      params.append("size", String(pagination.pageSize));
    }

    if (sorters && sorters.length > 0) {
      params.append("order_by", sorters.map((sorter) => (sorter.order == "asc" ? "+" : "-") + sorter.field).join(","));
    }

    if (filters && filters.length > 0) {
      filters.forEach((filter) => {
        if ("field" in filter && filter.value && filter.operator === "contains") {
          params.append(filter.field + "__like", "%" + filter.value + "%");
        }
      });
    }

    const response = await fetch(`${API_URL}/${resource}/?${params.toString()}`);

    if (response.status < 200 || response.status > 299) {
      if (response.status == 405) {
          const error: HttpError = {
              message: "Resource is not ready",
              statusCode: 405,
          };
          return Promise.reject(error);
      }
      throw response;
    }

    const data = await response.json();

    if (serverPagination) {
      return {
        data: data.items,
        total: data.total,
      };
    }
    return {
      data: data,
      total: data.length,
    };
  },
  create: async ({ resource, variables }) => {
    const response = await fetch(`${API_URL}/${resource}`, {
      method: "POST",
      body: JSON.stringify(variables),
      headers: {
        "Content-Type": "application/json",
      },
    });

    if (response.status < 200 || response.status > 299) {
      if (response.status == 405) {
          const error: HttpError = {
              message: "Resource is not ready",
              statusCode: 405,
          };
          return Promise.reject(error);
      }
      throw response;
    }

    const data = await response.json();

    return { data };
  },
  deleteOne: async ({ resource, id, variables, meta }) => {
    const response = await fetch(`${API_URL}/${resource}/${id}`,{
      method: "DELETE",
    });

    if (response.status < 200 || response.status > 299) {
      if (response.status == 405) {
          const error: HttpError = {
              message: "Resource is not ready",
              statusCode: 405,
          };
          return Promise.reject(error);
      }
      throw response;
    }

    const data = await response.json();

    return {
      data
    };
  },
  getApiUrl: () => API_URL,
  // Optional methods:
  // getMany: () => { /* ... */ },
  // createMany: () => { /* ... */ },
  // deleteMany: () => { /* ... */ },
  // updateMany: () => { /* ... */ },
  // custom: () => { /* ... */ },
};