import axios from "axios";
import { Buffer } from "buffer";
import { PoiDatasourceInf } from "../poi_datasource";
import { PointOfInterest } from "./entities/poi";
import { APIUrl } from "../../../core/constants/api_url";
import {
  API_ROUTE_PLACE,
  API_ROUTE_POINT,
} from "../../../core/constants/api_routes";
import { POIModel, POIModelToEntity } from "../../../domain/model/POIModel";

export class POIDatasourceProd implements PoiDatasourceInf {
  /**
   * Registers a new point of interest using the provided form data.
   * @param form - The point of interest data to be registered.
   * @returns A promise that resolves when the point is successfully registered.
   */
  async registerPoint(form: PointOfInterest): Promise<void> {
    const formToSend = new FormData();
    formToSend.append("idPlace", String(form.idPlace));
    formToSend.append("name", form.name);
    formToSend.append("image", form.image);
    formToSend.append("contentEN", form.contentEN);
    formToSend.append("contentES", form.contentES);
    formToSend.append("directionsEN", form.directionsEN);
    formToSend.append("directionsES", form.directionsES);

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

    await axios.post(APIUrl + API_ROUTE_POINT, formToSend, { headers });
  }

  /**
   * Retrieves a list of points of interest by place ID.
   * @param idPlace - The ID of the place.
   * @returns A promise that resolves to an array of PointOfInterest objects.
   */
  async getPOIsByPlace(idPlace: number): Promise<PointOfInterest[]> {
    const { data: dataES } = await axios.get<POIModel[]>(
      APIUrl + API_ROUTE_PLACE + `/${idPlace}` + API_ROUTE_POINT,
      {
        params: {
          lang: "ES",
        },
      }
    );

    const poiList = dataES.map((dataESModel) => {
      return POIModelToEntity(dataESModel);
    });

    return poiList;
  }

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

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

    const poi: PointOfInterest = POIModelToEntity(dataES);
    poi.contentEN = dataEN.content;
    poi.directionsEN = dataEN.directions;

    return poi;
  }

  /**
   * Generates a PDF for the specified points of interest.
   * @param idPlace - The ID of the place.
   * @param pointsId - An array of point IDs to include in the PDF.
   * @returns A promise that resolves to a base64-encoded string of the PDF.
   */
  async getPDFByPoints(idPlace: number, pointsId: number[]): Promise<string> {
    const { data } = await axios.get(
      APIUrl + API_ROUTE_PLACE + `/${idPlace}` + API_ROUTE_POINT + "/generate",
      {
        params: {
          pointsId: pointsId.join(","),
        },
        responseType: "arraybuffer",
      }
    );
    return Buffer.from(data, "binary").toString("base64");
  }
}
