import type {
  Adresse,
  FormationStage,
  Organisateur,
  Place,
  Session,
  Ville,
} from '@/types/stage';

export type ResolvedLocation = Adresse & {
  source: 'session' | 'stage' | 'organiser';
};

function fromPlaceAndVille(
  ville: Ville,
  place: Place | null,
  fallbackPlaceName: string,
): Omit<ResolvedLocation, 'source'> {
  const capacity = place?.plaCapacite ?? null;
  const geoX = place?.plaGeoX ?? ville.vilGeoX;
  const geoY = place?.plaGeoY ?? ville.vilGeoY;
  const geoZ = place?.plaGeoZoom ?? ville.vilGeoZoom;
  const placeName = place?.plaLibelle || fallbackPlaceName;
  const libelle = `${ville.vilNom} ${ville.vilCodepostal}`;
  return {libelle, placeName, geoX, geoY, geoZ, capacity};
}

function fromOrganiser(orga: Organisateur): Omit<ResolvedLocation, 'source'> | null {
  if (!orga.aenVil) return null;
  const lines = [orga.aenAdresse1, orga.aenAdresse2].filter(Boolean) as string[];
  const ville = orga.aenVil;
  const libelle = [...lines, `${ville.vilNom} ${ville.vilCodepostal}`].join(', ');
  return {
    libelle,
    placeName: orga.aenLibelle,
    geoX: ville.vilGeoX,
    geoY: ville.vilGeoY,
    geoZ: ville.vilGeoZoom,
    capacity: null,
  };
}

export function resolveStageLocation(stage: FormationStage): ResolvedLocation {
  const useOrga = stage.fstAdresseorganisateur === 1;
  if (useOrga) {
    const orga = stage.fstEve.aenOrganisateurs[0];
    if (orga) {
      const resolved = fromOrganiser(orga);
      if (resolved) return {...resolved, source: 'organiser'};
    }
  }

  const ville = stage.fstEve.eveVil;
  if (!ville) {
    return {
      source: 'stage',
      libelle: '',
      placeName: '',
      geoX: 0,
      geoY: 0,
      geoZ: 10,
      capacity: null,
    };
  }
  return {
    ...fromPlaceAndVille(ville, stage.fstEve.evePla, ville.vilNom),
    source: 'stage',
  };
}

export function resolveSessionLocation(
  session: Session,
  stage: FormationStage,
): ResolvedLocation {
  const inherit = session.fssAdressestage === 1;
  if (inherit) {
    return resolveStageLocation(stage);
  }

  const ville = session.fssVil;
  if (ville) {
    return {
      ...fromPlaceAndVille(ville, session.fssPla ?? null, ville.vilNom),
      source: 'session',
    };
  }
  return resolveStageLocation(stage);
}
