import { describe, it, expect } from 'vitest';
import {
  PAGE_IDS,
  ROUTES,
  pathFor,
  pageIdFromPath,
  localeFromPath,
  twinPath,
  allRoutes,
} from '@i18n/slugMap';
import { LOCALES } from '@i18n/locales';

describe('slug map contract (ROUTING_SPEC §1, ARCHITECTURE A5)', () => {
  it('every pageId has a path in both locales', () => {
    for (const id of PAGE_IDS) {
      for (const locale of LOCALES) {
        const p = ROUTES[id][locale];
        expect(p, `${id}.${locale}`).toMatch(/^\/.*\/$|^\/$/); // trailing slash canonical
      }
    }
  });

  it('all paths are unique (bijection — no two routes collide)', () => {
    const paths = allRoutes().map((r) => r.path);
    expect(new Set(paths).size).toBe(paths.length);
  });

  it('NO paths are prefixed with /no and use localised slugs', () => {
    for (const id of PAGE_IDS) {
      expect(ROUTES[id].no.startsWith('/no/') || ROUTES[id].no === '/no/').toBe(true);
    }
    expect(ROUTES.projects.no).toBe('/no/prosjekter/');
    expect(ROUTES.homelab.no).toBe('/no/prosjekter/hjemmelab/');
    expect(ROUTES.about.no).toBe('/no/om-meg/');
  });

  it('pageIdFromPath round-trips for every route', () => {
    for (const id of PAGE_IDS) {
      for (const locale of LOCALES) {
        expect(pageIdFromPath(pathFor(id, locale))).toBe(id);
      }
    }
  });

  it('localeFromPath detects the locale', () => {
    expect(localeFromPath('/projects/jobtrack/')).toBe('en');
    expect(localeFromPath('/no/prosjekter/jobtrack/')).toBe('no');
    expect(localeFromPath('/')).toBe('en');
    expect(localeFromPath('/no/')).toBe('no');
  });

  it('twinPath maps a page to its twin locale and back', () => {
    for (const id of PAGE_IDS) {
      const en = pathFor(id, 'en');
      const no = pathFor(id, 'no');
      expect(twinPath(en, 'no')).toBe(no);
      expect(twinPath(no, 'en')).toBe(en);
    }
  });

  it('twinPath falls back to the target home for unmapped paths', () => {
    expect(twinPath('/nonsense/', 'no')).toBe('/no/');
    expect(twinPath('/no/tull/', 'en')).toBe('/');
  });
});
