/**
 * @aurora-catalyst-generated
 * @source cliter/iam/account.aurora.yaml
 */
import { IamAccountTypeEnum } from '@api/graphql';
import { IamCreateUserDto } from '@api/iam/user';
import { ApiProperty } from '@nestjs/swagger';

export class IamCreateAccountDto {
  @ApiProperty({
    type: String,
    description: 'Unique identifier for the account. Used as primary key across the system.',
  })
  id: string;

  @ApiProperty({
    enum: IamAccountTypeEnum,
    description:
      'Type of account determining authentication and authorization behavior. USER: Regular user account with login credentials, associated with a person. SERVICE: Service account for API integrations and automated systems, typically without login UI access. Service accounts may have different permission scopes.',
    example: IamAccountTypeEnum.USER,
  })
  type: IamAccountTypeEnum;

  @ApiProperty({
    type: String,
    description:
      "Optional unique identifier code for the account, typically used for external system integrations or customer-facing account numbers. Must be unique across all accounts. Can be NULL for accounts that don't require external identification codes.",
  })
  code?: string;

  @ApiProperty({
    type: String,
    description:
      "Primary email address for the account. Used for authentication and notifications. Must be unique across all accounts. Can be NULL for service accounts that don't require email-based communication. Validated against RFC 5322 format.",
    example: 'john@gmail.com',
  })
  email?: string;

  @ApiProperty({
    type: String,
    description:
      'Unique username for account identification and login. Must be uniqueacross all accounts. Required for all account types. Typically followsnaming conventions: lowercase, alphanumeric with hyphens/underscores.',
  })
  username: string;

  @ApiProperty({
    type: Boolean,
    description:
      'Indicates whether the account is currently active and allowed to authenticate. Defaults to false (inactive) for security - accounts must be explicitly activated after creation, typically after email verification or admin approval. Inactive accounts cannot log in or access protected resources. This is separate from soft-delete (deletedAt) - inactive accounts can be reactivated.',
    example: true,
  })
  isActive: boolean;

  @ApiProperty({
    type: String,
    description:
      'Reference to the OAuth client application that this account belongs to. Each account must be associated with exactly one OAuth client for proper authentication and authorization scoping. The client determines available permissions and resources for the account.',
    example: '589cf4d0-af83-5c3a-8683-3c162633d000',
  })
  clientId: string;

  @ApiProperty({
    type: Array,
    description:
      'Optional array of tags for categorizing and filtering accounts. Each tag is limited to 64 characters. Uses GIN index for efficient array search operations. Common uses: department tags, customer segments, feature flags, or custom organizational categories. NULL indicates no tags assigned.',
  })
  tags?: string[];

  @ApiProperty({
    type: Array,
    description:
      'OAuth 2.0 scopes defining the access permissions for this account. Scopes limit what resources and operations the account can access. Each scope is a string up to 64 characters (e.g., "read:users", "write:posts"). NULL indicates default scope set. Used by OAuth authorization flows.',
  })
  scopes?: string[];

  @ApiProperty({
    type: Array,
    description:
      "Denormalized array of application codes that this account has access to. Stored for query performance optimization to avoid joins. Should be kept in sync with the account's roles and permissions. Updated automatically when roles or permissions change. Required field - empty array indicates no application access.",
  })
  dApplicationCodes: string[];

  @ApiProperty({
    type: Object,
    description:
      'Denormalized JSON structure containing the flattened permission tree for this account. Combines permissions from all assigned roles for fast authorization checks. Structure: { "permission.key": true, "resource:action": true } Automatically recalculated when roles or role permissions change. Required field - empty object indicates no permissions granted. Uses JSONB for efficient querying and indexing in PostgreSQL.',
  })
  dPermissions: any;

  @ApiProperty({
    type: Array,
    description:
      'Denormalized array of tenant IDs that this account belongs to. Stored for query performance to quickly filter data by tenant access. Should match the many-to-many relationship in the tenants field. Updated automatically when tenant associations change. Required field - empty array indicates no tenant access.',
  })
  dTenants: string[];

  @ApiProperty({
    type: Object,
    description:
      "Optional JSON field for storing custom account metadata and properties. Use for application-specific data that doesn't warrant dedicated columns. Examples: UI preferences, feature flags, custom fields, integration metadata. NULL indicates no custom metadata. No schema validation - use carefully.",
  })
  meta?: any;

  @ApiProperty({
    type: [String],
    description:
      'Many-to-many relationship defining the roles assigned to this account. An account can have zero or more roles. Roles determine the permissions and access levels for the account. NULL or empty indicates no roles assigned (account has no permissions). When roles change, denormalizedPermissions and denormalizedApplicationCodes are automatically updated.',
  })
  roleIds?: string[];

  @ApiProperty({
    type: [String],
    description:
      'Many-to-many relationship defining which tenants (organizations) this account belongs to. Enables multi-tenancy where one account can access multiple organizations. NULL or empty indicates no tenant associations. When tenants change, denormalizedTenantIds is automatically updated. Used for data isolation and access control in multi-tenant environments.',
  })
  tenantIds?: string[];

  @ApiProperty({
    type: Boolean,
    description:
      'Transient flag (not persisted). When true, the orchestration handler expands tenantIds with descendants from the tenant tree before creating the account.',
    required: false,
  })
  hasAddChildTenants?: boolean;

  @ApiProperty({
    type: IamCreateUserDto,
    description:
      "One-to-one relationship to the user profile containing personal information. For USER type accounts, this links to the associated user profile with name, surname, password, and other personal details. NULL for SERVICE type accounts which don't have user profiles. The user entity contains authentication credentials and personal data.",
  })
  user?: IamCreateUserDto;
}
