import axios from "axios";
import { APIUrl } from "../../../core/constants/api_url";
import { TownDatasourceInf } from "../town_datasource";
import { State } from "./entities/state";
import { Town } from "./entities/town";
import { StateModel } from "../../../domain/model/StateModel";
import { TownModelTrad, TownModel } from "../../../domain/model/TownModel";
import { API_ROUTE_STATE } from "../../../core/constants/api_routes";

export class TownDatasourceProd implements TownDatasourceInf {
  /**
   * Retrieves a list of states from the API.
   * @returns A promise that resolves to an array of State objects.
   */
  async getStates(): Promise<State[]> {
    const { data } = await axios.get<StateModel[]>(APIUrl + API_ROUTE_STATE);
    const states = data.map((value) => {
      const state: State = {
        stateId: value.stateId,
        name: value.name,
        imageURL: value.imageURL,
      };
      return state;
    });

    return states;
  }

  /**
   * Registers a new town using the provided form data.
   * @param form - The town data to be registered.
   * @returns A promise that resolves when the town is successfully registered.
   */
  async registerTown(form: Town): Promise<void> {
    const formToSend = new FormData();
    formToSend.append("name", form.name);
    formToSend.append("descriptionES", form.descriptionES || "");
    formToSend.append("descriptionEN", form.descriptionEN || "");
    formToSend.append("state", String(form.idState));
    formToSend.append("image", form.imageURL || "");

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

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

  /**
   * Retrieves a list of towns by state ID and state name.
   * @param idState - The ID of the state.
   * @param stateName - The name of the state.
   * @returns A promise that resolves to an array of Town objects.
   */
  async getTownsByState(idState: number, stateName: string): Promise<Town[]> {
    const { data } = await axios.get<TownModelTrad[]>(
      APIUrl + `/state/${idState}/town`,
      {
        params: {
          lang: "ES",
        },
      }
    );
    const towns = data.map((value) => {
      const town: Town = {
        idTown: value.townId,
        name: value.name,
        idState: value.stateId,
        state: stateName,
      };
      return town;
    });

    return towns;
  }

  /**
   * Retrieves a town by its ID.
   * @param idTown - The ID of the town.
   * @returns A promise that resolves to a Town object.
   */
  async getTown(idTown: number): Promise<Town> {
    const { data } = await axios.get<TownModel>(APIUrl + `/town/${idTown}`);
    const town: Town = {
      idTown: data.townId,
      name: data.name,
      idState: data.stateId,
      descriptionES: data.descriptionES,
      descriptionEN: data.descriptionEN,
      state: "",
      imageURL: data.imageName,
    };
    return town;
  }

  /**
   * Updates an existing town using the provided form data.
   * @param form - The town data to be updated.
   * @returns A promise that resolves when the town is successfully updated.
   */
  async updateTown(form: Town): Promise<void> {
    const formToSend = new FormData();
    formToSend.append("name", form.name);
    formToSend.append("descriptionES", form.descriptionES || "");
    formToSend.append("descriptionEN", form.descriptionEN || "");
    formToSend.append("image", form.imageURL || "");
    formToSend.append("state", String(form.idState));

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

    await axios.patch(APIUrl + `/town/${form.idTown}`, formToSend, { headers });
  }
}
