// App
// -----------------------------------------------------------------------------
import request from './request';
import { IReadManyResponse } from 'types/default';

export class RestApi<RecordType, RecordTypeForBackend = RecordType> {
  url: string;

  constructor(url: string) {
    this.url = url;
  }

  async create(data: RecordType | RecordTypeForBackend): Promise<RecordType> {
    const response = await request<
      RecordType | RecordTypeForBackend,
      RecordType
    >({
      method: 'POST',
      url: `${this.url}`,
      data,
    });
    return response.data;
  }

  async read(id: number | string): Promise<RecordType> {
    const response = await request<undefined, RecordType>({
      method: 'GET',
      url: `${this.url}${id}/`,
    });
    return response.data;
  }

  async readList({
    filter,
    pagination,
  }: {
    filter?: unknown; // TODO: filter type
    pagination?: { page?: number; pageSize?: number; ordering?: string };
  }): Promise<IReadManyResponse<RecordType>> {
    let searchParamsString = '';
    if (pagination) {
      const getParams: { [p: string]: string } = {};
      if (pagination.page) {
        getParams['page'] = pagination.page.toString();
      }
      if (pagination.pageSize) {
        getParams['page_size'] = pagination.pageSize.toString();
      }
      if (pagination.ordering) {
        getParams['ordering'] = pagination.ordering;
      }
      searchParamsString = new URLSearchParams(getParams).toString();
    }

    const response = await request<
      { filter: unknown },
      IReadManyResponse<RecordType>
    >({
      method: 'GET',
      url: `${this.url}?${searchParamsString}`,
      data: {
        filter,
      },
    });

    return response.data;
  }

  async update(
    id: number | string,
    data: RecordType | RecordTypeForBackend,
  ): Promise<RecordType> {
    const response = await request<
      RecordType | RecordTypeForBackend,
      RecordType
    >({
      method: 'PATCH',
      url: `${this.url}${id}/`,
      data,
    });

    return response.data;
  }

  async delete(id: number | string): Promise<void> {
    await request<undefined, undefined>({
      method: 'DELETE',
      url: `${this.url}${id}/`,
    });
  }
}
