import { Injectable, Logger } from '@nestjs/common';
import { OutboxRepository } from '../../infrastructure/persistence/repositories/outbox.repository';
import { ContributionDistributionResult } from '../../domain/services/contribution-calculator.service';
import { SyncedAdoption } from '../../domain/repositories/synced-data.repository.interface';

/**
 * 贡献值分配结果发布服务
 * 将计算完成的分配结果发布到 Kafka，供 mining-wallet-service 消费
 */
@Injectable()
export class ContributionDistributionPublisherService {
  private readonly logger = new Logger(
    ContributionDistributionPublisherService.name,
  );

  constructor(private readonly outboxRepository: OutboxRepository) {}

  /**
   * 发布分配结果到 Kafka
   */
  async publishDistributionResult(
    adoption: SyncedAdoption,
    result: ContributionDistributionResult,
    provinceCode: string,
    cityCode: string,
  ): Promise<void> {
    const eventId = `dist-${adoption.originalAdoptionId}-${Date.now()}`;

    const payload = {
      eventType: 'ContributionDistributionCompleted',
      eventId,
      timestamp: new Date().toISOString(),
      payload: {
        // 认种信息
        adoptionId: adoption.originalAdoptionId.toString(),
        adopterAccountSequence: adoption.accountSequence,
        treeCount: adoption.treeCount,
        adoptionDate: adoption.adoptionDate.toISOString(),

        // 用户贡献值分配
        userContributions: this.mapUserContributions(result),

        // 系统账户分配
        systemContributions: this.mapSystemContributions(
          result,
          provinceCode,
          cityCode,
        ),

        // 未分配（归总部）
        unallocatedToHeadquarters: this.mapUnallocated(result),
      },
    };

    await this.outboxRepository.save({
      eventType: 'ContributionDistributionCompleted',
      topic: 'contribution.distribution.completed',
      key: adoption.accountSequence,
      payload,
      aggregateId: adoption.originalAdoptionId.toString(),
      aggregateType: 'Adoption',
    });

    this.logger.debug(
      `Published distribution result for adoption ${adoption.originalAdoptionId}`,
    );
  }

  private mapUserContributions(result: ContributionDistributionResult): any[] {
    const contributions: any[] = [];

    // 个人贡献
    if (result.personalRecord) {
      contributions.push({
        accountSequence: result.personalRecord.accountSequence,
        contributionType: 'PERSONAL',
        amount: result.personalRecord.amount.value.toString(),
        effectiveDate: result.personalRecord.effectiveDate.toISOString(),
        expireDate: result.personalRecord.expireDate.toISOString(),
        sourceAdoptionId: result.personalRecord.sourceAdoptionId.toString(),
        sourceAccountSequence: result.personalRecord.sourceAccountSequence,
      });
    }

    // 团队层级贡献
    for (const record of result.teamLevelRecords) {
      contributions.push({
        accountSequence: record.accountSequence,
        contributionType: 'TEAM_LEVEL',
        amount: record.amount.value.toString(),
        levelDepth: record.levelDepth,
        effectiveDate: record.effectiveDate.toISOString(),
        expireDate: record.expireDate.toISOString(),
        sourceAdoptionId: record.sourceAdoptionId.toString(),
        sourceAccountSequence: record.sourceAccountSequence,
      });
    }

    // 团队奖励贡献
    for (const record of result.teamBonusRecords) {
      contributions.push({
        accountSequence: record.accountSequence,
        contributionType: 'TEAM_BONUS',
        amount: record.amount.value.toString(),
        bonusTier: record.bonusTier,
        effectiveDate: record.effectiveDate.toISOString(),
        expireDate: record.expireDate.toISOString(),
        sourceAdoptionId: record.sourceAdoptionId.toString(),
        sourceAccountSequence: record.sourceAccountSequence,
      });
    }

    return contributions;
  }

  private mapSystemContributions(
    result: ContributionDistributionResult,
    provinceCode: string,
    cityCode: string,
  ): any[] {
    return result.systemContributions.map((sys) => ({
      accountType: sys.accountType,
      amount: sys.amount.value.toString(),
      // 省份代码：PROVINCE 用自己的 regionCode，CITY 需要传递省份代码用于创建省份
      provinceCode:
        sys.accountType === 'PROVINCE'
          ? sys.regionCode || provinceCode
          : sys.accountType === 'CITY'
            ? provinceCode  // CITY 需要省份代码来创建省份（如果省份不存在）
            : undefined,
      // 城市代码：只有 CITY 类型有
      cityCode:
        sys.accountType === 'CITY' ? sys.regionCode || cityCode : undefined,
      neverExpires: sys.accountType === 'OPERATION', // 运营账户永不过期
    }));
  }

  private mapUnallocated(result: ContributionDistributionResult): any[] {
    return result.unallocatedContributions.map((u) => ({
      reason: u.reason,
      amount: u.amount.value.toString(),
      wouldBeAccountSequence: u.wouldBeAccountSequence,
      levelDepth: u.levelDepth,
      bonusTier: u.type.startsWith('BONUS_TIER_')
        ? parseInt(u.type.split('_')[2])
        : undefined,
    }));
  }
}
