import { test } from '@japa/runner'
import { DataDomain, DomainEntity, DomainProperty, DomainAssociation } from '../../../../src/index.js'
import {
  addAutoField,
  addIdField,
  addEmailField,
  addPasswordField,
  addVersionField,
  addNameField,
  addDescriptionField,
  addStatusField,
  addOwnerField,
  addUpdatedByField,
  addCreatedAtField,
  addUpdatedAtField,
  addDeletedAtField,
  addIsDeletedField,
  addFirstNameField,
  addLastNameField,
  addPhoneField,
  addAvatarUrlField,
  addPublicUniqueNameField,
  addSkuField,
  addPriceField,
  addQuantityField,
  addWeightField,
  addImagesField,
  addCustomStatusField,
  addBooleanField,
  addSessionIdField,
  addExpiresAtField,
  addUnitPriceField,
  addCurrencyAmountField,
  addRecommendedFields,
} from '../../../../src/modeling/helpers/Intelisense.js'
import { SemanticType } from '../../../../src/modeling/Semantics.js'

function createTestEntity(): DomainEntity {
  const domain = new DataDomain({ key: 'test-domain', info: { name: 'Test Domain' } })
  const namespace = domain.addNamespace({ info: { name: 'TestNamespace' } })
  const model = namespace.addModel({ info: { name: 'TestModel' } })
  return model.addEntity({ info: { name: 'TestEntity' } })
}

test.group('addAutoField()', () => {
  test('throws error for unsupported auto field', ({ assert }) => {
    const entity = createTestEntity()
    assert.throws(() => addAutoField(entity, 'unsupported-field'), 'Unsupported auto field: unsupported-field')
  })

  test('adds id field when autoField is "id"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'id') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'id')
    assert.isTrue(field.primary)
  })

  test('adds email field when autoField is "email"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'email') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'email')
    assert.isTrue(field.required)
    assert.isTrue(field.index)
  })

  test('adds name field when autoField is "name"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'name') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'name')
  })

  test('adds description field when autoField is "description"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'description') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'description')
  })

  test('adds status field when autoField is "status"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'status') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'status')
    assert.deepEqual(field.schema?.enum, ['Active', 'Draft', 'Archived'])
  })

  test('adds version field when autoField is "version"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'version') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'version')
    assert.equal(field.type, 'number')
    assert.isTrue(field.readOnly)
  })

  test('adds owner field when autoField is "owner"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'owner') as DomainAssociation
    assert.instanceOf(field, DomainAssociation)
    assert.equal(field.info.name, 'owner')
    assert.isTrue(field.required)
  })

  test('adds created at field when autoField is "created"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'created') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'created_at')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
  })

  test('adds updated at field when autoField is "updated"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'updated') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'updated_at')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
  })

  test('adds updated by field when autoField is "updated-by"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'updated-by') as DomainAssociation
    assert.instanceOf(field, DomainAssociation)
    assert.equal(field.info.name, 'updated_by')
    assert.isTrue(field.required)
  })

  test('adds is deleted field when autoField is "is-deleted"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'is-deleted') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'is_deleted')
    assert.equal(field.type, 'boolean')
    assert.isTrue(field.readOnly)
  })

  test('adds deleted at field when autoField is "deleted"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'deleted') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'deleted_at')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
  })

  test('adds first name field when autoField is "first-name"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'first-name') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'first_name')
    assert.equal(field.type, 'string')
  })

  test('adds last name field when autoField is "last-name"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'last-name') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'last_name')
    assert.equal(field.type, 'string')
  })

  test('adds phone field when autoField is "phone"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'phone') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'phone')
    assert.equal(field.type, 'string')
    assert.isTrue(field.index)
  })

  test('adds avatar url field when autoField is "avatar-url"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'avatar-url') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'avatar_url')
    assert.equal(field.type, 'string')
  })

  test('adds public unique name field when autoField is "public-unique-name"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'public-unique-name') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'slug')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
    assert.isTrue(field.index)
  })

  test('adds price field when autoField is "price"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'price') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'price')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
  })

  test('adds sku field when autoField is "sku"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'sku') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'sku')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
  })

  test('adds quantity field when autoField is "quantity"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'quantity') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'quantity')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
  })

  test('adds weight field when autoField is "weight"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'weight') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'weight')
    assert.equal(field.type, 'number')
  })

  test('adds images field when autoField is "images"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'images') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'images')
    assert.equal(field.type, 'string')
    assert.isTrue(field.multiple)
  })

  test('adds session id field when autoField is "session-id"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'session-id') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'sessionId')
    assert.equal(field.type, 'string')
  })

  test('adds expires at field when autoField is "expires-at"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'expires-at') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'expiresAt')
    assert.equal(field.type, 'datetime')
  })

  test('adds unit price field when autoField is "unit-price"', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAutoField(entity, 'unit-price') as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'unitPrice')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
  })
})

test.group('addIdField()', () => {
  test('creates new id field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addIdField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'id')
    assert.equal(field.type, 'string')
    assert.isTrue(field.primary)
    assert.isTrue(field.readOnly)
    assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'uuid-v4' })
  })

  test('returns existing id field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addIdField(entity) as DomainProperty
    const secondField = addIdField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.equal([...entity.properties].length, 1)
  })

  test('merges custom info with defaults', ({ assert }) => {
    const entity = createTestEntity()
    const field = addIdField(entity, { displayName: 'Unique Identifier' }) as DomainProperty
    assert.equal(field.info.name, 'id')
    assert.equal(field.info.displayName, 'Unique Identifier')
  })
})

test.group('addEmailField()', () => {
  test('creates new email field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addEmailField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'email')
    assert.equal(field.info.displayName, 'Email Address')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
    assert.isTrue(field.index)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing email field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addEmailField(entity) as DomainProperty
    const secondField = addEmailField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })

  test('merges custom info with defaults', ({ assert }) => {
    const entity = createTestEntity()
    const field = addEmailField(entity, { description: 'User email address' }) as DomainProperty
    assert.equal(field.info.name, 'email')
    assert.equal(field.info.description, 'User email address')
  })
})

test.group('addPasswordField()', () => {
  test('creates new password field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addPasswordField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'password')
    assert.equal(field.info.displayName, 'Password')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing password field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addPasswordField(entity) as DomainProperty
    const secondField = addPasswordField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })

  test('merges custom info with defaults', ({ assert }) => {
    const entity = createTestEntity()
    const field = addPasswordField(entity, { description: 'User password hash' }) as DomainProperty
    assert.equal(field.info.name, 'password')
    assert.equal(field.info.description, 'User password hash')
  })
})

test.group('addVersionField()', () => {
  test('creates new version field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addVersionField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'version')
    assert.equal(field.info.displayName, 'Version')
    assert.equal(field.type, 'number')
    assert.isTrue(field.readOnly)
    assert.isTrue(field.index)
    assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'incremental' })
    assert.equal(field.schema?.minimum, 0)
  })

  test('returns existing version field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addVersionField(entity) as DomainProperty
    const secondField = addVersionField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })

  test('adds semantic annotation', ({ assert }) => {
    const entity = createTestEntity()
    const field = addVersionField(entity) as DomainProperty
    const hasSemantic = field.hasSemantic(SemanticType.Version)
    assert.isTrue(hasSemantic)
  })
})

test.group('addNameField()', () => {
  test('creates new name field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addNameField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'name')
    assert.equal(field.info.displayName, 'Name')
    assert.equal(field.type, 'string')
  })

  test('returns existing name field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addNameField(entity) as DomainProperty
    const secondField = addNameField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })

  test('adds semantic annotation', ({ assert }) => {
    const entity = createTestEntity()
    const field = addNameField(entity) as DomainProperty
    const hasSemantic = field.hasSemantic(SemanticType.Title)
    assert.isTrue(hasSemantic)
  })
})

test.group('addDescriptionField()', () => {
  test('creates new description field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addDescriptionField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'description')
    assert.equal(field.info.displayName, 'Description')
    assert.equal(field.type, 'string')
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing description field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addDescriptionField(entity) as DomainProperty
    const secondField = addDescriptionField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addStatusField()', () => {
  test('creates new status field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addStatusField(entity) as DomainProperty
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'status')
    assert.equal(field.info.displayName, 'Status')
    assert.equal(field.type, 'string')
    assert.deepEqual(field.schema?.enum, ['Active', 'Draft', 'Archived'])
    assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'Draft' })
  })

  test('returns existing status field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addStatusField(entity) as DomainProperty
    const secondField = addStatusField(entity) as DomainProperty
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })

  test('adds semantic annotation', ({ assert }) => {
    const entity = createTestEntity()
    const field = addStatusField(entity) as DomainProperty
    const hasSemantic = field.hasSemantic(SemanticType.Status)
    assert.isTrue(hasSemantic)
  })
})

test.group('addOwnerField()', () => {
  test('creates new owner association when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addOwnerField(entity) as DomainAssociation
    assert.instanceOf(field, DomainAssociation)
    assert.equal(field.info.name, 'owner')
    assert.equal(field.info.displayName, 'Owner')
    assert.isTrue(field.required)
  })

  test('returns existing owner field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addOwnerField(entity)
    const secondField = addOwnerField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.associations], 1)
  })

  test('adds semantic annotation', ({ assert }) => {
    const entity = createTestEntity()
    const field = addOwnerField(entity)
    const hasSemantic = field.hasSemantic(SemanticType.ResourceOwnerIdentifier)
    assert.isTrue(hasSemantic)
  })
})

test.group('addUpdatedByField()', () => {
  test('creates new updated by association when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addUpdatedByField(entity)
    assert.instanceOf(field, DomainAssociation)
    assert.equal(field.info.name, 'updated_by')
    assert.equal(field.info.displayName, 'Updated By')
    assert.isTrue(field.required)
  })

  test('returns existing updated by field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addUpdatedByField(entity)
    const secondField = addUpdatedByField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.associations], 1)
  })

  test('adds semantic annotation', ({ assert }) => {
    const entity = createTestEntity()
    const field = addUpdatedByField(entity)
    const hasSemantic = field.hasSemantic(SemanticType.ResourceOwnerIdentifier)
    assert.isTrue(hasSemantic)
  })
})

test.group('addCreatedAtField()', () => {
  test('creates new created at field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addCreatedAtField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'created_at')
    assert.equal(field.info.displayName, 'Created At')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
    assert.isTrue(field.index)
    assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
  })

  test('returns existing created at field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addCreatedAtField(entity)
    const secondField = addCreatedAtField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addUpdatedAtField()', () => {
  test('creates new updated at field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addUpdatedAtField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'updated_at')
    assert.equal(field.info.displayName, 'Updated At')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
    assert.isTrue(field.index)
    assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
  })

  test('returns existing updated at field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addUpdatedAtField(entity)
    const secondField = addUpdatedAtField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addDeletedAtField()', () => {
  test('creates new deleted at field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addDeletedAtField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'deleted_at')
    assert.equal(field.info.displayName, 'Deleted At')
    assert.equal(field.type, 'datetime')
    assert.isTrue(field.readOnly)
    assert.isTrue(field.index)
    assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
  })

  test('returns existing deleted at field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addDeletedAtField(entity)
    const secondField = addDeletedAtField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addIsDeletedField()', () => {
  test('creates new is deleted field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addIsDeletedField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'is_deleted')
    assert.equal(field.info.displayName, 'Is Deleted')
    assert.equal(field.type, 'boolean')
    assert.isTrue(field.readOnly)
    assert.isTrue(field.index)
    assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'false' })
  })

  test('returns existing is deleted field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addIsDeletedField(entity)
    const secondField = addIsDeletedField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addFirstNameField()', () => {
  test('creates new first name field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addFirstNameField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'first_name')
    assert.equal(field.info.displayName, 'First Name')
    assert.equal(field.type, 'string')
  })

  test('returns existing first name field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addFirstNameField(entity)
    const secondField = addFirstNameField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addLastNameField()', () => {
  test('creates new last name field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addLastNameField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'last_name')
    assert.equal(field.info.displayName, 'Last Name')
    assert.equal(field.type, 'string')
  })

  test('returns existing last name field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addLastNameField(entity)
    const secondField = addLastNameField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addPhoneField()', () => {
  test('creates new phone field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addPhoneField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'phone')
    assert.equal(field.info.displayName, 'Phone Number')
    assert.equal(field.type, 'string')
    assert.isTrue(field.index)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing phone field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addPhoneField(entity)
    const secondField = addPhoneField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addAvatarUrlField()', () => {
  test('creates new avatar url field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addAvatarUrlField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'avatar_url')
    assert.equal(field.info.displayName, 'Avatar URL')
    assert.equal(field.type, 'string')
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing avatar url field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addAvatarUrlField(entity)
    const secondField = addAvatarUrlField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addPublicUniqueNameField()', () => {
  test('creates new public unique name field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addPublicUniqueNameField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'slug')
    assert.equal(field.info.displayName, 'Public Unique Name')
    assert.equal(field.type, 'string')
    assert.isTrue(field.index)
    assert.isTrue(field.required)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing public unique name field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addPublicUniqueNameField(entity)
    const secondField = addPublicUniqueNameField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addSkuField()', () => {
  test('creates new sku field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addSkuField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'sku')
    assert.equal(field.info.displayName, 'SKU')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing sku field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addSkuField(entity)
    const secondField = addSkuField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addPriceField()', () => {
  test('creates new price field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addPriceField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'price')
    assert.equal(field.info.displayName, 'Price')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
    assert.isUndefined(field.schema?.minimum)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing price field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addPriceField(entity)
    const secondField = addPriceField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addQuantityField()', () => {
  test('creates new quantity field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addQuantityField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'quantity')
    assert.equal(field.info.displayName, 'Quantity')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
    assert.equal(field.schema?.minimum, 0)
  })

  test('returns existing quantity field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addQuantityField(entity)
    const secondField = addQuantityField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addWeightField()', () => {
  test('creates new weight field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addWeightField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'weight')
    assert.equal(field.info.displayName, 'Weight')
    assert.equal(field.type, 'number')
  })

  test('returns existing weight field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addWeightField(entity)
    const secondField = addWeightField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addImagesField()', () => {
  test('creates new images field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addImagesField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'images')
    assert.equal(field.info.displayName, 'Images')
    assert.equal(field.type, 'string')
    assert.isTrue(field.multiple)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing images field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addImagesField(entity)
    const secondField = addImagesField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addCustomStatusField()', () => {
  test('creates new custom status field with provided enum values', ({ assert }) => {
    const entity = createTestEntity()
    const enumValues = ['Pending', 'In Progress', 'Completed', 'Cancelled']
    const field = addCustomStatusField(entity, enumValues)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'status')
    assert.equal(field.info.displayName, 'Status')
    assert.equal(field.type, 'string')
    assert.isTrue(field.required)
    assert.deepEqual(field.schema?.enum, enumValues)
    assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: enumValues[0] })
  })

  test('returns existing status field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const enumValues = ['Active', 'Inactive']
    const firstField = addCustomStatusField(entity, enumValues)
    const secondField = addCustomStatusField(entity, ['Different', 'Values'])
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addBooleanField()', () => {
  test('creates new boolean field with default value', ({ assert }) => {
    const entity = createTestEntity()
    const field = addBooleanField(entity, 'isActive')
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'isActive')
    assert.equal(field.type, 'boolean')
    assert.isTrue(field.required)
    assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'false' })
  })

  test('creates new boolean field with custom default value', ({ assert }) => {
    const entity = createTestEntity()
    const field = addBooleanField(entity, 'isEnabled', 'true')
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'isEnabled')
    assert.equal(field.type, 'boolean')
    assert.isTrue(field.required)
    assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'true' })
  })

  test('merges custom info with defaults', ({ assert }) => {
    const entity = createTestEntity()
    const field = addBooleanField(entity, 'isVisible', 'false', { displayName: 'Visible' })
    assert.equal(field.info.name, 'isVisible')
    assert.equal(field.info.displayName, 'Visible')
  })
})

test.group('addSessionIdField()', () => {
  test('creates new session id field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addSessionIdField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'sessionId')
    assert.equal(field.info.displayName, 'Session ID')
    assert.equal(field.type, 'string')
  })

  test('returns existing session id field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addSessionIdField(entity)
    const secondField = addSessionIdField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addExpiresAtField()', () => {
  test('creates new expires at field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addExpiresAtField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'expiresAt')
    assert.equal(field.info.displayName, 'Expires At')
    assert.equal(field.type, 'datetime')
  })

  test('returns existing expires at field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addExpiresAtField(entity)
    const secondField = addExpiresAtField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addUnitPriceField()', () => {
  test('creates new unit price field when none exists', ({ assert }) => {
    const entity = createTestEntity()
    const field = addUnitPriceField(entity)
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'unitPrice')
    assert.equal(field.info.displayName, 'Unit Price')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
    assert.isTrue(field.semantics.length > 0)
  })

  test('returns existing unit price field when one exists', ({ assert }) => {
    const entity = createTestEntity()
    const firstField = addUnitPriceField(entity)
    const secondField = addUnitPriceField(entity)
    assert.equal(firstField, secondField)
    assert.lengthOf([...entity.properties], 1)
  })
})

test.group('addCurrencyAmountField()', () => {
  test('creates new currency amount field with provided parameters', ({ assert }) => {
    const entity = createTestEntity()
    const field = addCurrencyAmountField(entity, 'subtotal', 'Subtotal')
    assert.instanceOf(field, DomainProperty)
    assert.equal(field.info.name, 'subtotal')
    assert.equal(field.info.displayName, 'Subtotal')
    assert.equal(field.type, 'number')
    assert.isTrue(field.required)
    assert.isTrue(field.semantics.length > 0)
  })

  test('merges custom info with defaults', ({ assert }) => {
    const entity = createTestEntity()
    const field = addCurrencyAmountField(entity, 'tax', 'Tax Amount', { description: 'Tax calculation' })
    assert.equal(field.info.name, 'tax')
    assert.equal(field.info.displayName, 'Tax Amount')
    assert.equal(field.info.description, 'Tax calculation')
  })
})

test.group('addRecommendedFields()', () => {
  test('adds multiple recommended fields to entity', ({ assert }) => {
    const entity = createTestEntity()
    const fields = addRecommendedFields(entity)
    assert.isArray(fields)
    assert.isAtLeast(fields.length, 3) // Should add at least id, created_at, updated_at

    // Check that ID field was added
    const idField = [...entity.properties].find((p) => p.info.name === 'id')
    assert.isDefined(idField)
    assert.isTrue(idField?.primary)

    // Check that created_at field was added
    const createdAtField = [...entity.properties].find((p) => p.info.name === 'created_at')
    assert.isDefined(createdAtField)
    assert.equal(createdAtField?.type, 'datetime')

    // Check that updated_at field was added
    const updatedAtField = [...entity.properties].find((p) => p.info.name === 'updated_at')
    assert.isDefined(updatedAtField)
    assert.equal(updatedAtField?.type, 'datetime')
  })

  test('does not add duplicate fields when recommended fields already exist', ({ assert }) => {
    const entity = createTestEntity()

    // Add an ID field first
    addIdField(entity)
    const initialFieldCount = [...entity.properties].length

    // Add recommended fields
    addRecommendedFields(entity)

    // Should not have duplicated the ID field
    const idFields = [...entity.properties].filter((p) => p.info.name === 'id')
    assert.equal(idFields.length, 1)

    // But should have added other recommended fields
    assert.isAtLeast([...entity.properties].length, initialFieldCount + 1)
  })
})
