import { describe, expect, it } from 'vitest';
import { readFileSync, existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { loadTokens } from '../index.js';

const __dirname = dirname(fileURLToPath(import.meta.url));
const generatedDir = resolve(__dirname, '../../generated');

describe('loadTokens', () => {
  it('returns a valid DesignTokens object', () => {
    const tokens = loadTokens();
    expect(tokens).toBeDefined();
    expect(tokens.meta).toBeDefined();
    expect(tokens.meta.name).toBeTruthy();
    expect(tokens.meta.version).toBeTruthy();
  });

  it('has color palette with expected keys', () => {
    const tokens = loadTokens();
    expect(tokens.color).toBeDefined();
    expect(tokens.color.palette).toBeDefined();
    expect(tokens.color.semantic).toBeDefined();
    expect(tokens.color.semantic.dark).toBeDefined();
    expect(tokens.color.brain).toBeDefined();
  });

  it('has typography with font families', () => {
    const tokens = loadTokens();
    expect(tokens.typography.fontFamily).toBeDefined();
    expect(Object.keys(tokens.typography.fontFamily).length).toBeGreaterThan(0);
  });

  it('has spacing values on 4pt grid', () => {
    const tokens = loadTokens();
    expect(tokens.spacing).toBeDefined();
    // All spacing values should be multiples of 4
    for (const [, value] of Object.entries(tokens.spacing)) {
      expect(value % 4).toBe(0);
    }
  });

  it('has radius values', () => {
    const tokens = loadTokens();
    expect(tokens.radius).toBeDefined();
    expect(Object.keys(tokens.radius).length).toBeGreaterThan(0);
  });

  it('has motion durations and easings', () => {
    const tokens = loadTokens();
    expect(tokens.motion).toBeDefined();
    expect(tokens.motion.duration).toBeDefined();
    expect(tokens.motion.easing).toBeDefined();
  });

  it('caches after first load', () => {
    const t1 = loadTokens();
    const t2 = loadTokens();
    expect(t1).toBe(t2);
  });
});

describe('generated files', () => {
  it('tokens.css exists and contains --ml- properties', () => {
    const cssPath = resolve(generatedDir, 'tokens.css');
    expect(existsSync(cssPath)).toBe(true);
    const css = readFileSync(cssPath, 'utf-8');
    expect(css).toContain('--ml-');
  });

  it('tokens.ts exists and exports token values', () => {
    const tsPath = resolve(generatedDir, 'tokens.ts');
    expect(existsSync(tsPath)).toBe(true);
    const ts = readFileSync(tsPath, 'utf-8');
    expect(ts).toContain('export');
  });

  it('MindLystTokens.kt exists and contains object declaration', () => {
    const ktPath = resolve(generatedDir, 'MindLystTokens.kt');
    expect(existsSync(ktPath)).toBe(true);
    const kt = readFileSync(ktPath, 'utf-8');
    expect(kt).toContain('object MindLystTokens');
  });

  it('MindLystTheme.swift exists and contains struct', () => {
    const swiftPath = resolve(generatedDir, 'MindLystTheme.swift');
    expect(existsSync(swiftPath)).toBe(true);
    const swift = readFileSync(swiftPath, 'utf-8');
    expect(swift).toContain('MindLyst');
  });
});
