import { Injectable, Inject, Logger } from '@nestjs/common';
import { RecoverByMnemonicCommand } from './recover-by-mnemonic.command';
import {
  UserAccountRepository,
  USER_ACCOUNT_REPOSITORY,
} from '@/domain/repositories/user-account.repository.interface';
import { AccountSequence } from '@/domain/value-objects';
import { TokenService } from '@/application/services/token.service';
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
import { BlockchainClientService } from '@/infrastructure/external/blockchain/blockchain-client.service';
import { ApplicationError } from '@/shared/exceptions/domain.exception';
import { RecoverAccountResult } from '../index';
import { generateRandomAvatarSvg } from '@/shared/utils/random-identity.util';

@Injectable()
export class RecoverByMnemonicHandler {
  private readonly logger = new Logger(RecoverByMnemonicHandler.name);

  constructor(
    @Inject(USER_ACCOUNT_REPOSITORY)
    private readonly userRepository: UserAccountRepository,
    private readonly tokenService: TokenService,
    private readonly eventPublisher: EventPublisherService,
    private readonly blockchainClient: BlockchainClientService,
  ) {}

  async execute(
    command: RecoverByMnemonicCommand,
  ): Promise<RecoverAccountResult> {
    const accountSequence = AccountSequence.create(command.accountSequence);
    const account =
      await this.userRepository.findByAccountSequence(accountSequence);
    if (!account) throw new ApplicationError('账户序列号不存在');
    if (!account.isActive) throw new ApplicationError('账户已冻结或注销');

    // 调用 blockchain-service 验证助记词（blockchain-service 内部查询哈希并验证）
    this.logger.log(
      `Verifying mnemonic for account ${command.accountSequence}`,
    );
    const verifyResult = await this.blockchainClient.verifyMnemonicByAccount({
      accountSequence: command.accountSequence,
      mnemonic: command.mnemonic,
    });

    if (!verifyResult.valid) {
      this.logger.warn(
        `Mnemonic verification failed for account ${command.accountSequence}: ${verifyResult.message}`,
      );
      throw new ApplicationError(verifyResult.message || '助记词错误');
    }

    this.logger.log(
      `Mnemonic verified successfully for account ${command.accountSequence}`,
    );

    // 如果头像为空，重新生成一个
    let avatarUrl = account.avatarUrl;
    this.logger.log(
      `Account ${command.accountSequence} avatarUrl from DB: ${avatarUrl ? `长度=${avatarUrl.length}` : 'null'}`,
    );
    if (avatarUrl) {
      this.logger.log(
        `Account ${command.accountSequence} avatarUrl前50字符: ${avatarUrl.substring(0, 50)}`,
      );
    }
    if (!avatarUrl) {
      this.logger.log(
        `Account ${command.accountSequence} has no avatar, generating new one`,
      );
      avatarUrl = generateRandomAvatarSvg();
      account.updateProfile({ avatarUrl });
    }

    account.addDevice(command.newDeviceId, command.deviceName);
    account.recordLogin();
    await this.userRepository.save(account);

    const tokens = await this.tokenService.generateTokenPair({
      userId: account.userId.toString(),
      accountSequence: account.accountSequence.value,
      deviceId: command.newDeviceId,
    });

    await this.eventPublisher.publishAll(account.domainEvents);
    account.clearDomainEvents();

    const result = {
      userId: account.userId.toString(),
      accountSequence: account.accountSequence.value,
      nickname: account.nickname,
      avatarUrl,
      referralCode: account.referralCode.value,
      accessToken: tokens.accessToken,
      refreshToken: tokens.refreshToken,
    };

    this.logger.log(
      `RecoverByMnemonic result - accountSequence: ${result.accountSequence}, nickname: ${result.nickname}`,
    );
    this.logger.log(
      `RecoverByMnemonic result - avatarUrl: ${result.avatarUrl ? `长度=${result.avatarUrl.length}` : 'null'}`,
    );

    return result;
  }
}
