import { expect, test } from 'vitest'
import { TokenDictionary } from '../src/dictionary'
import { addNegativeTokens } from '../src/middleware'

test('should add negative spacing', () => {
  const dictionary = new TokenDictionary({
    tokens: {
      spacing: {
        sm: { value: '40px' },
      },
    },
  })

  dictionary.registerTokens()
  dictionary.registerMiddleware(addNegativeTokens).build()

  expect(dictionary.allTokens).toMatchInlineSnapshot(`
    [
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "prop": "sm",
        },
        "name": "spacing.sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "sm",
        ],
        "type": "dimension",
        "value": "40px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "isNegative": true,
          "originalPath": [
            "spacing",
            "sm",
          ],
          "prop": "-sm",
        },
        "name": "spacing.-sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "-sm",
        ],
        "type": "dimension",
        "value": "calc(var(--spacing-sm) * -1)",
      },
    ]
  `)
})

test('with semantic spacing', () => {
  const dictionary = new TokenDictionary({
    tokens: {
      spacing: {
        sm: { value: '40px' },
      },
    },
    semanticTokens: {
      spacing: {
        gutter: {
          value: { base: 'token(spacing.sm)', '@small': '0.5rem' },
        },
      },
    },
  })

  dictionary.registerTokens()
  dictionary.registerMiddleware(addNegativeTokens)
  dictionary.build()

  expect(dictionary.allTokens).toMatchInlineSnapshot(`
    [
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "prop": "sm",
        },
        "name": "spacing.sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "sm",
        ],
        "type": "dimension",
        "value": "40px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "conditions": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
          "prop": "gutter",
          "rawValue": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
        },
        "name": "spacing.gutter",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "gutter",
        ],
        "type": "dimension",
        "value": "40px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "isNegative": true,
          "originalPath": [
            "spacing",
            "sm",
          ],
          "prop": "-sm",
        },
        "name": "spacing.-sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "-sm",
        ],
        "type": "dimension",
        "value": "calc(var(--spacing-sm) * -1)",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "conditions": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
          "isNegative": true,
          "originalPath": [
            "spacing",
            "gutter",
          ],
          "prop": "-gutter",
          "rawValue": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
        },
        "name": "spacing.-gutter",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "-gutter",
        ],
        "type": "dimension",
        "value": "calc(var(--spacing-gutter) * -1)",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "@small",
          "conditions": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
          "prop": "gutter",
          "rawValue": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
        },
        "name": "spacing.gutter",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "gutter",
        ],
        "type": "dimension",
        "value": "0.5rem",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "@small",
          "conditions": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
          "isNegative": true,
          "originalPath": [
            "spacing",
            "gutter",
          ],
          "prop": "-gutter",
          "rawValue": {
            "@small": "0.5rem",
            "base": "token(spacing.sm)",
          },
        },
        "name": "spacing.-gutter",
        "originalValue": "calc(var(--spacing-gutter) * -1)",
        "path": [
          "spacing",
          "-gutter",
        ],
        "type": "dimension",
        "value": "0.5rem",
      },
    ]
  `)
})

test('with semantic spacing', () => {
  const dictionary = new TokenDictionary({
    tokens: {
      spacing: {
        sm: { value: '40px' },
      },
    },
    semanticTokens: {
      spacing: {
        nested: { value: { base: 'token(spacing.sm)', sm: '50px' } },
      },
    },
  })

  dictionary.registerTokens()
  dictionary.registerMiddleware(addNegativeTokens)
  dictionary.build()

  expect(dictionary.allTokens).toMatchInlineSnapshot(`
    [
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "prop": "sm",
        },
        "name": "spacing.sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "sm",
        ],
        "type": "dimension",
        "value": "40px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "conditions": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
          "prop": "nested",
          "rawValue": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
        },
        "name": "spacing.nested",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "nested",
        ],
        "type": "dimension",
        "value": "40px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "isNegative": true,
          "originalPath": [
            "spacing",
            "sm",
          ],
          "prop": "-sm",
        },
        "name": "spacing.-sm",
        "originalValue": "40px",
        "path": [
          "spacing",
          "-sm",
        ],
        "type": "dimension",
        "value": "calc(var(--spacing-sm) * -1)",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "base",
          "conditions": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
          "isNegative": true,
          "originalPath": [
            "spacing",
            "nested",
          ],
          "prop": "-nested",
          "rawValue": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
        },
        "name": "spacing.-nested",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "-nested",
        ],
        "type": "dimension",
        "value": "calc(var(--spacing-nested) * -1)",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "sm",
          "conditions": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
          "prop": "nested",
          "rawValue": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
        },
        "name": "spacing.nested",
        "originalValue": "token(spacing.sm)",
        "path": [
          "spacing",
          "nested",
        ],
        "type": "dimension",
        "value": "50px",
      },
      Token {
        "deprecated": undefined,
        "description": undefined,
        "extensions": {
          "category": "spacing",
          "condition": "sm",
          "conditions": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
          "isNegative": true,
          "originalPath": [
            "spacing",
            "nested",
          ],
          "prop": "-nested",
          "rawValue": {
            "base": "token(spacing.sm)",
            "sm": "50px",
          },
        },
        "name": "spacing.-nested",
        "originalValue": "calc(var(--spacing-nested) * -1)",
        "path": [
          "spacing",
          "-nested",
        ],
        "type": "dimension",
        "value": "50px",
      },
    ]
  `)
})
