import { describe, expect, it } from 'vitest'
import {
  ORGANIZATION_MODEL_ICON_TOKENS,
  OrganizationModelBuiltinIconTokenSchema,
  OrganizationModelIconTokenSchema
} from '../icons'
import { IconNameSchema } from '../domains/shared'

describe('OrganizationModelIconTokenSchema', () => {
  it('accepts built-in semantic icon tokens', () => {
    for (const token of ORGANIZATION_MODEL_ICON_TOKENS) {
      expect(OrganizationModelBuiltinIconTokenSchema.parse(token)).toBe(token)
      expect(OrganizationModelIconTokenSchema.parse(token)).toBe(token)
    }
  })

  it('accepts custom extension icon tokens', () => {
    expect(OrganizationModelIconTokenSchema.parse('custom.partner-portal')).toBe('custom.partner-portal')
    expect(IconNameSchema.parse('custom.acme.ops_queue')).toBe('custom.acme.ops_queue')
  })

  it('rejects random strings outside the built-in and custom namespaces', () => {
    for (const token of [
      'nav.crm',
      'feature.sales',
      'surface.dashboard',
      'action.approve',
      'status.success',
      'random.icon',
      'custom.',
      'custom.Bad'
    ]) {
      expect(OrganizationModelIconTokenSchema.safeParse(token).success).toBe(false)
    }
  })

  // max-length — CustomIconTokenSchema allows at most 80 characters
  it('rejects custom token exceeding 80 characters', () => {
    // 'custom.' is 7 chars; pad with 'a' so total = 81
    const token = 'custom.' + 'a'.repeat(74)
    expect(token.length).toBe(81)
    expect(OrganizationModelIconTokenSchema.safeParse(token).success).toBe(false)
  })

  it('accepts custom token at exactly 80 characters', () => {
    // 'custom.' = 7 chars, fill rest with 'a' to reach exactly 80
    const token = 'custom.' + 'a'.repeat(73)
    expect(token.length).toBe(80)
    expect(OrganizationModelIconTokenSchema.safeParse(token).success).toBe(true)
  })

  // invalid charset — custom token regex only allows [a-z0-9] with [-._] separators
  it('rejects custom token with uppercase letters in the suffix', () => {
    expect(OrganizationModelIconTokenSchema.safeParse('custom.MyIcon').success).toBe(false)
  })

  it('rejects custom token with spaces', () => {
    expect(OrganizationModelIconTokenSchema.safeParse('custom.my icon').success).toBe(false)
  })

  it('rejects custom token with a leading separator (double-dot)', () => {
    expect(OrganizationModelIconTokenSchema.safeParse('custom..icon').success).toBe(false)
  })

  it('rejects custom token with a trailing separator', () => {
    expect(OrganizationModelIconTokenSchema.safeParse('custom.icon-').success).toBe(false)
  })

  // missing prefix — tokens without the 'custom.' prefix that are not built-ins
  it('rejects token that looks like a custom slug but lacks the custom. prefix', () => {
    expect(OrganizationModelIconTokenSchema.safeParse('my-icon').success).toBe(false)
    expect(OrganizationModelIconTokenSchema.safeParse('org.my-icon').success).toBe(false)
  })
})

// ---------------------------------------------------------------------------
// OrganizationModelBuiltinIconTokenSchema — only accepts built-ins
// ---------------------------------------------------------------------------

describe('OrganizationModelBuiltinIconTokenSchema', () => {
  it('accepts every entry in ORGANIZATION_MODEL_ICON_TOKENS', () => {
    for (const token of ORGANIZATION_MODEL_ICON_TOKENS) {
      expect(OrganizationModelBuiltinIconTokenSchema.safeParse(token).success).toBe(true)
    }
  })

  it('rejects custom.* tokens (only built-ins allowed)', () => {
    expect(OrganizationModelBuiltinIconTokenSchema.safeParse('custom.my-icon').success).toBe(false)
    expect(OrganizationModelBuiltinIconTokenSchema.safeParse('custom.partner-portal').success).toBe(false)
  })

  it('rejects arbitrary strings not in the enum', () => {
    expect(OrganizationModelBuiltinIconTokenSchema.safeParse('book').success).toBe(false)
    expect(OrganizationModelBuiltinIconTokenSchema.safeParse('').success).toBe(false)
    expect(OrganizationModelBuiltinIconTokenSchema.safeParse('nav.unknown-item').success).toBe(false)
  })
})
