/* Copyright (C) 2024 Manuel Bustillo*/

import { Entity } from '@/app/lib/definitions';
import { getCsrfToken, getSlug } from '@/app/lib/utils';

export interface Api<T extends Entity> {
  getAll(serializable: Serializable<T> ,callback: (objets: T[]) => void): void;
  create(serializable: Serializable<T>, object: T, callback: () => void): void;
  update(serializable: Serializable<T>, object: T, callback: () => void): void;
  destroy(serializable: Serializable<T>, object: T, callback: () => void): void;
}

export interface Serializable<T> {
  fromJson(json: any): T;
  toJson(object: T): string;
  apiPath(): string;
}

export class AbstractApi<T extends Entity> implements Api<T> {
  getAll(serializable: Serializable<T>, callback: (objets: T[]) => void): void {
    fetch(`/api/${getSlug()}/${serializable.apiPath()}`)
      .then((response) => response.json())
      .then((data) => {
        callback(data.map((record: any) => {
          return serializable.fromJson(record);
        }));
      }, (error) => {
        return [];
      });
  }

  update(serializable: Serializable<T>, object: T, callback: () => void): void {
    fetch(`/api/${getSlug()}/${serializable.apiPath()}/${object.id}`, {
      method: 'PUT',
      body: serializable.toJson(object),
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': getCsrfToken(),
      }
    }).then(callback)
      .catch((error) => console.error(error));
  }

  create(serializable: Serializable<T>, object: T, callback: () => void): void {
    fetch(`/api/${getSlug()}/${serializable.apiPath()}`, {
      method: 'POST',
      body: serializable.toJson(object),
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': getCsrfToken(),
      }
    }).then(callback)
      .catch((error) => console.error(error));
  }

  destroy(serializable: Serializable<T>, object: T, callback: () => void): void {
    fetch(`/api/${getSlug()}/${serializable.apiPath()}/${object.id}`, {
      method: 'DELETE',
      headers: {
        'X-CSRF-TOKEN': getCsrfToken(),
      }
    }).then(callback)
      .catch((error) => console.error(error));
  }
}