import {resolveStageLocation, resolveSessionLocation} from './stageAddress';
import type {FormationStage, Session, Ville, Place, Organisateur} from '@/types/stage';

const ville: Ville = {
  vilNom: 'Rennes',
  vilCodepostal: '35000',
  vilGeoX: 1.1,
  vilGeoY: 2.2,
  vilGeoZoom: 10,
};

const place: Place = {
  plaLibelle: 'Salle des fêtes',
  plaCapacite: 200,
  plaGeoX: 3.3,
  plaGeoY: 4.4,
  plaGeoZoom: 15,
};

const orga: Organisateur = {
  aenId: 7,
  aenLibelle: 'Asso Bretonne',
  aenAdresse1: '12 rue du Stang',
  aenAdresse2: null,
  aenVil: {
    vilNom: 'Quimper',
    vilCodepostal: '29000',
    vilGeoX: 5.5,
    vilGeoY: 6.6,
    vilGeoZoom: 12,
  },
};

function makeStage(overrides: Partial<FormationStage> = {}): FormationStage {
  return {
    fstId: 1,
    fstDescription: '',
    fstTarifs: '',
    fstAdresseorganisateur: 0,
    fstEve: {
      eveId: 10,
      eveDate: '2026-05-01',
      eveHeure: '2026-05-01T09:00:00Z',
      eveLibelle: 'Stage',
      eveTev: {tevLibelle: 'Stage'},
      eveVil: ville,
      evePla: place,
      aenOrganisateurs: [orga],
    },
    sessions: [],
    ...overrides,
  };
}

function makeSession(overrides: Partial<Session> = {}): Session {
  return {
    fssFod: {fodNom: 'Danse'},
    fssSoustitre: '',
    fssDateDebut: '2026-05-01',
    fssHeureDebut: '2026-05-01T09:00:00Z',
    fssDateFin: '2026-05-01',
    fssHeureFin: '2026-05-01T17:00:00Z',
    fssTarifs: '',
    fssDescription: '',
    fssAdressestage: 0,
    fssVil: null,
    fssPla: null,
    animateurs: [],
    ...overrides,
  };
}

describe('resolveStageLocation', () => {
  it('returns stage own place when fstAdresseorganisateur is 0', () => {
    const loc = resolveStageLocation(makeStage({fstAdresseorganisateur: 0}));

    expect(loc.source).toBe('stage');
    expect(loc.geoX).toBe(place.plaGeoX);
    expect(loc.placeName).toBe(place.plaLibelle);
    expect(loc.libelle).toContain('Rennes');
  });

  it('falls back to ville when stage has no place', () => {
    const stage = makeStage({fstAdresseorganisateur: 0});
    stage.fstEve.evePla = null;

    const loc = resolveStageLocation(stage);

    expect(loc.source).toBe('stage');
    expect(loc.geoX).toBe(ville.vilGeoX);
    expect(loc.placeName).toBe(ville.vilNom);
  });

  it('returns organiser address when fstAdresseorganisateur is 1', () => {
    const loc = resolveStageLocation(makeStage({fstAdresseorganisateur: 1}));

    expect(loc.source).toBe('organiser');
    expect(loc.libelle).toContain('12 rue du Stang');
    expect(loc.libelle).toContain('Quimper');
    expect(loc.geoX).toBe(orga.aenVil!.vilGeoX);
    expect(loc.placeName).toBe(orga.aenLibelle);
  });

  it('falls back to stage address when flag is 1 but no organiser', () => {
    const stage = makeStage({fstAdresseorganisateur: 1});
    stage.fstEve.aenOrganisateurs = [];

    const loc = resolveStageLocation(stage);

    expect(loc.source).toBe('stage');
  });
});

describe('resolveSessionLocation', () => {
  it('uses session own location when fssAdressestage is 0', () => {
    const session = makeSession({
      fssAdressestage: 0,
      fssVil: ville,
      fssPla: place,
    });

    const loc = resolveSessionLocation(session, makeStage());

    expect(loc.source).toBe('session');
    expect(loc.geoX).toBe(place.plaGeoX);
  });

  it('falls back to stage location when fssAdressestage is 1', () => {
    const session = makeSession({fssAdressestage: 1});
    const stage = makeStage({fstAdresseorganisateur: 0});

    const loc = resolveSessionLocation(session, stage);

    expect(loc.source).toBe('stage');
    expect(loc.geoX).toBe(place.plaGeoX);
  });

  it('cascades to organiser when session inherits from stage that inherits from orga', () => {
    const session = makeSession({fssAdressestage: 1});
    const stage = makeStage({fstAdresseorganisateur: 1});

    const loc = resolveSessionLocation(session, stage);

    expect(loc.source).toBe('organiser');
    expect(loc.geoX).toBe(orga.aenVil!.vilGeoX);
  });
});
