/**
 * IoT/Smart Home Domain Template
 *
 * A comprehensive IoT/Smart Home data domain following domain-driven design principles.
 * This template covers the complete IoT ecosystem lifecycle including:
 *
 * - Device Management: Devices, sensors, connectivity, firmware
 * - Data Collection: Sensor data, telemetry, analytics
 * - Automation: Rules, triggers, actions, schedules
 * - User Management: Users, permissions, device access
 * - Monitoring: Alerts, notifications, health status
 * - Integration: Third-party services, APIs, protocols
 *
 * Key Features:
 * - Complete device lifecycle management
 * - Real-time data collection and analytics
 * - Smart automation and rules engine
 * - User access and permission management
 * - System monitoring and alerting
 * - Third-party service integration
 * - IoT ecosystem management
 *
 * Use Cases:
 * - Smart home systems
 * - IoT device management
 * - Home automation
 * - Sensor data analytics
 * - Device monitoring and maintenance
 * - User access control
 * - Third-party integrations
 */

import { DataDomain } from '../../../DataDomain.js'
import {
  addIdField,
  addNameField,
  addDescriptionField,
  addEmailField,
  addPhoneField,
  addCustomStatusField,
  addCreatedAtField,
  addUpdatedAtField,
} from '../../../helpers/Intelisense.js'
import { SemanticType } from '../../../Semantics.js'
import type { CreateTemplateOptions } from '../../types.js'

function createDomain(): DataDomain {
  return new DataDomain({
    info: {
      name: 'IoT Smart Home Platform',
      displayName: 'IoT Smart Home Platform',
      description:
        'A comprehensive IoT/Smart Home platform with device management, data collection, ' +
        'automation, user management, monitoring, and integration',
    },
  })
}

/**
 * Creates a comprehensive IoT/Smart Home data domain following domain-driven design principles.
 *
 * This function demonstrates the proper hierarchy and organization for an IoT/Smart Home platform:
 * 1. Creates the root DataDomain for the IoT/Smart Home platform
 * 2. Organizes functionality into logical namespaces (Device Management, Data Collection, etc.)
 * 3. Groups related entities into models within each namespace
 * 4. Defines entities with proper semantic annotations for IoT workflows
 * 5. Establishes associations with appropriate cardinality for IoT relationships
 *
 * @returns A fully configured DataDomain with all IoT/Smart Home entities and relationships
 */
export default function createIoTSmartHomeDomain(options: CreateTemplateOptions = {}): DataDomain {
  // Ensure the root data domain
  const domain = options.domain ?? createDomain()

  //
  // 1. DEVICE MANAGEMENT NAMESPACE
  //
  const deviceManagement = domain.addNamespace({
    info: {
      name: 'DeviceManagement',
      displayName: 'Device Management',
      description: 'Devices, sensors, connectivity, and firmware',
    },
  })

  // Device Model
  const deviceModel = deviceManagement.addModel({
    info: {
      name: 'Devices',
      displayName: 'Device Management',
      description: 'IoT devices and sensors',
    },
  })

  // Device Entity
  const deviceEntity = deviceModel.addEntity({
    info: {
      name: 'device',
      displayName: 'Device',
      description: 'IoT device with sensors and capabilities',
    },
  })

  addIdField(deviceEntity, { displayName: 'Device ID', description: 'Unique identifier for the device' })

  addNameField(deviceEntity, { description: 'Device name and model' })

  addDescriptionField(deviceEntity, { description: 'Device description and capabilities' })

  deviceEntity.addProperty({
    info: { name: 'device_type', displayName: 'Device Type', description: 'Type of IoT device' },
    type: 'string',
    required: true,
    schema: {
      enum: [
        'sensor',
        'actuator',
        'controller',
        'gateway',
        'camera',
        'thermostat',
        'light',
        'lock',
        'appliance',
        'speaker',
      ],
    },
  })

  deviceEntity.addProperty({
    info: { name: 'manufacturer', displayName: 'Manufacturer', description: 'Device manufacturer' },
    type: 'string',
    required: true,
  })

  deviceEntity.addProperty({
    info: { name: 'model', displayName: 'Model', description: 'Device model' },
    type: 'string',
    required: true,
  })

  deviceEntity.addProperty({
    info: { name: 'serial_number', displayName: 'Serial Number', description: 'Device serial number' },
    type: 'string',
    required: true,
    unique: true,
  })

  deviceEntity.addProperty({
    info: { name: 'mac_address', displayName: 'MAC Address', description: 'Device MAC address' },
    type: 'string',
    required: true,
    unique: true,
  })

  deviceEntity.addProperty({
    info: { name: 'ip_address', displayName: 'IP Address', description: 'Device IP address' },
    type: 'string',
    required: false,
    semantics: [{ id: SemanticType.ClientIPAddress }],
  })

  deviceEntity.addProperty({
    info: { name: 'location', displayName: 'Location', description: 'Device location in home' },
    type: 'string',
    required: false,
  })

  deviceEntity.addProperty({
    info: { name: 'firmware_version', displayName: 'Firmware Version', description: 'Current firmware version' },
    type: 'string',
    required: true,
  })

  addCustomStatusField(deviceEntity, ['online', 'offline', 'maintenance', 'error', 'updating'], {
    displayName: 'Device Status',
    description: 'Current status of the device',
  })

  addCreatedAtField(deviceEntity, { description: 'When the device was created' })
  addUpdatedAtField(deviceEntity, { description: 'When the device was last updated' })

  // Sensor Entity
  const sensorEntity = deviceModel.addEntity({
    info: {
      name: 'sensor',
      displayName: 'Sensor',
      description: 'IoT sensor with measurement capabilities',
    },
  })

  addIdField(sensorEntity, { displayName: 'Sensor ID', description: 'Unique identifier for the sensor' })

  addNameField(sensorEntity, { description: 'Sensor name and type' })

  addDescriptionField(sensorEntity, { description: 'Sensor description and capabilities' })

  sensorEntity.addProperty({
    info: { name: 'sensor_type', displayName: 'Sensor Type', description: 'Type of sensor' },
    type: 'string',
    required: true,
    schema: {
      enum: [
        'temperature',
        'humidity',
        'pressure',
        'motion',
        'light',
        'sound',
        'air_quality',
        'water_level',
        'smoke',
        'carbon_monoxide',
      ],
    },
  })

  sensorEntity.addProperty({
    info: { name: 'measurement_unit', displayName: 'Measurement Unit', description: 'Unit of measurement' },
    type: 'string',
    required: true,
  })

  sensorEntity.addProperty({
    info: { name: 'min_value', displayName: 'Minimum Value', description: 'Minimum measurement value' },
    type: 'number',
    required: false,
  })

  sensorEntity.addProperty({
    info: { name: 'max_value', displayName: 'Maximum Value', description: 'Maximum measurement value' },
    type: 'number',
    required: false,
  })

  addCustomStatusField(sensorEntity, ['active', 'inactive', 'calibrating', 'error'], {
    displayName: 'Sensor Status',
    description: 'Current status of the sensor',
  })

  addCreatedAtField(sensorEntity, { description: 'When the sensor was created' })

  // Sensor-Device Association (Many-to-One)
  sensorEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this sensor' },
      required: true,
      multiple: false,
    }
  )

  // Firmware Entity
  const firmwareEntity = deviceModel.addEntity({
    info: {
      name: 'firmware',
      displayName: 'Firmware',
      description: 'Device firmware versions and updates',
    },
  })

  addIdField(firmwareEntity, { displayName: 'Firmware ID', description: 'Unique identifier for the firmware' })

  addNameField(firmwareEntity, { description: 'Firmware name and version' })

  addDescriptionField(firmwareEntity, { description: 'Firmware description and changes' })

  firmwareEntity.addProperty({
    info: { name: 'version', displayName: 'Version', description: 'Firmware version number' },
    type: 'string',
    required: true,
  })

  firmwareEntity.addProperty({
    info: { name: 'release_date', displayName: 'Release Date', description: 'Firmware release date' },
    type: 'date',
    required: true,
  })

  firmwareEntity.addProperty({
    info: { name: 'file_size', displayName: 'File Size', description: 'Firmware file size in bytes' },
    type: 'number',
    required: true,
    schema: {
      minimum: 0,
    },
  })

  firmwareEntity.addProperty({
    info: { name: 'compatibility', displayName: 'Compatibility', description: 'Compatible device models' },
    type: 'string',
    required: true,
  })

  addCustomStatusField(firmwareEntity, ['available', 'installing', 'installed', 'failed'], {
    displayName: 'Firmware Status',
    description: 'Current status of the firmware',
  })

  addCreatedAtField(firmwareEntity, { description: 'When the firmware was created' })

  // Firmware-Device Association (Many-to-One)
  firmwareEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this firmware' },
      required: true,
      multiple: false,
    }
  )

  //
  // 2. DATA COLLECTION NAMESPACE
  //
  const dataCollection = domain.addNamespace({
    info: {
      name: 'DataCollection',
      displayName: 'Data Collection',
      description: 'Sensor data, telemetry, and analytics',
    },
  })

  // Data Model
  const dataModel = dataCollection.addModel({
    info: {
      name: 'Data',
      displayName: 'Data Collection',
      description: 'Sensor data and telemetry',
    },
  })

  // Sensor Data Entity
  const sensorDataEntity = dataModel.addEntity({
    info: {
      name: 'sensor_data',
      displayName: 'Sensor Data',
      description: 'Sensor measurement data',
    },
  })

  addIdField(sensorDataEntity, { displayName: 'Data ID', description: 'Unique identifier for the sensor data' })

  addNameField(sensorDataEntity, { description: 'Data name and description' })

  sensorDataEntity.addProperty({
    info: { name: 'timestamp', displayName: 'Timestamp', description: 'Data timestamp' },
    type: 'datetime',
    required: true,
  })

  sensorDataEntity.addProperty({
    info: { name: 'value', displayName: 'Value', description: 'Sensor measurement value' },
    type: 'number',
    required: true,
  })

  sensorDataEntity.addProperty({
    info: { name: 'unit', displayName: 'Unit', description: 'Measurement unit' },
    type: 'string',
    required: true,
  })

  sensorDataEntity.addProperty({
    info: { name: 'quality', displayName: 'Quality', description: 'Data quality indicator' },
    type: 'string',
    required: true,
    schema: {
      enum: ['excellent', 'good', 'fair', 'poor'],
    },
  })

  addCustomStatusField(sensorDataEntity, ['raw', 'processed', 'archived'], {
    displayName: 'Data Status',
    description: 'Current status of the sensor data',
  })

  addCreatedAtField(sensorDataEntity, { description: 'When the data was created' })

  // SensorData-Sensor Association (Many-to-One)
  sensorDataEntity.addAssociation(
    { key: sensorEntity.key },
    {
      info: { name: 'sensor', displayName: 'Sensor', description: 'Sensor for this data' },
      required: true,
      multiple: false,
    }
  )

  // Telemetry Entity
  const telemetryEntity = dataModel.addEntity({
    info: {
      name: 'telemetry',
      displayName: 'Telemetry',
      description: 'Device telemetry and system metrics',
    },
  })

  addIdField(telemetryEntity, { displayName: 'Telemetry ID', description: 'Unique identifier for the telemetry' })

  addNameField(telemetryEntity, { description: 'Telemetry name and description' })

  telemetryEntity.addProperty({
    info: { name: 'timestamp', displayName: 'Timestamp', description: 'Telemetry timestamp' },
    type: 'datetime',
    required: true,
  })

  telemetryEntity.addProperty({
    info: { name: 'metric_type', displayName: 'Metric Type', description: 'Type of telemetry metric' },
    type: 'string',
    required: true,
    schema: {
      enum: ['cpu_usage', 'memory_usage', 'network_traffic', 'battery_level', 'signal_strength', 'temperature'],
    },
  })

  telemetryEntity.addProperty({
    info: { name: 'value', displayName: 'Value', description: 'Telemetry value' },
    type: 'number',
    required: true,
  })

  telemetryEntity.addProperty({
    info: { name: 'unit', displayName: 'Unit', description: 'Measurement unit' },
    type: 'string',
    required: true,
  })

  addCustomStatusField(telemetryEntity, ['normal', 'warning', 'critical'], {
    displayName: 'Telemetry Status',
    description: 'Current status of the telemetry',
  })

  addCreatedAtField(telemetryEntity, { description: 'When the telemetry was created' })

  // Telemetry-Device Association (Many-to-One)
  telemetryEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this telemetry' },
      required: true,
      multiple: false,
    }
  )

  // Analytics Entity
  const analyticsEntity = dataModel.addEntity({
    info: {
      name: 'analytics',
      displayName: 'Analytics',
      description: 'Data analytics and insights',
    },
  })

  addIdField(analyticsEntity, { displayName: 'Analytics ID', description: 'Unique identifier for the analytics' })

  addNameField(analyticsEntity, { description: 'Analytics name and description' })

  addDescriptionField(analyticsEntity, { description: 'Analytics description and insights' })

  analyticsEntity.addProperty({
    info: { name: 'analytics_type', displayName: 'Analytics Type', description: 'Type of analytics' },
    type: 'string',
    required: true,
    schema: {
      enum: ['trend_analysis', 'pattern_recognition', 'anomaly_detection', 'predictive_modeling', 'usage_statistics'],
    },
  })

  analyticsEntity.addProperty({
    info: { name: 'time_period', displayName: 'Time Period', description: 'Analytics time period' },
    type: 'string',
    required: true,
    schema: {
      enum: ['hourly', 'daily', 'weekly', 'monthly', 'yearly'],
    },
  })

  analyticsEntity.addProperty({
    info: { name: 'start_date', displayName: 'Start Date', description: 'Analytics start date' },
    type: 'date',
    required: true,
  })

  analyticsEntity.addProperty({
    info: { name: 'end_date', displayName: 'End Date', description: 'Analytics end date' },
    type: 'date',
    required: true,
  })

  addCustomStatusField(analyticsEntity, ['processing', 'completed', 'failed'], {
    displayName: 'Analytics Status',
    description: 'Current status of the analytics',
  })

  addCreatedAtField(analyticsEntity, { description: 'When the analytics was created' })

  //
  // 3. AUTOMATION NAMESPACE
  //
  const automation = domain.addNamespace({
    info: {
      name: 'Automation',
      displayName: 'Automation',
      description: 'Rules, triggers, actions, and schedules',
    },
  })

  // Automation Model
  const automationModel = automation.addModel({
    info: {
      name: 'Automation',
      displayName: 'Automation Management',
      description: 'Automation rules and schedules',
    },
  })

  // Rule Entity
  const ruleEntity = automationModel.addEntity({
    info: {
      name: 'rule',
      displayName: 'Rule',
      description: 'Automation rule with conditions and actions',
    },
  })

  addIdField(ruleEntity, { displayName: 'Rule ID', description: 'Unique identifier for the rule' })

  addNameField(ruleEntity, { description: 'Rule name and description' })

  addDescriptionField(ruleEntity, { description: 'Rule description and logic' })

  ruleEntity.addProperty({
    info: { name: 'rule_type', displayName: 'Rule Type', description: 'Type of automation rule' },
    type: 'string',
    required: true,
    schema: {
      enum: ['if_then', 'schedule', 'location_based', 'time_based', 'condition_based'],
    },
  })

  ruleEntity.addProperty({
    info: { name: 'condition', displayName: 'Condition', description: 'Rule condition logic' },
    type: 'string',
    required: true,
  })

  ruleEntity.addProperty({
    info: { name: 'action', displayName: 'Action', description: 'Rule action to execute' },
    type: 'string',
    required: true,
  })

  ruleEntity.addProperty({
    info: { name: 'priority', displayName: 'Priority', description: 'Rule priority level' },
    type: 'string',
    required: true,
    schema: {
      enum: ['low', 'medium', 'high', 'critical'],
    },
  })

  addCustomStatusField(ruleEntity, ['active', 'inactive', 'testing', 'error'], {
    displayName: 'Rule Status',
    description: 'Current status of the rule',
  })

  addCreatedAtField(ruleEntity, { description: 'When the rule was created' })

  // Trigger Entity
  const triggerEntity = automationModel.addEntity({
    info: {
      name: 'trigger',
      displayName: 'Trigger',
      description: 'Automation trigger event',
    },
  })

  addIdField(triggerEntity, { displayName: 'Trigger ID', description: 'Unique identifier for the trigger' })

  addNameField(triggerEntity, { description: 'Trigger name and description' })

  addDescriptionField(triggerEntity, { description: 'Trigger description and conditions' })

  triggerEntity.addProperty({
    info: { name: 'trigger_type', displayName: 'Trigger Type', description: 'Type of trigger' },
    type: 'string',
    required: true,
    schema: {
      enum: ['sensor_threshold', 'time_schedule', 'location_change', 'device_state', 'user_action'],
    },
  })

  triggerEntity.addProperty({
    info: { name: 'condition', displayName: 'Condition', description: 'Trigger condition' },
    type: 'string',
    required: true,
  })

  triggerEntity.addProperty({
    info: { name: 'frequency', displayName: 'Frequency', description: 'Trigger frequency' },
    type: 'string',
    required: false,
    schema: {
      enum: ['once', 'recurring', 'continuous'],
    },
  })

  addCustomStatusField(triggerEntity, ['active', 'inactive', 'paused'], {
    displayName: 'Trigger Status',
    description: 'Current status of the trigger',
  })

  addCreatedAtField(triggerEntity, { description: 'When the trigger was created' })

  // Trigger-Rule Association (Many-to-One)
  triggerEntity.addAssociation(
    { key: ruleEntity.key },
    {
      info: { name: 'rule', displayName: 'Rule', description: 'Rule for this trigger' },
      required: true,
      multiple: false,
    }
  )

  // Action Entity
  const actionEntity = automationModel.addEntity({
    info: {
      name: 'action',
      displayName: 'Action',
      description: 'Automation action to execute',
    },
  })

  addIdField(actionEntity, { displayName: 'Action ID', description: 'Unique identifier for the action' })

  addNameField(actionEntity, { description: 'Action name and description' })

  addDescriptionField(actionEntity, { description: 'Action description and parameters' })

  actionEntity.addProperty({
    info: { name: 'action_type', displayName: 'Action Type', description: 'Type of action' },
    type: 'string',
    required: true,
    schema: {
      enum: ['device_control', 'notification', 'data_logging', 'api_call', 'script_execution'],
    },
  })

  actionEntity.addProperty({
    info: { name: 'parameters', displayName: 'Parameters', description: 'Action parameters' },
    type: 'string',
    required: false,
  })

  actionEntity.addProperty({
    info: { name: 'delay', displayName: 'Delay', description: 'Action delay in seconds' },
    type: 'number',
    required: false,
    schema: {
      minimum: 0,
    },
  })

  addCustomStatusField(actionEntity, ['pending', 'executing', 'completed', 'failed'], {
    displayName: 'Action Status',
    description: 'Current status of the action',
  })

  addCreatedAtField(actionEntity, { description: 'When the action was created' })

  // Action-Rule Association (Many-to-One)
  actionEntity.addAssociation(
    { key: ruleEntity.key },
    {
      info: { name: 'rule', displayName: 'Rule', description: 'Rule for this action' },
      required: true,
      multiple: false,
    }
  )

  // Schedule Entity
  const scheduleEntity = automationModel.addEntity({
    info: {
      name: 'schedule',
      displayName: 'Schedule',
      description: 'Automation schedule',
    },
  })

  addIdField(scheduleEntity, { displayName: 'Schedule ID', description: 'Unique identifier for the schedule' })

  addNameField(scheduleEntity, { description: 'Schedule name and description' })

  addDescriptionField(scheduleEntity, { description: 'Schedule description and timing' })

  scheduleEntity.addProperty({
    info: { name: 'schedule_type', displayName: 'Schedule Type', description: 'Type of schedule' },
    type: 'string',
    required: true,
    schema: {
      enum: ['daily', 'weekly', 'monthly', 'custom', 'sunrise_sunset'],
    },
  })

  scheduleEntity.addProperty({
    info: { name: 'start_time', displayName: 'Start Time', description: 'Schedule start time' },
    type: 'time',
    required: true,
  })

  scheduleEntity.addProperty({
    info: { name: 'end_time', displayName: 'End Time', description: 'Schedule end time' },
    type: 'time',
    required: false,
  })

  scheduleEntity.addProperty({
    info: { name: 'days_of_week', displayName: 'Days of Week', description: 'Days of week for schedule' },
    type: 'string',
    required: false,
  })

  addCustomStatusField(scheduleEntity, ['active', 'inactive', 'paused'], {
    displayName: 'Schedule Status',
    description: 'Current status of the schedule',
  })

  addCreatedAtField(scheduleEntity, { description: 'When the schedule was created' })

  // Schedule-Rule Association (Many-to-One)
  scheduleEntity.addAssociation(
    { key: ruleEntity.key },
    {
      info: { name: 'rule', displayName: 'Rule', description: 'Rule for this schedule' },
      required: true,
      multiple: false,
    }
  )

  //
  // 4. USER MANAGEMENT NAMESPACE
  //
  const userManagement = domain.addNamespace({
    info: {
      name: 'UserManagement',
      displayName: 'User Management',
      description: 'Users, permissions, and device access',
    },
  })

  // User Model
  const userModel = userManagement.addModel({
    info: {
      name: 'Users',
      displayName: 'User Management',
      description: 'User accounts and permissions',
    },
  })

  // User Entity
  const userEntity = userModel.addEntity({
    info: {
      name: 'user',
      displayName: 'User',
      description: 'System user with access permissions',
    },
  })

  addIdField(userEntity, { displayName: 'User ID', description: 'Unique identifier for the user' })

  addNameField(userEntity, { description: 'User name and title' })

  addDescriptionField(userEntity, { description: 'User description and notes' })

  addEmailField(userEntity, { description: 'User email address' })

  addPhoneField(userEntity, { description: 'User phone number' })

  userEntity.addProperty({
    info: { name: 'user_type', displayName: 'User Type', description: 'Type of user' },
    type: 'string',
    required: true,
    schema: {
      enum: ['owner', 'admin', 'family_member', 'guest', 'service_account'],
    },
  })

  userEntity.addProperty({
    info: { name: 'username', displayName: 'Username', description: 'User login username' },
    type: 'string',
    required: true,
    unique: true,
  })

  userEntity.addProperty({
    info: { name: 'last_login', displayName: 'Last Login', description: 'User last login date' },
    type: 'datetime',
    required: false,
  })

  addCustomStatusField(userEntity, ['active', 'inactive', 'suspended', 'pending'], {
    displayName: 'User Status',
    description: 'Current status of the user',
  })

  addCreatedAtField(userEntity, { description: 'When the user was created' })
  addUpdatedAtField(userEntity, { description: 'When the user was last updated' })

  // Permission Entity
  const permissionEntity = userModel.addEntity({
    info: {
      name: 'permission',
      displayName: 'Permission',
      description: 'User permissions and access rights',
    },
  })

  addIdField(permissionEntity, {
    displayName: 'Permission ID',
    description: 'Unique identifier for the permission',
  })

  addNameField(permissionEntity, { description: 'Permission name and description' })

  addDescriptionField(permissionEntity, { description: 'Permission description and scope' })

  permissionEntity.addProperty({
    info: { name: 'permission_type', displayName: 'Permission Type', description: 'Type of permission' },
    type: 'string',
    required: true,
    schema: {
      enum: ['read', 'write', 'admin', 'control', 'view', 'configure'],
    },
  })

  permissionEntity.addProperty({
    info: { name: 'resource', displayName: 'Resource', description: 'Resource for permission' },
    type: 'string',
    required: true,
  })

  permissionEntity.addProperty({
    info: { name: 'scope', displayName: 'Scope', description: 'Permission scope' },
    type: 'string',
    required: true,
    schema: {
      enum: ['all', 'specific', 'room', 'device', 'system'],
    },
  })

  addCustomStatusField(permissionEntity, ['active', 'inactive', 'temporary'], {
    displayName: 'Permission Status',
    description: 'Current status of the permission',
  })

  addCreatedAtField(permissionEntity, { description: 'When the permission was created' })

  // Permission-User Association (Many-to-One)
  permissionEntity.addAssociation(
    { key: userEntity.key },
    {
      info: { name: 'user', displayName: 'User', description: 'User for this permission' },
      required: true,
      multiple: false,
    }
  )

  // Device Access Entity
  const deviceAccessEntity = userModel.addEntity({
    info: {
      name: 'device_access',
      displayName: 'Device Access',
      description: 'User access to specific devices',
    },
  })

  addIdField(deviceAccessEntity, {
    displayName: 'Access ID',
    description: 'Unique identifier for the device access',
  })

  addNameField(deviceAccessEntity, { description: 'Access name and description' })

  deviceAccessEntity.addProperty({
    info: { name: 'access_type', displayName: 'Access Type', description: 'Type of device access' },
    type: 'string',
    required: true,
    schema: {
      enum: ['full_control', 'read_only', 'limited_control', 'monitor_only'],
    },
  })

  deviceAccessEntity.addProperty({
    info: { name: 'granted_date', displayName: 'Granted Date', description: 'Access granted date' },
    type: 'date',
    required: true,
  })

  deviceAccessEntity.addProperty({
    info: { name: 'expiry_date', displayName: 'Expiry Date', description: 'Access expiry date' },
    type: 'date',
    required: false,
  })

  addCustomStatusField(deviceAccessEntity, ['active', 'expired', 'revoked'], {
    displayName: 'Access Status',
    description: 'Current status of the device access',
  })

  addCreatedAtField(deviceAccessEntity, { description: 'When the access was created' })

  // DeviceAccess-User Association (Many-to-One)
  deviceAccessEntity.addAssociation(
    { key: userEntity.key },
    {
      info: { name: 'user', displayName: 'User', description: 'User for this device access' },
      required: true,
      multiple: false,
    }
  )

  // DeviceAccess-Device Association (Many-to-One)
  deviceAccessEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this access' },
      required: true,
      multiple: false,
    }
  )

  //
  // 5. MONITORING NAMESPACE
  //
  const monitoring = domain.addNamespace({
    info: {
      name: 'Monitoring',
      displayName: 'Monitoring',
      description: 'Alerts, notifications, and health status',
    },
  })

  // Monitoring Model
  const monitoringModel = monitoring.addModel({
    info: {
      name: 'Monitoring',
      displayName: 'Monitoring Management',
      description: 'System monitoring and alerting',
    },
  })

  // Alert Entity
  const alertEntity = monitoringModel.addEntity({
    info: {
      name: 'alert',
      displayName: 'Alert',
      description: 'System alert or notification',
    },
  })

  addIdField(alertEntity, { displayName: 'Alert ID', description: 'Unique identifier for the alert' })

  addNameField(alertEntity, { description: 'Alert name and title' })

  addDescriptionField(alertEntity, { description: 'Alert description and details' })

  alertEntity.addProperty({
    info: { name: 'alert_type', displayName: 'Alert Type', description: 'Type of alert' },
    type: 'string',
    required: true,
    schema: {
      enum: ['error', 'warning', 'info', 'critical', 'maintenance'],
    },
  })

  alertEntity.addProperty({
    info: { name: 'severity', displayName: 'Severity', description: 'Alert severity level' },
    type: 'string',
    required: true,
    schema: {
      enum: ['low', 'medium', 'high', 'critical'],
    },
  })

  alertEntity.addProperty({
    info: { name: 'triggered_at', displayName: 'Triggered At', description: 'Alert trigger time' },
    type: 'datetime',
    required: true,
  })

  alertEntity.addProperty({
    info: { name: 'resolved_at', displayName: 'Resolved At', description: 'Alert resolution time' },
    type: 'datetime',
    required: false,
  })

  addCustomStatusField(alertEntity, ['active', 'acknowledged', 'resolved', 'dismissed'], {
    displayName: 'Alert Status',
    description: 'Current status of the alert',
  })

  addCreatedAtField(alertEntity, { description: 'When the alert was created' })

  // Alert-Device Association (Many-to-One)
  alertEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this alert' },
      required: false,
      multiple: false,
    }
  )

  // Notification Entity
  const notificationEntity = monitoringModel.addEntity({
    info: {
      name: 'notification',
      displayName: 'Notification',
      description: 'User notification message',
    },
  })

  addIdField(notificationEntity, {
    displayName: 'Notification ID',
    description: 'Unique identifier for the notification',
  })

  addNameField(notificationEntity, { description: 'Notification name and title' })

  addDescriptionField(notificationEntity, { description: 'Notification message content' })

  notificationEntity.addProperty({
    info: { name: 'notification_type', displayName: 'Notification Type', description: 'Type of notification' },
    type: 'string',
    required: true,
    schema: {
      enum: ['email', 'sms', 'push', 'in_app', 'webhook'],
    },
  })

  notificationEntity.addProperty({
    info: { name: 'recipient', displayName: 'Recipient', description: 'Notification recipient' },
    type: 'string',
    required: true,
  })

  notificationEntity.addProperty({
    info: { name: 'sent_at', displayName: 'Sent At', description: 'Notification sent time' },
    type: 'datetime',
    required: true,
  })

  notificationEntity.addProperty({
    info: { name: 'read_at', displayName: 'Read At', description: 'Notification read time' },
    type: 'datetime',
    required: false,
  })

  addCustomStatusField(notificationEntity, ['pending', 'sent', 'delivered', 'read', 'failed'], {
    displayName: 'Notification Status',
    description: 'Current status of the notification',
  })

  addCreatedAtField(notificationEntity, { description: 'When the notification was created' })

  // Notification-User Association (Many-to-One)
  notificationEntity.addAssociation(
    { key: userEntity.key },
    {
      info: { name: 'user', displayName: 'User', description: 'User for this notification' },
      required: true,
      multiple: false,
    }
  )

  // Health Status Entity
  const healthStatusEntity = monitoringModel.addEntity({
    info: {
      name: 'health_status',
      displayName: 'Health Status',
      description: 'System and device health status',
    },
  })

  addIdField(healthStatusEntity, {
    displayName: 'Health ID',
    description: 'Unique identifier for the health status',
  })

  addNameField(healthStatusEntity, { description: 'Health status name and description' })

  healthStatusEntity.addProperty({
    info: { name: 'health_type', displayName: 'Health Type', description: 'Type of health status' },
    type: 'string',
    required: true,
    schema: {
      enum: ['system', 'device', 'network', 'battery', 'connectivity'],
    },
  })

  healthStatusEntity.addProperty({
    info: { name: 'check_time', displayName: 'Check Time', description: 'Health check time' },
    type: 'datetime',
    required: true,
  })

  healthStatusEntity.addProperty({
    info: { name: 'score', displayName: 'Score', description: 'Health score (0-100)' },
    type: 'number',
    required: true,
    schema: {
      minimum: 0,
      maximum: 100,
    },
  })

  addCustomStatusField(healthStatusEntity, ['excellent', 'good', 'fair', 'poor', 'critical'], {
    displayName: 'Health Status',
    description: 'Current health status',
  })

  addCreatedAtField(healthStatusEntity, { description: 'When the health status was created' })

  // HealthStatus-Device Association (Many-to-One)
  healthStatusEntity.addAssociation(
    { key: deviceEntity.key },
    {
      info: { name: 'device', displayName: 'Device', description: 'Device for this health status' },
      required: false,
      multiple: false,
    }
  )

  //
  // 6. INTEGRATION NAMESPACE
  //
  const integration = domain.addNamespace({
    info: {
      name: 'Integration',
      displayName: 'Integration',
      description: 'Third-party services, APIs, and protocols',
    },
  })

  // Integration Model
  const integrationModel = integration.addModel({
    info: {
      name: 'Integrations',
      displayName: 'Integration Management',
      description: 'Third-party integrations and APIs',
    },
  })

  // Integration Entity
  const integrationEntity = integrationModel.addEntity({
    info: {
      name: 'integration',
      displayName: 'Integration',
      description: 'Third-party service integration',
    },
  })

  addIdField(integrationEntity, {
    displayName: 'Integration ID',
    description: 'Unique identifier for the integration',
  })

  addNameField(integrationEntity, { description: 'Integration name and description' })

  addDescriptionField(integrationEntity, { description: 'Integration description and capabilities' })

  integrationEntity.addProperty({
    info: { name: 'integration_type', displayName: 'Integration Type', description: 'Type of integration' },
    type: 'string',
    required: true,
    schema: {
      enum: ['api', 'webhook', 'protocol', 'service', 'platform'],
    },
  })

  integrationEntity.addProperty({
    info: { name: 'provider', displayName: 'Provider', description: 'Integration provider' },
    type: 'string',
    required: true,
  })

  integrationEntity.addProperty({
    info: { name: 'endpoint_url', displayName: 'Endpoint URL', description: 'Integration endpoint URL' },
    type: 'string',
    required: false,
  })

  integrationEntity.addProperty({
    info: { name: 'api_key', displayName: 'API Key', description: 'Integration API key' },
    type: 'string',
    required: false,
  })

  integrationEntity.addProperty({
    info: { name: 'protocol', displayName: 'Protocol', description: 'Integration protocol' },
    type: 'string',
    required: false,
    schema: {
      enum: ['http', 'https', 'mqtt', 'coap', 'websocket', 'tcp'],
    },
  })

  addCustomStatusField(integrationEntity, ['active', 'inactive', 'testing', 'error'], {
    displayName: 'Integration Status',
    description: 'Current status of the integration',
  })

  addCreatedAtField(integrationEntity, { description: 'When the integration was created' })

  // API Call Entity
  const apiCallEntity = integrationModel.addEntity({
    info: {
      name: 'api_call',
      displayName: 'API Call',
      description: 'API call to third-party service',
    },
  })

  addIdField(apiCallEntity, { displayName: 'Call ID', description: 'Unique identifier for the API call' })

  addNameField(apiCallEntity, { description: 'API call name and description' })

  apiCallEntity.addProperty({
    info: { name: 'endpoint', displayName: 'Endpoint', description: 'API endpoint' },
    type: 'string',
    required: true,
  })

  apiCallEntity.addProperty({
    info: { name: 'method', displayName: 'Method', description: 'HTTP method' },
    type: 'string',
    required: true,
    schema: {
      enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
    },
  })

  apiCallEntity.addProperty({
    info: { name: 'request_data', displayName: 'Request Data', description: 'API request data' },
    type: 'string',
    required: false,
  })

  apiCallEntity.addProperty({
    info: { name: 'response_data', displayName: 'Response Data', description: 'API response data' },
    type: 'string',
    required: false,
  })

  apiCallEntity.addProperty({
    info: { name: 'response_code', displayName: 'Response Code', description: 'HTTP response code' },
    type: 'number',
    required: false,
  })

  apiCallEntity.addProperty({
    info: { name: 'duration', displayName: 'Duration', description: 'API call duration in milliseconds' },
    type: 'number',
    required: false,
    schema: {
      minimum: 0,
    },
  })

  addCustomStatusField(apiCallEntity, ['pending', 'in_progress', 'completed', 'failed', 'timeout'], {
    displayName: 'Call Status',
    description: 'Current status of the API call',
  })

  addCreatedAtField(apiCallEntity, { description: 'When the API call was created' })

  // ApiCall-Integration Association (Many-to-One)
  apiCallEntity.addAssociation(
    { key: integrationEntity.key },
    {
      info: { name: 'integration', displayName: 'Integration', description: 'Integration for this API call' },
      required: true,
      multiple: false,
    }
  )

  return domain
}
