import { AggregateRoot } from './aggregate-root.base'
import {
  AuthorizationId,
  UserId,
  AdminUserId,
  RegionCode,
  AssessmentConfig,
} from '@/domain/value-objects'
import { RoleType, AuthorizationStatus, MonthlyTargetType } from '@/domain/enums'
import { DomainError } from '@/shared/exceptions'
import {
  CommunityAuthorizedEvent,
  CommunityAuthRequestedEvent,
  AuthProvinceCompanyRequestedEvent,
  AuthCityCompanyRequestedEvent,
  AuthProvinceCompanyGrantedEvent,
  AuthCityCompanyGrantedEvent,
  ProvinceCompanyAuthorizedEvent,
  CityCompanyAuthorizedEvent,
  BenefitActivatedEvent,
  BenefitDeactivatedEvent,
  RoleAuthorizedEvent,
  RoleRevokedEvent,
  PercentageCheckExemptedEvent,
} from '@/domain/events'

export interface AuthorizationRoleProps {
  authorizationId: AuthorizationId
  userId: UserId
  roleType: RoleType
  regionCode: RegionCode
  regionName: string
  status: AuthorizationStatus
  displayTitle: string
  authorizedAt: Date | null
  authorizedBy: AdminUserId | null
  revokedAt: Date | null
  revokedBy: AdminUserId | null
  revokeReason: string | null
  assessmentConfig: AssessmentConfig
  requireLocalPercentage: number
  exemptFromPercentageCheck: boolean
  benefitActive: boolean
  benefitActivatedAt: Date | null
  benefitDeactivatedAt: Date | null
  benefitValidUntil: Date | null  // 权益有效期截止日期
  lastAssessmentMonth: string | null  // 上次考核月份 YYYY-MM
  monthlyTreesAdded: number  // 当月新增树数
  lastMonthTreesAdded: number  // 上月新增树数（考核用存档）
  currentMonthIndex: number
  deletedAt: Date | null  // 软删除时间 (大厂通用做法)
  officePhotoUrls: string[]  // 办公室照片 URL 列表
  createdAt: Date
  updatedAt: Date
}

export class AuthorizationRole extends AggregateRoot {
  private _authorizationId: AuthorizationId
  private _userId: UserId
  private _roleType: RoleType
  private _regionCode: RegionCode
  private _regionName: string
  private _status: AuthorizationStatus
  private _displayTitle: string

  // 授权信息
  private _authorizedAt: Date | null
  private _authorizedBy: AdminUserId | null
  private _revokedAt: Date | null
  private _revokedBy: AdminUserId | null
  private _revokeReason: string | null

  // 考核配置
  private _assessmentConfig: AssessmentConfig

  // 自有团队占比
  private _requireLocalPercentage: number
  private _exemptFromPercentageCheck: boolean

  // 权益状态
  private _benefitActive: boolean
  private _benefitActivatedAt: Date | null
  private _benefitDeactivatedAt: Date | null
  private _benefitValidUntil: Date | null

  // 月度考核追踪
  private _lastAssessmentMonth: string | null
  private _monthlyTreesAdded: number
  private _lastMonthTreesAdded: number  // 上月新增树数（考核用存档）

  // 当前考核月份索引
  private _currentMonthIndex: number

  // 软删除 (大厂通用做法)
  private _deletedAt: Date | null

  // 办公室照片
  private _officePhotoUrls: string[]

  private _createdAt: Date
  private _updatedAt: Date

  // Getters
  get authorizationId(): AuthorizationId {
    return this._authorizationId
  }
  get userId(): UserId {
    return this._userId
  }
  get roleType(): RoleType {
    return this._roleType
  }
  get regionCode(): RegionCode {
    return this._regionCode
  }
  get regionName(): string {
    return this._regionName
  }
  get status(): AuthorizationStatus {
    return this._status
  }
  get displayTitle(): string {
    return this._displayTitle
  }
  get authorizedAt(): Date | null {
    return this._authorizedAt
  }
  get authorizedBy(): AdminUserId | null {
    return this._authorizedBy
  }
  get revokedAt(): Date | null {
    return this._revokedAt
  }
  get revokedBy(): AdminUserId | null {
    return this._revokedBy
  }
  get revokeReason(): string | null {
    return this._revokeReason
  }
  get assessmentConfig(): AssessmentConfig {
    return this._assessmentConfig
  }
  get requireLocalPercentage(): number {
    return this._requireLocalPercentage
  }
  get exemptFromPercentageCheck(): boolean {
    return this._exemptFromPercentageCheck
  }
  get benefitActive(): boolean {
    return this._benefitActive
  }
  get benefitActivatedAt(): Date | null {
    return this._benefitActivatedAt
  }
  get benefitDeactivatedAt(): Date | null {
    return this._benefitDeactivatedAt
  }
  get benefitValidUntil(): Date | null {
    return this._benefitValidUntil
  }
  get lastAssessmentMonth(): string | null {
    return this._lastAssessmentMonth
  }
  get monthlyTreesAdded(): number {
    return this._monthlyTreesAdded
  }
  get lastMonthTreesAdded(): number {
    return this._lastMonthTreesAdded
  }
  get currentMonthIndex(): number {
    return this._currentMonthIndex
  }
  get createdAt(): Date {
    return this._createdAt
  }
  get updatedAt(): Date {
    return this._updatedAt
  }
  get deletedAt(): Date | null {
    return this._deletedAt
  }
  get officePhotoUrls(): string[] {
    return this._officePhotoUrls
  }
  get isActive(): boolean {
    return this._status === AuthorizationStatus.AUTHORIZED
  }

  // 私有构造函数
  private constructor(props: AuthorizationRoleProps) {
    super()
    this._authorizationId = props.authorizationId
    this._userId = props.userId
    this._roleType = props.roleType
    this._regionCode = props.regionCode
    this._regionName = props.regionName
    this._status = props.status
    this._displayTitle = props.displayTitle
    this._authorizedAt = props.authorizedAt
    this._authorizedBy = props.authorizedBy
    this._revokedAt = props.revokedAt
    this._revokedBy = props.revokedBy
    this._revokeReason = props.revokeReason
    this._assessmentConfig = props.assessmentConfig
    this._requireLocalPercentage = props.requireLocalPercentage
    this._exemptFromPercentageCheck = props.exemptFromPercentageCheck
    this._benefitActive = props.benefitActive
    this._benefitActivatedAt = props.benefitActivatedAt
    this._benefitDeactivatedAt = props.benefitDeactivatedAt
    this._benefitValidUntil = props.benefitValidUntil
    this._lastAssessmentMonth = props.lastAssessmentMonth
    this._monthlyTreesAdded = props.monthlyTreesAdded
    this._lastMonthTreesAdded = props.lastMonthTreesAdded
    this._currentMonthIndex = props.currentMonthIndex
    this._deletedAt = props.deletedAt
    this._officePhotoUrls = props.officePhotoUrls
    this._createdAt = props.createdAt
    this._updatedAt = props.updatedAt
  }

  // 工厂方法 - 从数据库重建
  static fromPersistence(props: AuthorizationRoleProps): AuthorizationRole {
    return new AuthorizationRole(props)
  }

  /**
   * 计算权益有效期截止日期
   * 规则：激活当月 + 下月末
   * 例如：11月3日激活 -> 12月31日23:59:59
   */
  private static calculateBenefitValidUntil(activatedAt: Date): Date {
    const year = activatedAt.getFullYear()
    const month = activatedAt.getMonth() // 0-based

    // 下下个月的第一天的前一天 = 下个月的最后一天
    // 例如：11月 -> month=10 -> month+2=12 (1月) -> 12月31日
    const nextNextMonth = month + 2
    const validUntil = new Date(year, nextNextMonth, 0, 23, 59, 59, 999)

    return validUntil
  }

  /**
   * 获取当前月份字符串 YYYY-MM
   */
  private static getCurrentMonthString(date: Date = new Date()): string {
    const year = date.getFullYear()
    const month = (date.getMonth() + 1).toString().padStart(2, '0')
    return `${year}-${month}`
  }

  // 工厂方法 - 创建社区授权
  static createCommunityAuth(params: { userId: UserId; communityName: string }): AuthorizationRole {
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.COMMUNITY,
      regionCode: RegionCode.create(params.communityName),
      regionName: params.communityName,
      status: AuthorizationStatus.PENDING,
      displayTitle: params.communityName,
      authorizedAt: null,
      authorizedBy: null,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forCommunity(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: false,
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: new Date(),
      updatedAt: new Date(),
    })

    auth.addDomainEvent(
      new CommunityAuthRequestedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        communityName: params.communityName,
      }),
    )

    return auth
  }

  // 工厂方法 - 自助申请社区授权（直接生效，无需审核）
  static createSelfAppliedCommunity(params: { userId: UserId; communityName: string; officePhotoUrls?: string[] }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.COMMUNITY,
      regionCode: RegionCode.create(params.communityName),
      regionName: params.communityName,
      status: AuthorizationStatus.AUTHORIZED, // 自助申请直接生效
      displayTitle: params.communityName,
      authorizedAt: now,
      authorizedBy: null, // 自助申请无管理员
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forCommunity(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: false, // 权益需要达到考核目标后激活
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: params.officePhotoUrls ?? [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new CommunityAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        communityName: params.communityName,
        authorizedBy: null, // 自助申请
      }),
    )

    return auth
  }

  // 工厂方法 - 管理员直接授权社区
  static createCommunity(params: {
    userId: UserId
    communityName: string
    adminId: AdminUserId
    skipAssessment?: boolean
  }): AuthorizationRole {
    const skipAssessment = params.skipAssessment ?? false
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.COMMUNITY,
      regionCode: RegionCode.create(params.communityName),
      regionName: params.communityName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: params.communityName,
      authorizedAt: now,
      authorizedBy: params.adminId,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forCommunity(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: skipAssessment,
      benefitActivatedAt: skipAssessment ? now : null,
      benefitDeactivatedAt: null,
      benefitValidUntil: skipAssessment ? AuthorizationRole.calculateBenefitValidUntil(now) : null,
      lastAssessmentMonth: skipAssessment ? AuthorizationRole.getCurrentMonthString(now) : null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: skipAssessment ? 1 : 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new CommunityAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        communityName: params.communityName,
        authorizedBy: params.adminId.value,
      }),
    )

    return auth
  }

  // 工厂方法 - 创建授权省公司
  static createAuthProvinceCompany(params: {
    userId: UserId
    provinceCode: string
    provinceName: string
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_PROVINCE_COMPANY,
      regionCode: RegionCode.create(params.provinceCode),
      regionName: params.provinceName,
      status: AuthorizationStatus.PENDING,
      displayTitle: `授权${params.provinceName}`,
      authorizedAt: null,
      authorizedBy: null,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthProvince(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: false,
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthProvinceCompanyRequestedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        provinceCode: params.provinceCode,
        provinceName: params.provinceName,
      }),
    )

    return auth
  }

  // 工厂方法 - 自助申请授权省公司（直接生效，无需审核）
  static createSelfAppliedAuthProvinceCompany(params: {
    userId: UserId
    provinceCode: string
    provinceName: string
    officePhotoUrls?: string[]
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_PROVINCE_COMPANY,
      regionCode: RegionCode.create(params.provinceCode),
      regionName: params.provinceName,
      status: AuthorizationStatus.AUTHORIZED, // 自助申请直接生效
      displayTitle: `授权${params.provinceName}`,
      authorizedAt: now,
      authorizedBy: null, // 自助申请无管理员
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthProvince(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: false, // 权益需要达到考核目标后激活
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: params.officePhotoUrls ?? [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthProvinceCompanyGrantedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        provinceCode: params.provinceCode,
        provinceName: params.provinceName,
        authorizedBy: null, // 自助申请
      }),
    )

    return auth
  }

  // 工厂方法 - 创建正式省公司
  // 授权即激活，开始按月考核（150, 300, 600, 1200, 2400, 4800, 9600, 19200, 11750）
  static createProvinceCompany(params: {
    userId: UserId
    provinceCode: string
    provinceName: string
    adminId: AdminUserId
    skipAssessment?: boolean  // 保留兼容，但不再影响激活状态
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.PROVINCE_COMPANY,
      regionCode: RegionCode.create(params.provinceCode),
      regionName: params.provinceName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: params.provinceName,
      authorizedAt: now,
      authorizedBy: params.adminId,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forProvince(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: true,  // 授权即激活
      benefitActivatedAt: now,
      benefitDeactivatedAt: null,
      benefitValidUntil: AuthorizationRole.calculateBenefitValidUntil(now),
      lastAssessmentMonth: AuthorizationRole.getCurrentMonthString(now),
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 1,  // 从第1个月开始考核
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new ProvinceCompanyAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        provinceCode: params.provinceCode,
        provinceName: params.provinceName,
        authorizedBy: params.adminId.value,
      }),
    )

    return auth
  }

  // 工厂方法 - 创建授权市公司
  static createAuthCityCompany(params: {
    userId: UserId
    cityCode: string
    cityName: string
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_CITY_COMPANY,
      regionCode: RegionCode.create(params.cityCode),
      regionName: params.cityName,
      status: AuthorizationStatus.PENDING,
      displayTitle: `授权${params.cityName}`,
      authorizedAt: null,
      authorizedBy: null,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthCity(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: false,
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthCityCompanyRequestedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        cityCode: params.cityCode,
        cityName: params.cityName,
      }),
    )

    return auth
  }

  // 工厂方法 - 自助申请授权市公司（直接生效，无需审核）
  static createSelfAppliedAuthCityCompany(params: {
    userId: UserId
    cityCode: string
    cityName: string
    officePhotoUrls?: string[]
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_CITY_COMPANY,
      regionCode: RegionCode.create(params.cityCode),
      regionName: params.cityName,
      status: AuthorizationStatus.AUTHORIZED, // 自助申请直接生效
      displayTitle: `授权${params.cityName}`,
      authorizedAt: now,
      authorizedBy: null, // 自助申请无管理员
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthCity(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: false, // 权益需要达到考核目标后激活
      benefitActivatedAt: null,
      benefitDeactivatedAt: null,
      benefitValidUntil: null,
      lastAssessmentMonth: null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 0,
      deletedAt: null,
      officePhotoUrls: params.officePhotoUrls ?? [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthCityCompanyGrantedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        cityCode: params.cityCode,
        cityName: params.cityName,
        authorizedBy: null, // 自助申请
      }),
    )

    return auth
  }

  // 工厂方法 - 创建正式市公司
  // 授权即激活，开始按月考核（30, 60, 120, 240, 480, 960, 1920, 3840, 2350）
  static createCityCompany(params: {
    userId: UserId
    cityCode: string
    cityName: string
    adminId: AdminUserId
    skipAssessment?: boolean  // 保留兼容，但不再影响激活状态
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.CITY_COMPANY,
      regionCode: RegionCode.create(params.cityCode),
      regionName: params.cityName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: params.cityName,
      authorizedAt: now,
      authorizedBy: params.adminId,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forCity(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: true,  // 授权即激活
      benefitActivatedAt: now,
      benefitDeactivatedAt: null,
      benefitValidUntil: AuthorizationRole.calculateBenefitValidUntil(now),
      lastAssessmentMonth: AuthorizationRole.getCurrentMonthString(now),
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 1,  // 从第1个月开始考核
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new CityCompanyAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        cityCode: params.cityCode,
        cityName: params.cityName,
        authorizedBy: params.adminId.value,
      }),
    )

    return auth
  }

  // 工厂方法 - 自动升级创建省区域（省团队伞下第一个累计达到5万棵）
  // 与手动授权 createProvinceCompany 完全一致，仅 authorizedBy 为 null
  static createAutoUpgradedProvinceCompany(params: {
    userId: UserId
    provinceCode: string
    provinceName: string
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.PROVINCE_COMPANY,
      regionCode: RegionCode.create(params.provinceCode),
      regionName: params.provinceName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: params.provinceName,
      authorizedAt: now,
      authorizedBy: null, // 自动升级无管理员
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forProvince(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: true,  // 授权即激活（与手动授权一致）
      benefitActivatedAt: now,
      benefitDeactivatedAt: null,
      benefitValidUntil: AuthorizationRole.calculateBenefitValidUntil(now),
      lastAssessmentMonth: AuthorizationRole.getCurrentMonthString(now),
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 1,  // 从第1个月开始考核（与手动授权一致）
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new ProvinceCompanyAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        provinceCode: params.provinceCode,
        provinceName: params.provinceName,
        authorizedBy: null, // 自动升级
      }),
    )

    return auth
  }

  // 工厂方法 - 自动升级创建市区域（市团队伞下第一个累计达到1万棵）
  // 与手动授权 createCityCompany 完全一致，仅 authorizedBy 为 null
  static createAutoUpgradedCityCompany(params: {
    userId: UserId
    cityCode: string
    cityName: string
  }): AuthorizationRole {
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.CITY_COMPANY,
      regionCode: RegionCode.create(params.cityCode),
      regionName: params.cityName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: params.cityName,
      authorizedAt: now,
      authorizedBy: null, // 自动升级无管理员
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forCity(),
      requireLocalPercentage: 0,
      exemptFromPercentageCheck: true,
      benefitActive: true,  // 授权即激活（与手动授权一致）
      benefitActivatedAt: now,
      benefitDeactivatedAt: null,
      benefitValidUntil: AuthorizationRole.calculateBenefitValidUntil(now),
      lastAssessmentMonth: AuthorizationRole.getCurrentMonthString(now),
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: 1,  // 从第1个月开始考核（与手动授权一致）
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new CityCompanyAuthorizedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        cityCode: params.cityCode,
        cityName: params.cityName,
        authorizedBy: null, // 自动升级
      }),
    )

    return auth
  }

  // 工厂方法 - Admin授权省团队
  static createAuthProvinceCompanyByAdmin(params: {
    userId: UserId
    provinceCode: string
    provinceName: string
    adminId: AdminUserId
    skipAssessment?: boolean
  }): AuthorizationRole {
    const skipAssessment = params.skipAssessment ?? false
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_PROVINCE_COMPANY,
      regionCode: RegionCode.create(params.provinceCode),
      regionName: params.provinceName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: `授权${params.provinceName}`,
      authorizedAt: now,
      authorizedBy: params.adminId,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthProvince(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: skipAssessment,
      benefitActivatedAt: skipAssessment ? now : null,
      benefitDeactivatedAt: null,
      benefitValidUntil: skipAssessment ? AuthorizationRole.calculateBenefitValidUntil(now) : null,
      lastAssessmentMonth: skipAssessment ? AuthorizationRole.getCurrentMonthString(now) : null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: skipAssessment ? 1 : 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthProvinceCompanyGrantedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        provinceCode: params.provinceCode,
        provinceName: params.provinceName,
        authorizedBy: params.adminId.value,
      }),
    )

    return auth
  }

  // 工厂方法 - Admin授权市团队
  static createAuthCityCompanyByAdmin(params: {
    userId: UserId
    cityCode: string
    cityName: string
    adminId: AdminUserId
    skipAssessment?: boolean
  }): AuthorizationRole {
    const skipAssessment = params.skipAssessment ?? false
    const now = new Date()
    const auth = new AuthorizationRole({
      authorizationId: AuthorizationId.generate(),
      userId: params.userId,
      roleType: RoleType.AUTH_CITY_COMPANY,
      regionCode: RegionCode.create(params.cityCode),
      regionName: params.cityName,
      status: AuthorizationStatus.AUTHORIZED,
      displayTitle: `授权${params.cityName}`,
      authorizedAt: now,
      authorizedBy: params.adminId,
      revokedAt: null,
      revokedBy: null,
      revokeReason: null,
      assessmentConfig: AssessmentConfig.forAuthCity(),
      requireLocalPercentage: 5.0,
      exemptFromPercentageCheck: false,
      benefitActive: skipAssessment,
      benefitActivatedAt: skipAssessment ? now : null,
      benefitDeactivatedAt: null,
      benefitValidUntil: skipAssessment ? AuthorizationRole.calculateBenefitValidUntil(now) : null,
      lastAssessmentMonth: skipAssessment ? AuthorizationRole.getCurrentMonthString(now) : null,
      monthlyTreesAdded: 0,
      lastMonthTreesAdded: 0,
      currentMonthIndex: skipAssessment ? 1 : 0,
      deletedAt: null,
      officePhotoUrls: [],
      createdAt: now,
      updatedAt: now,
    })

    auth.addDomainEvent(
      new AuthCityCompanyGrantedEvent({
        authorizationId: auth.authorizationId.value,
        userId: params.userId.value,
        cityCode: params.cityCode,
        cityName: params.cityName,
        authorizedBy: params.adminId.value,
      }),
    )

    return auth
  }

  // 核心领域行为

  /**
   * 激活权益（初始考核达标后）
   * 设置有效期为当前月 + 下月末
   */
  activateBenefit(): void {
    if (this._benefitActive) {
      throw new DomainError('权益已激活')
    }

    const now = new Date()
    this._status = AuthorizationStatus.AUTHORIZED
    this._benefitActive = true
    this._benefitActivatedAt = now
    this._benefitValidUntil = AuthorizationRole.calculateBenefitValidUntil(now)
    this._lastAssessmentMonth = AuthorizationRole.getCurrentMonthString(now)
    this._monthlyTreesAdded = 0
    this._currentMonthIndex = 1
    this._updatedAt = now

    this.addDomainEvent(
      new BenefitActivatedEvent({
        authorizationId: this._authorizationId.value,
        userId: this._userId.value,
        roleType: this._roleType,
        regionCode: this._regionCode.value,
      }),
    )
  }

  /**
   * 失效权益（月度考核不达标）
   * 重置所有考核相关字段
   */
  deactivateBenefit(reason: string): void {
    if (!this._benefitActive) {
      return
    }

    const now = new Date()
    this._benefitActive = false
    this._benefitDeactivatedAt = now
    this._benefitValidUntil = null
    this._lastAssessmentMonth = null
    this._monthlyTreesAdded = 0
    this._lastMonthTreesAdded = 0
    this._currentMonthIndex = 0 // 重置月份索引
    this._updatedAt = now

    this.addDomainEvent(
      new BenefitDeactivatedEvent({
        authorizationId: this._authorizationId.value,
        userId: this._userId.value,
        roleType: this._roleType,
        reason,
      }),
    )
  }

  /**
   * 续期权益（月度考核达标后）
   * 延长有效期到下下月末
   *
   * 注意：不修改 monthlyTreesAdded，因为：
   * - treesAdded 是上月的考核完成数（来自 lastMonthTreesAdded）
   * - monthlyTreesAdded 是当月累计器，已被月初存档重置为 0
   * - 当月新增的树会通过 addMonthlyTrees() 累加
   */
  renewBenefit(_treesAdded: number): void {
    if (!this._benefitActive) {
      throw new DomainError('权益未激活，无法续期')
    }

    const now = new Date()
    this._benefitValidUntil = AuthorizationRole.calculateBenefitValidUntil(now)
    this._lastAssessmentMonth = AuthorizationRole.getCurrentMonthString(now)
    this._currentMonthIndex += 1  // 考核月份索引递增
    this._updatedAt = now
  }

  /**
   * 增加月度新增树数
   */
  addMonthlyTrees(treeCount: number): void {
    this._monthlyTreesAdded += treeCount
    this._updatedAt = new Date()
  }

  /**
   * 存档并重置月度新增树数（每月1日0:00调用）
   * 将当月数据存档到 lastMonthTreesAdded，然后重置当月计数器
   */
  archiveAndResetMonthlyTrees(): void {
    this._lastMonthTreesAdded = this._monthlyTreesAdded  // 存档
    this._monthlyTreesAdded = 0  // 重置
    this._updatedAt = new Date()
  }

  /**
   * 获取用于考核的树数
   * 根据 benefitValidUntil 判断使用上月还是当月数据
   * - 如果有效期在上月末或更早 → 用 lastMonthTreesAdded
   * - 如果有效期在当月末 → 用 monthlyTreesAdded
   */
  getTreesForAssessment(checkDate: Date = new Date()): number {
    if (!this._benefitValidUntil) return 0

    const validUntilMonth = this._benefitValidUntil.getMonth()
    const validUntilYear = this._benefitValidUntil.getFullYear()
    const checkMonth = checkDate.getMonth()
    const checkYear = checkDate.getFullYear()

    // 如果有效期年月 < 检查年月，说明有效期在上月或更早
    if (validUntilYear < checkYear ||
        (validUntilYear === checkYear && validUntilMonth < checkMonth)) {
      // 有效期在上月末或更早 → 用存档数据
      return this._lastMonthTreesAdded
    } else {
      // 有效期在当月末 → 用当月数据
      return this._monthlyTreesAdded
    }
  }

  /**
   * @deprecated 使用 archiveAndResetMonthlyTrees 代替
   */
  resetMonthlyTrees(): void {
    this.archiveAndResetMonthlyTrees()
  }

  /**
   * 检查权益是否已过期
   */
  isBenefitExpired(checkDate: Date = new Date()): boolean {
    if (!this._benefitActive || !this._benefitValidUntil) {
      return false
    }
    return checkDate > this._benefitValidUntil
  }

  /**
   * 管理员授权
   */
  authorize(adminId: AdminUserId): void {
    if (this._status === AuthorizationStatus.AUTHORIZED) {
      throw new DomainError('已授权，无需重复授权')
    }

    this._status = AuthorizationStatus.AUTHORIZED
    this._authorizedAt = new Date()
    this._authorizedBy = adminId
    this._updatedAt = new Date()

    this.addDomainEvent(
      new RoleAuthorizedEvent({
        authorizationId: this._authorizationId.value,
        userId: this._userId.value,
        roleType: this._roleType,
        regionCode: this._regionCode.value,
        authorizedBy: adminId.value,
      }),
    )
  }

  /**
   * 撤销授权
   * 软删除: 设置 deletedAt 使记录在查询时被过滤 (大厂通用做法)
   */
  revoke(adminId: AdminUserId, reason: string): void {
    if (this._status === AuthorizationStatus.REVOKED) {
      throw new DomainError('已撤销')
    }

    const now = new Date()
    this._status = AuthorizationStatus.REVOKED
    this._revokedAt = now
    this._revokedBy = adminId
    this._revokeReason = reason
    this._benefitActive = false
    this._benefitDeactivatedAt = now
    this._deletedAt = now  // 软删除: 允许将来重新创建相同 accountSequence + roleType + regionCode 的授权
    this._updatedAt = now

    this.addDomainEvent(
      new RoleRevokedEvent({
        authorizationId: this._authorizationId.value,
        userId: this._userId.value,
        roleType: this._roleType,
        regionCode: this._regionCode.value,
        reason,
        revokedBy: adminId.value,
      }),
    )
  }

  /**
   * 豁免占比考核
   */
  exemptLocalPercentageCheck(adminId: AdminUserId): void {
    this._exemptFromPercentageCheck = true
    this._updatedAt = new Date()

    this.addDomainEvent(
      new PercentageCheckExemptedEvent({
        authorizationId: this._authorizationId.value,
        userId: this._userId.value,
        exemptedBy: adminId.value,
      }),
    )
  }

  /**
   * 取消豁免占比考核
   */
  cancelExemptLocalPercentageCheck(): void {
    this._exemptFromPercentageCheck = false
    this._updatedAt = new Date()
  }

  /**
   * 递增考核月份
   */
  incrementMonthIndex(): void {
    this._currentMonthIndex += 1
    this._updatedAt = new Date()
  }

  /**
   * 获取初始考核目标
   */
  getInitialTarget(): number {
    return this._assessmentConfig.initialTargetTreeCount
  }

  /**
   * 检查是否需要占比考核
   */
  needsLocalPercentageCheck(): boolean {
    return (
      !this._exemptFromPercentageCheck &&
      this._requireLocalPercentage > 0 &&
      (this._roleType === RoleType.AUTH_PROVINCE_COMPANY ||
        this._roleType === RoleType.AUTH_CITY_COMPANY)
    )
  }

  /**
   * 检查是否需要阶梯考核
   */
  needsLadderAssessment(): boolean {
    return this._assessmentConfig.monthlyTargetType === MonthlyTargetType.LADDER
  }

  /**
   * 检查是否需要固定月度考核
   */
  needsFixedAssessment(): boolean {
    return this._assessmentConfig.monthlyTargetType === MonthlyTargetType.FIXED
  }

  /**
   * 转换为持久化数据
   */
  toPersistence(): Record<string, any> {
    return {
      id: this._authorizationId.value,
      userId: this._userId.accountSequence,
      accountSequence: this._userId.accountSequence,
      roleType: this._roleType,
      regionCode: this._regionCode.value,
      regionName: this._regionName,
      status: this._status,
      displayTitle: this._displayTitle,
      authorizedAt: this._authorizedAt,
      authorizedBy: this._authorizedBy?.accountSequence || null,
      revokedAt: this._revokedAt,
      revokedBy: this._revokedBy?.accountSequence || null,
      revokeReason: this._revokeReason,
      initialTargetTreeCount: this._assessmentConfig.initialTargetTreeCount,
      monthlyTargetType: this._assessmentConfig.monthlyTargetType,
      requireLocalPercentage: this._requireLocalPercentage,
      exemptFromPercentageCheck: this._exemptFromPercentageCheck,
      benefitActive: this._benefitActive,
      benefitActivatedAt: this._benefitActivatedAt,
      benefitDeactivatedAt: this._benefitDeactivatedAt,
      benefitValidUntil: this._benefitValidUntil,
      lastAssessmentMonth: this._lastAssessmentMonth,
      monthlyTreesAdded: this._monthlyTreesAdded,
      lastMonthTreesAdded: this._lastMonthTreesAdded,
      currentMonthIndex: this._currentMonthIndex,
      officePhotoUrls: this._officePhotoUrls,
      deletedAt: this._deletedAt,
      createdAt: this._createdAt,
      updatedAt: this._updatedAt,
    }
  }
}
