import { existsSync, readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { TIMEZONES, nearestTimezone, timezoneLabel } from './timezones';

// The server ships as its own source archive, so it is absent from a
// client-only checkout. Where both halves sit side by side (the development
// tree) the list-sync check below runs; where they don't, it skips rather
// than failing on a file that was never meant to be there.
//
// The two cases are told apart deliberately: a MISSING SERVER DIRECTORY means
// a client-only checkout, so skip. A server directory that exists but does not
// contain the file means the path above is WRONG, so fail loudly. A plain
// existsSync on the file alone would silently downgrade a broken path to a
// skip — which is exactly what happened when the server's modules moved into
// utilities/ and this check quietly stopped running.
const SERVER_DIR = fileURLToPath(new URL('../../../../CambiumServer', import.meta.url));
const SERVER_TIMEZONE_LIST = fileURLToPath(
  new URL('../../../../CambiumServer/utilities/timezones.py', import.meta.url)
);
const HAVE_SERVER = existsSync(SERVER_DIR);

describe('nearestTimezone', () => {
  it('returns list members unchanged', () => {
    expect(nearestTimezone('Asia/Tokyo')).toBe('Asia/Tokyo');
    expect(nearestTimezone('UTC')).toBe('UTC');
  });

  it('maps non-list zones to the same-offset list entry', () => {
    // Same offset year-round as their targets (both shift DST together).
    expect(nearestTimezone('Europe/Berlin')).toBe('Europe/Paris');
    expect(nearestTimezone('Asia/Seoul')).toBe('Asia/Tokyo');
    expect(nearestTimezone('America/Vancouver')).toBe('America/Los_Angeles');
  });

  it('falls back to UTC for unknown or empty input', () => {
    expect(nearestTimezone('Not/AZone')).toBe('UTC');
    expect(nearestTimezone('')).toBe('UTC');
    expect(nearestTimezone(null)).toBe('UTC');
    expect(nearestTimezone(undefined)).toBe('UTC');
  });
});

describe('timezoneLabel', () => {
  it('replaces underscores for display', () => {
    expect(timezoneLabel('America/Los_Angeles')).toBe('America/Los Angeles');
  });
});

describe('list sync with the server', () => {
  // Order matters as much as membership: the picker renders these in list
  // order, and a zone the client offers but the server rejects is a login
  // that fails with no explanation.
  it.skipIf(!HAVE_SERVER)(
    'matches the server timezone list exactly (values and order)',
    () => {
      expect(
        existsSync(SERVER_TIMEZONE_LIST),
        `the server is present but ${SERVER_TIMEZONE_LIST} is not — this path is stale`
      ).toBe(true);
      const py = readFileSync(SERVER_TIMEZONE_LIST, 'utf-8');
      const pyList = [...py.matchAll(/^ {4}"([^"]+)",$/gm)].map((m) => m[1]);
      expect(pyList).toEqual(TIMEZONES);
    }
  );
});
