/**
 * 人群包用途类型
 */
export enum SegmentUsageType {
  GENERAL = 'GENERAL', // 通用
  NOTIFICATION = 'NOTIFICATION', // 通知定向
  ADVERTISING = 'ADVERTISING', // 广告定向
  ANALYTICS = 'ANALYTICS', // 数据分析
}

/**
 * 条件类型
 */
export type ConditionType = 'tag' | 'feature' | 'profile';

/**
 * 条件操作符
 */
export type ConditionOperator =
  | 'eq' // 等于
  | 'neq' // 不等于
  | 'gt' // 大于
  | 'gte' // 大于等于
  | 'lt' // 小于
  | 'lte' // 小于等于
  | 'in' // 在列表中
  | 'not_in' // 不在列表中
  | 'contains' // 包含
  | 'starts_with' // 以...开头
  | 'ends_with'; // 以...结尾

/**
 * 单个条件
 */
export interface SegmentCondition {
  type: ConditionType;
  field: string; // tagCode, rfmScore, province 等
  operator: ConditionOperator;
  value: unknown;
}

/**
 * 条件组
 */
export interface SegmentConditionGroup {
  type: 'AND' | 'OR';
  conditions: (SegmentCondition | SegmentConditionGroup)[];
}

/**
 * 人群包实体
 */
export class AudienceSegmentEntity {
  constructor(
    public readonly id: string,
    public readonly name: string,
    public readonly description: string | null,
    public readonly conditions: SegmentConditionGroup,
    public readonly estimatedUsers: number | null,
    public readonly lastCalculated: Date | null,
    public readonly usageType: SegmentUsageType,
    public readonly isEnabled: boolean,
    public readonly createdAt: Date,
    public readonly updatedAt: Date,
    public readonly createdBy: string,
  ) {}

  /**
   * 创建人群包
   */
  static create(params: {
    id: string;
    name: string;
    description?: string | null;
    conditions: SegmentConditionGroup;
    usageType?: SegmentUsageType;
    createdBy: string;
  }): AudienceSegmentEntity {
    const now = new Date();
    return new AudienceSegmentEntity(
      params.id,
      params.name,
      params.description ?? null,
      params.conditions,
      null,
      null,
      params.usageType ?? SegmentUsageType.GENERAL,
      true,
      now,
      now,
      params.createdBy,
    );
  }

  /**
   * 更新人群包
   */
  update(params: {
    name?: string;
    description?: string | null;
    conditions?: SegmentConditionGroup;
    usageType?: SegmentUsageType;
    isEnabled?: boolean;
  }): AudienceSegmentEntity {
    return new AudienceSegmentEntity(
      this.id,
      params.name ?? this.name,
      params.description !== undefined ? params.description : this.description,
      params.conditions ?? this.conditions,
      this.estimatedUsers,
      this.lastCalculated,
      params.usageType ?? this.usageType,
      params.isEnabled ?? this.isEnabled,
      this.createdAt,
      new Date(),
      this.createdBy,
    );
  }

  /**
   * 更新预估用户数
   */
  updateEstimatedUsers(count: number): AudienceSegmentEntity {
    return new AudienceSegmentEntity(
      this.id,
      this.name,
      this.description,
      this.conditions,
      count,
      new Date(),
      this.usageType,
      this.isEnabled,
      this.createdAt,
      new Date(),
      this.createdBy,
    );
  }

  /**
   * 验证条件格式
   */
  static validateConditions(conditions: unknown): conditions is SegmentConditionGroup {
    if (!conditions || typeof conditions !== 'object') {
      return false;
    }

    const group = conditions as SegmentConditionGroup;
    if (!['AND', 'OR'].includes(group.type)) {
      return false;
    }

    if (!Array.isArray(group.conditions) || group.conditions.length === 0) {
      return false;
    }

    return group.conditions.every((condition) => {
      if ('type' in condition && ['AND', 'OR'].includes(condition.type as string)) {
        return AudienceSegmentEntity.validateConditions(condition);
      }

      const c = condition as SegmentCondition;
      if (!['tag', 'feature', 'profile'].includes(c.type)) {
        return false;
      }
      if (!c.field || typeof c.field !== 'string') {
        return false;
      }
      if (!c.operator) {
        return false;
      }
      return true;
    });
  }

  /**
   * 获取条件中涉及的所有标签 code
   */
  getTagCodes(): string[] {
    return this.extractTagCodes(this.conditions);
  }

  private extractTagCodes(group: SegmentConditionGroup): string[] {
    const codes: string[] = [];

    for (const condition of group.conditions) {
      if ('type' in condition && ['AND', 'OR'].includes(condition.type as string)) {
        codes.push(...this.extractTagCodes(condition as SegmentConditionGroup));
      } else {
        const c = condition as SegmentCondition;
        if (c.type === 'tag') {
          codes.push(c.field);
        }
      }
    }

    return [...new Set(codes)];
  }

  /**
   * 获取条件中涉及的所有特征字段
   */
  getFeatureFields(): string[] {
    return this.extractFeatureFields(this.conditions);
  }

  private extractFeatureFields(group: SegmentConditionGroup): string[] {
    const fields: string[] = [];

    for (const condition of group.conditions) {
      if ('type' in condition && ['AND', 'OR'].includes(condition.type as string)) {
        fields.push(...this.extractFeatureFields(condition as SegmentConditionGroup));
      } else {
        const c = condition as SegmentCondition;
        if (c.type === 'feature') {
          fields.push(c.field);
        }
      }
    }

    return [...new Set(fields)];
  }
}
