import axios from "axios";
import { APIUrl } from "../../../core/constants/api_url";
import { PlaceDatasourceInf } from "../place_datasource";
import { AvailableDays, Place } from "./entities/place";
import {
  PlaceModel,
  placeModelToEntity,
} from "../../../domain/model/PlaceModel";

export class PlaceDatasourceProd implements PlaceDatasourceInf {
  /**
   * Registers a new place using the provided form data.
   * @param form - The place data to be registered.
   * @returns A promise that resolves when the place is successfully registered.
   */
  async registerPlace(form: Place): Promise<void> {
    const formToSend = new FormData();
    formToSend.append("available", form.available);
    formToSend.append("idTown", String(form.idTown));
    formToSend.append("name", form.name);
    formToSend.append("categoriesId", form.categoriesId.join(","));
    formToSend.append("descriptionES", form.descriptions?.[0] ?? "");
    formToSend.append("descriptionEN", form.descriptions?.[1] ?? "");
    formToSend.append("image", form.imagesList?.[0] ?? "");
    formToSend.append("latitude", String(form.latitude));
    formToSend.append("longitude", String(form.longitude));
    formToSend.append("openAt", String(form.openAt));
    formToSend.append("closeAt", String(form.closeAt));
    formToSend.append("address", form.address);

    if (form.available === AvailableDays.CUSTOM) {
      formToSend.append("startDate", String(form.startDate));
      formToSend.append("endDate", String(form.endDate));
    }

    const headers = {
      "Content-Type": "multipart/form-data",
    };

    await axios.post(APIUrl + "/place", formToSend, { headers });
  }

  /**
   * Retrieves a list of places by town ID.
   * @param idTown - The ID of the town.
   * @returns A promise that resolves to an array of Place objects.
   */
  async getPlacesByTown(idTown: number): Promise<Place[]> {
    const { data } = await axios.get<PlaceModel[]>(
      APIUrl + `/place/town/${idTown}/place`,
      {
        params: {
          lang: "ES",
        },
      }
    );

    const places = data.map((dataES) => {
      return placeModelToEntity(dataES);
    });

    return places;
  }

  /**
   * Retrieves a place by its ID.
   * @param idPlace - The ID of the place.
   * @returns A promise that resolves to a Place object.
   */
  async getPlaceById(idPlace: number): Promise<Place> {
    const { data: dataES } = await axios.get<PlaceModel>(
      APIUrl + `/place/${idPlace}`,
      {
        params: {
          lang: "ES",
        },
      }
    );

    const { data: dataEN } = await axios.get<PlaceModel>(
      APIUrl + `/place/${idPlace}`,
      {
        params: {
          lang: "EN",
        },
      }
    );

    const place: Place = placeModelToEntity(dataES);
    place.descriptions?.push(dataEN.description);

    return place;
  }

  /**
   * Updates an existing place using the provided form data.
   * @param place - The place data to be updated.
   * @returns A promise that resolves when the place is successfully updated.
   */
  async updatePlace(place: Place): Promise<void> {
    const formToSend = new FormData();
    formToSend.append("available", place.available);
    formToSend.append("idTown", String(place.idTown));
    formToSend.append("name", place.name);
    formToSend.append("categoriesId", place.categoriesId.join(","));
    formToSend.append("descriptionES", place.descriptions?.[0] ?? "");
    formToSend.append("descriptionEN", place.descriptions?.[1] ?? "");
    formToSend.append("image", place.imagesList?.[0] ?? "");
    formToSend.append("latitude", String(place.latitude));
    formToSend.append("longitude", String(place.longitude));
    formToSend.append("openAt", String(place.openAt));
    formToSend.append("closeAt", String(place.closeAt));
    formToSend.append("address", place.address);

    if (place.available === AvailableDays.CUSTOM) {
      formToSend.append("startDate", String(place.startDate));
      formToSend.append("endDate", String(place.endDate));
    }

    const headers = {
      "Content-Type": "multipart/form-data",
    };

    await axios.patch(APIUrl + `/place/${place.idPlace}`, formToSend, {
      headers,
    });
  }
}
