import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Kafka, Consumer, logLevel, EachMessagePayload } from 'kafkajs';
import { PrismaService } from '../persistence/prisma/prisma.service';
import { Decimal } from '@prisma/client/runtime/library';

/**
 * Debezium CDC 事件结构 (经过 ExtractNewRecordState 转换后)
 */

// authorization_roles 表
interface CdcAuthorizationRolePayload {
  id: string;
  user_id: string;
  account_sequence: string;
  role_type: string;
  region_code: string;
  region_name: string;
  status: string;
  display_title: string;
  authorized_at?: string | null;
  authorized_by?: string | null;
  revoked_at?: string | null;
  revoked_by?: string | null;
  deleted_at?: string | null;
  initial_target_tree_count: number;
  monthly_target_type: string;
  benefit_active: boolean;
  benefit_activated_at?: string | null;
  last_assessment_month?: string | null;
  monthly_trees_added: number;
  created_at: string;
  __op: 'c' | 'u' | 'd' | 'r';
  __table: string;
  __source_ts_ms: number;
  __deleted?: string;
}

// monthly_assessments 表
interface CdcMonthlyAssessmentPayload {
  id: string;
  authorization_id: string;
  user_id: string;
  account_sequence: string;
  role_type: string;
  region_code: string;
  assessment_month: string;
  month_index: number;
  monthly_target: number;
  cumulative_target: number;
  monthly_completed: number;
  cumulative_completed: number;
  completed_at?: string | null;
  result: string;
  ranking_in_region?: number | null;
  is_first_place: boolean;
  is_bypassed: boolean;
  assessed_at?: string | null;
  created_at: string;
  __op: 'c' | 'u' | 'd' | 'r';
  __table: string;
  __source_ts_ms: number;
  __deleted?: string;
}

// system_account_ledgers 表 (系统账户分类账流水)
interface CdcSystemAccountLedgerPayload {
  ledger_id: string;
  account_id: string;
  entry_type: string;
  amount: string;
  balance_after: string;
  source_order_id?: string | null;
  source_reward_id?: string | null;
  tx_hash?: string | null;
  memo?: string | null;
  created_at: string;
  __op: 'c' | 'u' | 'd' | 'r';
  __table: string;
  __source_ts_ms: number;
  __deleted?: string;
}

// system_accounts 表
interface CdcSystemAccountPayload {
  account_id: string;
  account_type: string;
  region_code?: string | null;
  region_name?: string | null;
  wallet_address?: string | null;
  usdt_balance: string;
  hashpower: string;
  total_received: string;
  total_transferred: string;
  status: string;
  created_at: string;
  __op: 'c' | 'u' | 'd' | 'r';
  __table: string;
  __source_ts_ms: number;
  __deleted?: string;
}

// benefit_assessment_records 表 (权益考核记录)
interface CdcBenefitAssessmentRecordPayload {
  id: string;
  authorization_id: string;
  user_id: string;
  account_sequence: string;
  role_type: string;
  region_code: string;
  region_name: string;
  assessment_month: string;
  month_index: number;
  monthly_target: number;
  cumulative_target: number;
  trees_completed: number;
  trees_required: number;
  benefit_action_taken: string;
  previous_benefit_status: boolean;
  new_benefit_status: boolean;
  new_valid_until?: string | null;
  result: string;
  remarks?: string | null;
  assessed_at: string;
  created_at: string;
  __op: 'c' | 'u' | 'd' | 'r';
  __table: string;
  __source_ts_ms: number;
  __deleted?: string;
}

type CdcAuthorizationPayload = CdcAuthorizationRolePayload | CdcMonthlyAssessmentPayload | CdcSystemAccountLedgerPayload | CdcSystemAccountPayload | CdcBenefitAssessmentRecordPayload;

/**
 * Authorization CDC 消费者服务
 *
 * 消费 Debezium 从 authorization-service PostgreSQL 捕获的数据变更
 *
 * Topics:
 * - cdc.authorization.public.authorization_roles
 * - cdc.authorization.public.monthly_assessments
 * - cdc.authorization.public.system_accounts
 */
@Injectable()
export class AuthorizationCdcConsumerService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(AuthorizationCdcConsumerService.name);
  private kafka: Kafka;
  private consumer: Consumer;
  private isRunning = false;

  // CDC Topics
  private readonly cdcTopics = [
    'cdc.authorization.public.authorization_roles',
    'cdc.authorization.public.monthly_assessments',
    'cdc.authorization.public.system_accounts',
    'cdc.authorization.public.system_account_ledgers',
    'cdc.authorization.public.benefit_assessment_records',
  ];
  private readonly consumerGroup: string;

  constructor(
    private readonly configService: ConfigService,
    private readonly prisma: PrismaService,
  ) {
    const brokers = (this.configService.get<string>('KAFKA_BROKERS', 'localhost:9092')).split(',');
    const clientId = this.configService.get<string>('KAFKA_CLIENT_ID', 'admin-service');
    this.consumerGroup = this.configService.get<string>('KAFKA_AUTHORIZATION_CDC_GROUP', 'admin-service-authorization-cdc');

    this.kafka = new Kafka({
      clientId: `${clientId}-authorization-cdc`,
      brokers,
      logLevel: logLevel.WARN,
    });

    this.consumer = this.kafka.consumer({ groupId: this.consumerGroup });

    this.logger.log(`[Authorization-CDC] Configured to consume topics: ${this.cdcTopics.join(', ')}`);
  }

  async onModuleInit() {
    await this.start();
  }

  async onModuleDestroy() {
    await this.stop();
  }

  async start(): Promise<void> {
    if (this.isRunning) {
      this.logger.warn('[Authorization-CDC] Consumer already running');
      return;
    }

    try {
      this.logger.log('[Authorization-CDC] Connecting to Kafka...');
      await this.consumer.connect();

      for (const topic of this.cdcTopics) {
        await this.consumer.subscribe({
          topic,
          fromBeginning: false,
        });
      }

      this.logger.log(`[Authorization-CDC] Subscribed to topics: ${this.cdcTopics.join(', ')}`);

      await this.consumer.run({
        eachMessage: async (payload: EachMessagePayload) => {
          await this.handleMessage(payload);
        },
      });

      this.isRunning = true;
      this.logger.log('[Authorization-CDC] Consumer started successfully');
    } catch (error) {
      this.logger.error('[Authorization-CDC] Failed to start consumer:', error);
    }
  }

  async stop(): Promise<void> {
    if (!this.isRunning) return;

    try {
      await this.consumer.disconnect();
      this.isRunning = false;
      this.logger.log('[Authorization-CDC] Consumer stopped');
    } catch (error) {
      this.logger.error('[Authorization-CDC] Failed to stop consumer:', error);
    }
  }

  private async handleMessage(payload: EachMessagePayload): Promise<void> {
    const { topic, partition, message } = payload;

    if (!message.value) {
      this.logger.warn(`[Authorization-CDC] Empty message from ${topic}:${partition}`);
      return;
    }

    try {
      const data = JSON.parse(message.value.toString()) as CdcAuthorizationPayload;
      const operation = data.__op;
      const table = data.__table;

      this.logger.debug(
        `[Authorization-CDC] Received ${operation} event for table ${table}`
      );

      // 幂等性检查
      const eventId = `authorization-cdc:${topic}:${partition}:${message.offset}`;
      if (await this.isEventProcessed(eventId)) {
        this.logger.debug(`[Authorization-CDC] Event ${eventId} already processed, skipping`);
        return;
      }

      // 根据表名处理不同的事件
      switch (table) {
        case 'authorization_roles':
          await this.processAuthorizationRoleEvent(data as CdcAuthorizationRolePayload);
          break;
        case 'monthly_assessments':
          await this.processMonthlyAssessmentEvent(data as CdcMonthlyAssessmentPayload);
          break;
        case 'system_accounts':
          await this.processSystemAccountEvent(data as CdcSystemAccountPayload);
          break;
        case 'system_account_ledgers':
          await this.processSystemAccountLedgerEvent(data as CdcSystemAccountLedgerPayload);
          break;
        case 'benefit_assessment_records':
          await this.processBenefitAssessmentRecordEvent(data as CdcBenefitAssessmentRecordPayload);
          break;
        default:
          this.logger.warn(`[Authorization-CDC] Unknown table: ${table}`);
      }

      // 记录已处理
      await this.markEventProcessed(eventId, `authorization-cdc:${table}:${operation}`);

      this.logger.log(
        `[Authorization-CDC] ✓ Processed ${operation} for table: ${table}`
      );
    } catch (error) {
      this.logger.error(`[Authorization-CDC] Failed to process message:`, error);
      throw error; // 让 KafkaJS 重试
    }
  }

  // ==================== authorization_roles 处理 ====================

  private async processAuthorizationRoleEvent(data: CdcAuthorizationRolePayload): Promise<void> {
    const operation = data.__op;
    const isDeleted = data.__deleted === 'true';

    if (operation === 'd' || isDeleted) {
      await this.handleAuthorizationRoleDelete(data);
    } else if (operation === 'c' || operation === 'r') {
      await this.handleAuthorizationRoleCreateOrSnapshot(data);
    } else if (operation === 'u') {
      await this.handleAuthorizationRoleUpdate(data);
    }
  }

  private async handleAuthorizationRoleCreateOrSnapshot(data: CdcAuthorizationRolePayload): Promise<void> {
    await this.prisma.authorizationRoleQueryView.upsert({
      where: { id: data.id },
      create: {
        id: data.id,
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        regionName: data.region_name,
        status: data.status,
        displayTitle: data.display_title,
        authorizedAt: data.authorized_at ? new Date(data.authorized_at) : null,
        authorizedBy: data.authorized_by || null,
        revokedAt: data.revoked_at ? new Date(data.revoked_at) : null,
        revokedBy: data.revoked_by || null,
        deletedAt: data.deleted_at ? new Date(data.deleted_at) : null,
        initialTargetTreeCount: data.initial_target_tree_count,
        monthlyTargetType: data.monthly_target_type,
        benefitActive: data.benefit_active,
        benefitActivatedAt: data.benefit_activated_at ? new Date(data.benefit_activated_at) : null,
        lastAssessmentMonth: data.last_assessment_month || null,
        monthlyTreesAdded: data.monthly_trees_added,
        createdAt: new Date(data.created_at),
        syncedAt: new Date(),
      },
      update: {
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        regionName: data.region_name,
        status: data.status,
        displayTitle: data.display_title,
        authorizedAt: data.authorized_at ? new Date(data.authorized_at) : null,
        authorizedBy: data.authorized_by || null,
        revokedAt: data.revoked_at ? new Date(data.revoked_at) : null,
        revokedBy: data.revoked_by || null,
        deletedAt: data.deleted_at ? new Date(data.deleted_at) : null,
        initialTargetTreeCount: data.initial_target_tree_count,
        monthlyTargetType: data.monthly_target_type,
        benefitActive: data.benefit_active,
        benefitActivatedAt: data.benefit_activated_at ? new Date(data.benefit_activated_at) : null,
        lastAssessmentMonth: data.last_assessment_month || null,
        monthlyTreesAdded: data.monthly_trees_added,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Created/Snapshot authorization role: ${data.id}`);
  }

  private async handleAuthorizationRoleUpdate(data: CdcAuthorizationRolePayload): Promise<void> {
    const exists = await this.prisma.authorizationRoleQueryView.findUnique({
      where: { id: data.id },
      select: { id: true },
    });

    if (!exists) {
      await this.handleAuthorizationRoleCreateOrSnapshot(data);
      return;
    }

    await this.prisma.authorizationRoleQueryView.update({
      where: { id: data.id },
      data: {
        status: data.status,
        authorizedAt: data.authorized_at ? new Date(data.authorized_at) : null,
        authorizedBy: data.authorized_by || null,
        revokedAt: data.revoked_at ? new Date(data.revoked_at) : null,
        revokedBy: data.revoked_by || null,
        deletedAt: data.deleted_at ? new Date(data.deleted_at) : null,
        benefitActive: data.benefit_active,
        benefitActivatedAt: data.benefit_activated_at ? new Date(data.benefit_activated_at) : null,
        lastAssessmentMonth: data.last_assessment_month || null,
        monthlyTreesAdded: data.monthly_trees_added,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Updated authorization role: ${data.id}`);
  }

  private async handleAuthorizationRoleDelete(data: CdcAuthorizationRolePayload): Promise<void> {
    try {
      await this.prisma.authorizationRoleQueryView.delete({
        where: { id: data.id },
      });
      this.logger.log(`[Authorization-CDC] Deleted authorization role: ${data.id}`);
    } catch {
      this.logger.warn(`[Authorization-CDC] Authorization role not found for delete: ${data.id}`);
    }
  }

  // ==================== monthly_assessments 处理 ====================

  private async processMonthlyAssessmentEvent(data: CdcMonthlyAssessmentPayload): Promise<void> {
    const operation = data.__op;
    const isDeleted = data.__deleted === 'true';

    if (operation === 'd' || isDeleted) {
      await this.handleMonthlyAssessmentDelete(data);
    } else if (operation === 'c' || operation === 'r') {
      await this.handleMonthlyAssessmentCreateOrSnapshot(data);
    } else if (operation === 'u') {
      await this.handleMonthlyAssessmentUpdate(data);
    }
  }

  private async handleMonthlyAssessmentCreateOrSnapshot(data: CdcMonthlyAssessmentPayload): Promise<void> {
    await this.prisma.monthlyAssessmentQueryView.upsert({
      where: { id: data.id },
      create: {
        id: data.id,
        authorizationId: data.authorization_id,
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        assessmentMonth: data.assessment_month,
        monthIndex: data.month_index,
        monthlyTarget: data.monthly_target,
        cumulativeTarget: data.cumulative_target,
        monthlyCompleted: data.monthly_completed,
        cumulativeCompleted: data.cumulative_completed,
        completedAt: data.completed_at ? new Date(data.completed_at) : null,
        result: data.result,
        rankingInRegion: data.ranking_in_region || null,
        isFirstPlace: data.is_first_place,
        isBypassed: data.is_bypassed,
        assessedAt: data.assessed_at ? new Date(data.assessed_at) : null,
        createdAt: new Date(data.created_at),
        syncedAt: new Date(),
      },
      update: {
        authorizationId: data.authorization_id,
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        assessmentMonth: data.assessment_month,
        monthIndex: data.month_index,
        monthlyTarget: data.monthly_target,
        cumulativeTarget: data.cumulative_target,
        monthlyCompleted: data.monthly_completed,
        cumulativeCompleted: data.cumulative_completed,
        completedAt: data.completed_at ? new Date(data.completed_at) : null,
        result: data.result,
        rankingInRegion: data.ranking_in_region || null,
        isFirstPlace: data.is_first_place,
        isBypassed: data.is_bypassed,
        assessedAt: data.assessed_at ? new Date(data.assessed_at) : null,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Created/Snapshot monthly assessment: ${data.id}`);
  }

  private async handleMonthlyAssessmentUpdate(data: CdcMonthlyAssessmentPayload): Promise<void> {
    const exists = await this.prisma.monthlyAssessmentQueryView.findUnique({
      where: { id: data.id },
      select: { id: true },
    });

    if (!exists) {
      await this.handleMonthlyAssessmentCreateOrSnapshot(data);
      return;
    }

    await this.prisma.monthlyAssessmentQueryView.update({
      where: { id: data.id },
      data: {
        monthlyCompleted: data.monthly_completed,
        cumulativeCompleted: data.cumulative_completed,
        completedAt: data.completed_at ? new Date(data.completed_at) : null,
        result: data.result,
        rankingInRegion: data.ranking_in_region || null,
        isFirstPlace: data.is_first_place,
        isBypassed: data.is_bypassed,
        assessedAt: data.assessed_at ? new Date(data.assessed_at) : null,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Updated monthly assessment: ${data.id}`);
  }

  private async handleMonthlyAssessmentDelete(data: CdcMonthlyAssessmentPayload): Promise<void> {
    try {
      await this.prisma.monthlyAssessmentQueryView.delete({
        where: { id: data.id },
      });
      this.logger.log(`[Authorization-CDC] Deleted monthly assessment: ${data.id}`);
    } catch {
      this.logger.warn(`[Authorization-CDC] Monthly assessment not found for delete: ${data.id}`);
    }
  }

  // ==================== system_accounts 处理 ====================

  private async processSystemAccountEvent(data: CdcSystemAccountPayload): Promise<void> {
    const operation = data.__op;
    const isDeleted = data.__deleted === 'true';

    if (operation === 'd' || isDeleted) {
      await this.handleSystemAccountDelete(data);
    } else if (operation === 'c' || operation === 'r') {
      await this.handleSystemAccountCreateOrSnapshot(data);
    } else if (operation === 'u') {
      await this.handleSystemAccountUpdate(data);
    }
  }

  private async handleSystemAccountCreateOrSnapshot(data: CdcSystemAccountPayload): Promise<void> {
    await this.prisma.systemAccountQueryView.upsert({
      where: { id: BigInt(data.account_id) },
      create: {
        id: BigInt(data.account_id),
        accountType: data.account_type,
        regionCode: data.region_code || null,
        regionName: data.region_name || null,
        walletAddress: data.wallet_address || null,
        usdtBalance: new Decimal(data.usdt_balance || '0'),
        hashpower: new Decimal(data.hashpower || '0'),
        totalReceived: new Decimal(data.total_received || '0'),
        totalTransferred: new Decimal(data.total_transferred || '0'),
        status: data.status,
        createdAt: new Date(data.created_at),
        syncedAt: new Date(),
      },
      update: {
        accountType: data.account_type,
        regionCode: data.region_code || null,
        regionName: data.region_name || null,
        walletAddress: data.wallet_address || null,
        usdtBalance: new Decimal(data.usdt_balance || '0'),
        hashpower: new Decimal(data.hashpower || '0'),
        totalReceived: new Decimal(data.total_received || '0'),
        totalTransferred: new Decimal(data.total_transferred || '0'),
        status: data.status,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Created/Snapshot system account: ${data.account_id} (${data.account_type})`);
  }

  private async handleSystemAccountUpdate(data: CdcSystemAccountPayload): Promise<void> {
    const id = BigInt(data.account_id);
    const exists = await this.prisma.systemAccountQueryView.findUnique({
      where: { id },
      select: { id: true },
    });

    if (!exists) {
      await this.handleSystemAccountCreateOrSnapshot(data);
      return;
    }

    await this.prisma.systemAccountQueryView.update({
      where: { id },
      data: {
        walletAddress: data.wallet_address || null,
        usdtBalance: new Decimal(data.usdt_balance || '0'),
        hashpower: new Decimal(data.hashpower || '0'),
        totalReceived: new Decimal(data.total_received || '0'),
        totalTransferred: new Decimal(data.total_transferred || '0'),
        status: data.status,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Updated system account: ${data.account_id} (${data.account_type})`);
  }

  private async handleSystemAccountDelete(data: CdcSystemAccountPayload): Promise<void> {
    const id = BigInt(data.account_id);

    try {
      await this.prisma.systemAccountQueryView.delete({
        where: { id },
      });
      this.logger.log(`[Authorization-CDC] Deleted system account: ${data.account_id}`);
    } catch {
      this.logger.warn(`[Authorization-CDC] System account not found for delete: ${data.account_id}`);
    }
  }

  // ==================== system_account_ledgers 处理 ====================

  private async processSystemAccountLedgerEvent(data: CdcSystemAccountLedgerPayload): Promise<void> {
    const operation = data.__op;
    const isDeleted = data.__deleted === 'true';

    // 系统账户流水是 append-only，通常只有 create 和 snapshot
    if (operation === 'd' || isDeleted) {
      await this.handleSystemAccountLedgerDelete(data);
    } else if (operation === 'c' || operation === 'r') {
      await this.handleSystemAccountLedgerCreate(data);
    } else if (operation === 'u') {
      await this.handleSystemAccountLedgerUpdate(data);
    }
  }

  private async handleSystemAccountLedgerCreate(data: CdcSystemAccountLedgerPayload): Promise<void> {
    await this.prisma.systemAccountLedgerView.upsert({
      where: { id: BigInt(data.ledger_id) },
      create: {
        id: BigInt(data.ledger_id),
        accountId: BigInt(data.account_id),
        entryType: data.entry_type,
        amount: new Decimal(data.amount),
        balanceAfter: new Decimal(data.balance_after),
        sourceOrderId: data.source_order_id ? BigInt(data.source_order_id) : null,
        sourceRewardId: data.source_reward_id ? BigInt(data.source_reward_id) : null,
        txHash: data.tx_hash || null,
        memo: data.memo || null,
        createdAt: new Date(data.created_at),
        syncedAt: new Date(),
      },
      update: {
        accountId: BigInt(data.account_id),
        entryType: data.entry_type,
        amount: new Decimal(data.amount),
        balanceAfter: new Decimal(data.balance_after),
        sourceOrderId: data.source_order_id ? BigInt(data.source_order_id) : null,
        sourceRewardId: data.source_reward_id ? BigInt(data.source_reward_id) : null,
        txHash: data.tx_hash || null,
        memo: data.memo || null,
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Created system account ledger: ${data.ledger_id} (${data.entry_type})`);
  }

  private async handleSystemAccountLedgerUpdate(data: CdcSystemAccountLedgerPayload): Promise<void> {
    await this.handleSystemAccountLedgerCreate(data);
    this.logger.log(`[Authorization-CDC] Updated system account ledger: ${data.ledger_id}`);
  }

  private async handleSystemAccountLedgerDelete(data: CdcSystemAccountLedgerPayload): Promise<void> {
    const id = BigInt(data.ledger_id);

    try {
      await this.prisma.systemAccountLedgerView.delete({
        where: { id },
      });
      this.logger.log(`[Authorization-CDC] Deleted system account ledger: ${data.ledger_id}`);
    } catch {
      this.logger.warn(`[Authorization-CDC] System account ledger not found for delete: ${data.ledger_id}`);
    }
  }

  // ==================== benefit_assessment_records 处理 ====================

  private async processBenefitAssessmentRecordEvent(data: CdcBenefitAssessmentRecordPayload): Promise<void> {
    const operation = data.__op;
    const isDeleted = data.__deleted === 'true';

    if (operation === 'd' || isDeleted) {
      await this.handleBenefitAssessmentRecordDelete(data);
    } else if (operation === 'c' || operation === 'r') {
      await this.handleBenefitAssessmentRecordCreateOrSnapshot(data);
    } else if (operation === 'u') {
      await this.handleBenefitAssessmentRecordUpdate(data);
    }
  }

  private async handleBenefitAssessmentRecordCreateOrSnapshot(data: CdcBenefitAssessmentRecordPayload): Promise<void> {
    await this.prisma.benefitAssessmentQueryView.upsert({
      where: { id: data.id },
      create: {
        id: data.id,
        authorizationId: data.authorization_id,
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        regionName: data.region_name,
        assessmentMonth: data.assessment_month,
        monthIndex: data.month_index,
        monthlyTarget: data.monthly_target,
        cumulativeTarget: data.cumulative_target,
        treesCompleted: data.trees_completed,
        treesRequired: data.trees_required,
        benefitActionTaken: data.benefit_action_taken,
        previousBenefitStatus: data.previous_benefit_status,
        newBenefitStatus: data.new_benefit_status,
        newValidUntil: data.new_valid_until ? new Date(data.new_valid_until) : null,
        result: data.result,
        remarks: data.remarks || null,
        assessedAt: new Date(data.assessed_at),
        createdAt: new Date(data.created_at),
        syncedAt: new Date(),
      },
      update: {
        authorizationId: data.authorization_id,
        userId: data.user_id,
        accountSequence: data.account_sequence,
        roleType: data.role_type,
        regionCode: data.region_code,
        regionName: data.region_name,
        assessmentMonth: data.assessment_month,
        monthIndex: data.month_index,
        monthlyTarget: data.monthly_target,
        cumulativeTarget: data.cumulative_target,
        treesCompleted: data.trees_completed,
        treesRequired: data.trees_required,
        benefitActionTaken: data.benefit_action_taken,
        previousBenefitStatus: data.previous_benefit_status,
        newBenefitStatus: data.new_benefit_status,
        newValidUntil: data.new_valid_until ? new Date(data.new_valid_until) : null,
        result: data.result,
        remarks: data.remarks || null,
        assessedAt: new Date(data.assessed_at),
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Created/Snapshot benefit assessment record: ${data.id} (${data.role_type} - ${data.assessment_month})`);
  }

  private async handleBenefitAssessmentRecordUpdate(data: CdcBenefitAssessmentRecordPayload): Promise<void> {
    const exists = await this.prisma.benefitAssessmentQueryView.findUnique({
      where: { id: data.id },
      select: { id: true },
    });

    if (!exists) {
      await this.handleBenefitAssessmentRecordCreateOrSnapshot(data);
      return;
    }

    await this.prisma.benefitAssessmentQueryView.update({
      where: { id: data.id },
      data: {
        treesCompleted: data.trees_completed,
        treesRequired: data.trees_required,
        benefitActionTaken: data.benefit_action_taken,
        previousBenefitStatus: data.previous_benefit_status,
        newBenefitStatus: data.new_benefit_status,
        newValidUntil: data.new_valid_until ? new Date(data.new_valid_until) : null,
        result: data.result,
        remarks: data.remarks || null,
        assessedAt: new Date(data.assessed_at),
        syncedAt: new Date(),
      },
    });

    this.logger.log(`[Authorization-CDC] Updated benefit assessment record: ${data.id}`);
  }

  private async handleBenefitAssessmentRecordDelete(data: CdcBenefitAssessmentRecordPayload): Promise<void> {
    try {
      await this.prisma.benefitAssessmentQueryView.delete({
        where: { id: data.id },
      });
      this.logger.log(`[Authorization-CDC] Deleted benefit assessment record: ${data.id}`);
    } catch {
      this.logger.warn(`[Authorization-CDC] Benefit assessment record not found for delete: ${data.id}`);
    }
  }

  // ==================== Helper Methods ====================

  private async isEventProcessed(eventId: string): Promise<boolean> {
    const count = await this.prisma.processedEvent.count({
      where: { eventId },
    });
    return count > 0;
  }

  private async markEventProcessed(eventId: string, eventType: string): Promise<void> {
    await this.prisma.processedEvent.create({
      data: {
        eventId,
        eventType,
        processedAt: new Date(),
      },
    });
  }

  /**
   * 获取消费者状态
   */
  getStatus(): { isRunning: boolean; topics: string[]; consumerGroup: string } {
    return {
      isRunning: this.isRunning,
      topics: this.cdcTopics,
      consumerGroup: this.consumerGroup,
    };
  }
}
