/**
 * 标签类型
 */
export enum TagType {
  MANUAL = 'MANUAL', // 手动打标 (管理员操作)
  AUTO = 'AUTO', // 自动打标 (规则驱动)
  COMPUTED = 'COMPUTED', // 计算型 (实时计算，不存储关联)
  SYSTEM = 'SYSTEM', // 系统内置 (不可删除)
}

/**
 * 标签值类型
 */
export enum TagValueType {
  BOOLEAN = 'BOOLEAN', // 布尔型: 有/无
  ENUM = 'ENUM', // 枚举型: 高/中/低
  NUMBER = 'NUMBER', // 数值型: 0-100分
  STRING = 'STRING', // 字符串型
}

/**
 * 标签变更操作
 */
export enum TagAction {
  ASSIGN = 'ASSIGN', // 打标签
  UPDATE = 'UPDATE', // 更新标签值
  REMOVE = 'REMOVE', // 移除标签
  EXPIRE = 'EXPIRE', // 过期移除
}

/**
 * 标签分类实体
 */
export class TagCategoryEntity {
  constructor(
    public readonly id: string,
    public readonly code: string,
    public readonly name: string,
    public readonly description: string | null,
    public readonly sortOrder: number,
    public readonly isEnabled: boolean,
    public readonly createdAt: Date,
    public readonly updatedAt: Date,
  ) {}

  static create(params: {
    id: string;
    code: string;
    name: string;
    description?: string | null;
    sortOrder?: number;
  }): TagCategoryEntity {
    const now = new Date();
    return new TagCategoryEntity(
      params.id,
      params.code,
      params.name,
      params.description ?? null,
      params.sortOrder ?? 0,
      true,
      now,
      now,
    );
  }

  update(params: {
    name?: string;
    description?: string | null;
    sortOrder?: number;
    isEnabled?: boolean;
  }): TagCategoryEntity {
    return new TagCategoryEntity(
      this.id,
      this.code,
      params.name ?? this.name,
      params.description !== undefined ? params.description : this.description,
      params.sortOrder ?? this.sortOrder,
      params.isEnabled ?? this.isEnabled,
      this.createdAt,
      new Date(),
    );
  }
}

/**
 * 用户标签实体
 */
export class UserTagEntity {
  constructor(
    public readonly id: string,
    public readonly categoryId: string | null,
    public readonly code: string,
    public readonly name: string,
    public readonly description: string | null,
    public readonly color: string | null,
    public readonly type: TagType,
    public readonly valueType: TagValueType,
    public readonly enumValues: string[] | null,
    public readonly ruleId: string | null,
    public readonly isAdvertisable: boolean,
    public readonly estimatedUsers: number | null,
    public readonly isEnabled: boolean,
    public readonly sortOrder: number,
    public readonly createdAt: Date,
    public readonly updatedAt: Date,
  ) {}

  /**
   * 创建新标签
   */
  static create(params: {
    id: string;
    code: string;
    name: string;
    categoryId?: string | null;
    description?: string | null;
    color?: string | null;
    type?: TagType;
    valueType?: TagValueType;
    enumValues?: string[] | null;
    ruleId?: string | null;
    isAdvertisable?: boolean;
    sortOrder?: number;
  }): UserTagEntity {
    const now = new Date();
    return new UserTagEntity(
      params.id,
      params.categoryId ?? null,
      params.code,
      params.name,
      params.description ?? null,
      params.color ?? null,
      params.type ?? TagType.MANUAL,
      params.valueType ?? TagValueType.BOOLEAN,
      params.enumValues ?? null,
      params.ruleId ?? null,
      params.isAdvertisable ?? true,
      null,
      true,
      params.sortOrder ?? 0,
      now,
      now,
    );
  }

  /**
   * 更新标签
   */
  update(params: {
    categoryId?: string | null;
    name?: string;
    description?: string | null;
    color?: string | null;
    valueType?: TagValueType;
    enumValues?: string[] | null;
    isAdvertisable?: boolean;
    isEnabled?: boolean;
    sortOrder?: number;
  }): UserTagEntity {
    return new UserTagEntity(
      this.id,
      params.categoryId !== undefined ? params.categoryId : this.categoryId,
      this.code,
      params.name ?? this.name,
      params.description !== undefined ? params.description : this.description,
      params.color !== undefined ? params.color : this.color,
      this.type,
      params.valueType ?? this.valueType,
      params.enumValues !== undefined ? params.enumValues : this.enumValues,
      this.ruleId,
      params.isAdvertisable ?? this.isAdvertisable,
      this.estimatedUsers,
      params.isEnabled ?? this.isEnabled,
      params.sortOrder ?? this.sortOrder,
      this.createdAt,
      new Date(),
    );
  }

  /**
   * 关联规则
   */
  linkRule(ruleId: string): UserTagEntity {
    return new UserTagEntity(
      this.id,
      this.categoryId,
      this.code,
      this.name,
      this.description,
      this.color,
      TagType.AUTO,
      this.valueType,
      this.enumValues,
      ruleId,
      this.isAdvertisable,
      this.estimatedUsers,
      this.isEnabled,
      this.sortOrder,
      this.createdAt,
      new Date(),
    );
  }

  /**
   * 取消关联规则
   */
  unlinkRule(): UserTagEntity {
    return new UserTagEntity(
      this.id,
      this.categoryId,
      this.code,
      this.name,
      this.description,
      this.color,
      TagType.MANUAL,
      this.valueType,
      this.enumValues,
      null,
      this.isAdvertisable,
      this.estimatedUsers,
      this.isEnabled,
      this.sortOrder,
      this.createdAt,
      new Date(),
    );
  }

  /**
   * 更新预估用户数
   */
  updateEstimatedUsers(count: number): UserTagEntity {
    return new UserTagEntity(
      this.id,
      this.categoryId,
      this.code,
      this.name,
      this.description,
      this.color,
      this.type,
      this.valueType,
      this.enumValues,
      this.ruleId,
      this.isAdvertisable,
      count,
      this.isEnabled,
      this.sortOrder,
      this.createdAt,
      new Date(),
    );
  }

  /**
   * 是否为自动标签
   */
  isAutoTag(): boolean {
    return this.type === TagType.AUTO && this.ruleId !== null;
  }

  /**
   * 是否可删除
   */
  canDelete(): boolean {
    return this.type !== TagType.SYSTEM;
  }

  /**
   * 验证枚举值是否有效
   */
  isValidEnumValue(value: string): boolean {
    if (this.valueType !== TagValueType.ENUM) {
      return true;
    }
    if (!this.enumValues || this.enumValues.length === 0) {
      return true;
    }
    return this.enumValues.includes(value);
  }
}

/**
 * 用户-标签关联实体
 */
export class UserTagAssignmentEntity {
  constructor(
    public readonly id: string,
    public readonly accountSequence: string,
    public readonly tagId: string,
    public readonly value: string | null,
    public readonly assignedAt: Date,
    public readonly assignedBy: string | null,
    public readonly expiresAt: Date | null,
    public readonly source: string | null,
  ) {}

  /**
   * 创建关联 (手动打标)
   */
  static createManual(params: {
    id: string;
    accountSequence: string;
    tagId: string;
    value?: string | null;
    assignedBy: string;
    expiresAt?: Date | null;
  }): UserTagAssignmentEntity {
    return new UserTagAssignmentEntity(
      params.id,
      params.accountSequence,
      params.tagId,
      params.value ?? null,
      new Date(),
      params.assignedBy,
      params.expiresAt ?? null,
      'manual',
    );
  }

  /**
   * 创建关联 (自动打标)
   */
  static createAuto(params: {
    id: string;
    accountSequence: string;
    tagId: string;
    value?: string | null;
    ruleId?: string;
  }): UserTagAssignmentEntity {
    return new UserTagAssignmentEntity(
      params.id,
      params.accountSequence,
      params.tagId,
      params.value ?? null,
      new Date(),
      null,
      null,
      params.ruleId ? `rule:${params.ruleId}` : 'auto',
    );
  }

  /**
   * 创建关联 (导入)
   */
  static createFromImport(params: {
    id: string;
    accountSequence: string;
    tagId: string;
    value?: string | null;
    expiresAt?: Date | null;
  }): UserTagAssignmentEntity {
    return new UserTagAssignmentEntity(
      params.id,
      params.accountSequence,
      params.tagId,
      params.value ?? null,
      new Date(),
      null,
      params.expiresAt ?? null,
      'import',
    );
  }

  /**
   * 更新标签值
   */
  updateValue(value: string | null): UserTagAssignmentEntity {
    return new UserTagAssignmentEntity(
      this.id,
      this.accountSequence,
      this.tagId,
      value,
      this.assignedAt,
      this.assignedBy,
      this.expiresAt,
      this.source,
    );
  }

  /**
   * 是否已过期
   */
  isExpired(): boolean {
    if (!this.expiresAt) {
      return false;
    }
    return this.expiresAt < new Date();
  }

  /**
   * 是否为手动打标
   */
  isManual(): boolean {
    return this.source === 'manual';
  }

  /**
   * 是否为自动打标
   */
  isAuto(): boolean {
    return this.source?.startsWith('rule:') || this.source === 'auto';
  }
}

/**
 * 标签变更日志实体
 */
export class UserTagLogEntity {
  constructor(
    public readonly id: string,
    public readonly accountSequence: string,
    public readonly tagCode: string,
    public readonly action: TagAction,
    public readonly oldValue: string | null,
    public readonly newValue: string | null,
    public readonly reason: string | null,
    public readonly operatorId: string | null,
    public readonly createdAt: Date,
  ) {}

  static create(params: {
    id: string;
    accountSequence: string;
    tagCode: string;
    action: TagAction;
    oldValue?: string | null;
    newValue?: string | null;
    reason?: string | null;
    operatorId?: string | null;
  }): UserTagLogEntity {
    return new UserTagLogEntity(
      params.id,
      params.accountSequence,
      params.tagCode,
      params.action,
      params.oldValue ?? null,
      params.newValue ?? null,
      params.reason ?? null,
      params.operatorId ?? null,
      new Date(),
    );
  }
}
