import http from '@/http';
import type {ActeursVillePage, EpciActeursCarte, EpciDetail, EpciStats, SubdivisionAutre, VilleEvent} from '@/types/ville';
import {ACTEURS_PAR_PAGE} from '@/services/villeService';

/**
 * Fetches the logo URL for an EPCI from the media API
 * @param suaId - The EPCI (SubdivisionAutre) ID
 * @returns Promise with the logo URL or null if not found
 */
export async function getEpciLogo(suaId: number): Promise<string | null> {
  try {
    const response = await http.get(
      `/media/geolocale_subdivision_autre/${suaId}/Logo`
    );

    const url = response.data?.url;
    // Check if it's a real image (not a placeholder)
    if (url && !url.includes('dummyimage.com')) {
      return url;
    }
    return null;
  } catch {
    return null;
  }
}

/**
 * Finds the first EPCI with suaLogoPartenaire enabled from a list of SubdivisionAutre
 * @param subAutres - Array of SubdivisionAutre entities
 * @returns The first SubdivisionAutre with logo partenaire enabled, or null
 */
export function findEpciWithLogo(
  subAutres: SubdivisionAutre[] | undefined
): SubdivisionAutre | null {
  if (!subAutres || subAutres.length === 0) {
    return null;
  }

  return subAutres.find((sua) => sua.suaLogoPartenaire === 1) || null;
}

/**
 * Fetches the referentiel ID for the "EPCI" subdivision type
 * @returns Promise with the refId number
 * @throws Error if EPCI referentiel not found
 */
export async function getEpciRefId(): Promise<number> {
  const response = await http.get(
    '/geolocale_referentiel_subdivisions?refNom=EPCI'
  );

  const members = response.data['hydra:member'];
  if (!members || members.length === 0) {
    throw new Error('EPCI referentiel not found');
  }

  return members[0].refId;
}

/**
 * Fetches the list of all EPCI entities
 * @returns Promise with the array of SubdivisionAutre (EPCI)
 * @throws Error if request fails
 */
export async function getEpciList(): Promise<EpciDetail[]> {
  const refId = await getEpciRefId();

  const response = await http.get(
    `/geolocale_subdivision_autres?suaRef=${refId}&itemsPerPage=200`
  );

  return response.data['hydra:member'];
}

/**
 * Fetches a single EPCI by its ID
 * @param id - The EPCI (SubdivisionAutre) ID
 * @returns Promise with the EPCI detail data
 * @throws Error if id is empty or EPCI not found
 */
export async function getEpci(id: string): Promise<EpciDetail> {
  if (!id || id.trim() === '') {
    throw new Error('EPCI id is required');
  }

  try {
    const response = await http.get(
      `/geolocale_subdivision_autres/${id}`
    );

    return response.data;
  } catch (error: unknown) {
    const httpError = error as {response?: {status: number}};
    if (httpError.response?.status === 404) {
      throw new Error(`EPCI not found for ID: ${id}`);
    }
    throw error;
  }
}

/**
 * Fetches statistics for a given EPCI
 * @param id - The EPCI (SubdivisionAutre) ID
 * @returns Promise with the EPCI statistics
 * @throws Error if request fails
 */
export async function getEpciStats(id: string): Promise<EpciStats> {
  try {
    const response = await http.get(
      `/geolocale_subdivision_autres/${id}/stats`
    );

    return response.data;
  } catch (error: unknown) {
    const httpError = error as {response?: {status: number}};
    if (httpError.response?.status === 404) {
      throw new Error(`Stats not found for EPCI ID: ${id}`);
    }
    throw error;
  }
}

/**
 * Prochains événements valides des communes de l'EPCI (bloc agenda de la fiche, spec L172).
 * En cas d'échec de l'API, aucun événement : le bloc reste affichable.
 */
export async function getEpciEvents(id: string): Promise<VilleEvent[]> {
  try {
    const today = new Date().toISOString().slice(0, 10);
    const response = await http.get(
      `/evenements?page=1&itemsPerPage=4&eveVil.subAutres=${id}&eveValide=1&eveDate%5Bafter%5D=${today}`
    );
    return response.data['hydra:member'] ?? [];
  } catch {
    return [];
  }
}

/**
 * Une page d'acteurs des communes de l'EPCI, même contrat que la ville (spec L173).
 * En cas d'échec de l'API, une page vide : le bloc reste affichable.
 */
export async function getEpciActeurs(id: string, page = 1, itemsPerPage = ACTEURS_PAR_PAGE): Promise<ActeursVillePage> {
  try {
    const response = await http.get(`/geolocale_subdivision_autres/${id}/acteurs?page=${page}&itemsPerPage=${itemsPerPage}`);
    return response.data;
  } catch {
    return {total: 0, page, itemsPerPage, items: []};
  }
}

/** Acteurs actifs géolocalisés de l'EPCI et centre de la carte (spec L171). Carte vide si l'API échoue. */
export async function getEpciActeursCarte(id: string): Promise<EpciActeursCarte> {
  try {
    const response = await http.get(`/geolocale_subdivision_autres/${id}/acteurs-carte`);
    return response.data;
  } catch {
    return {suaId: Number(id), centre: null, acteurs: []};
  }
}
