import { Injectable, Inject, Logger } from '@nestjs/common';
import { AutoCreateAccountCommand } from './auto-create-account.command';
import {
  UserAccountRepository,
  USER_ACCOUNT_REPOSITORY,
} from '@/domain/repositories/user-account.repository.interface';
import { UserAccount } from '@/domain/aggregates/user-account/user-account.aggregate';
import {
  AccountSequenceGeneratorService,
  UserValidatorService,
} from '@/domain/services';
import { ReferralCode, AccountSequence } from '@/domain/value-objects';
import { TokenService } from '@/application/services/token.service';
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
import { ApplicationError } from '@/shared/exceptions/domain.exception';
import { AutoCreateAccountResult } from '../index';
import { generateIdentity } from '@/shared/utils';

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

  constructor(
    @Inject(USER_ACCOUNT_REPOSITORY)
    private readonly userRepository: UserAccountRepository,
    private readonly sequenceGenerator: AccountSequenceGeneratorService,
    private readonly validatorService: UserValidatorService,
    private readonly tokenService: TokenService,
    private readonly eventPublisher: EventPublisherService,
  ) {}

  async execute(
    command: AutoCreateAccountCommand,
  ): Promise<AutoCreateAccountResult> {
    this.logger.log(`Creating account for device: ${command.deviceId}`);

    // 1. 验证设备ID
    const deviceCheck = await this.validatorService.checkDeviceNotRegistered(
      command.deviceId,
    );
    if (!deviceCheck.isValid)
      throw new ApplicationError(deviceCheck.errorMessage!);

    // 2. 验证邀请码
    let inviterSequence: AccountSequence | null = null;
    if (command.inviterReferralCode) {
      const referralCode = ReferralCode.create(command.inviterReferralCode);
      const referralValidation =
        await this.validatorService.validateReferralCode(referralCode);
      if (!referralValidation.isValid)
        throw new ApplicationError(referralValidation.errorMessage!);
      const inviter =
        await this.userRepository.findByReferralCode(referralCode);
      inviterSequence = inviter!.accountSequence;
    }

    // 3. 生成用户序列号
    const accountSequence =
      await this.sequenceGenerator.generateNextUserSequence();

    // 4. 生成用户名和头像
    const identity = generateIdentity(accountSequence.value);

    // 5. 构建设备名称，保存完整的设备信息 JSON
    let deviceNameStr = '未命名设备';
    if (command.deviceName) {
      const parts: string[] = [];
      if (command.deviceName.model) parts.push(command.deviceName.model);
      if (command.deviceName.platform) parts.push(command.deviceName.platform);
      if (command.deviceName.osVersion)
        parts.push(command.deviceName.osVersion);
      if (parts.length > 0) deviceNameStr = parts.join(' ');
    }

    // 6. 创建账户 - 传递完整的 deviceName JSON
    const account = UserAccount.createAutomatic({
      accountSequence,
      initialDeviceId: command.deviceId,
      deviceName: deviceNameStr,
      deviceInfo: command.deviceName, // 100% 保持原样存储
      inviterSequence,
      nickname: identity.username,
      avatarSvg: identity.avatarSvg,
    });

    // 7. 保存账户
    await this.userRepository.save(account);

    // 8. 生成 Token
    const tokens = await this.tokenService.generateTokenPair({
      userId: account.userId.toString(),
      accountSequence: account.accountSequence.value,
      deviceId: command.deviceId,
    });

    // 9. 发布领域事件
    await this.eventPublisher.publishAll(account.domainEvents);
    account.clearDomainEvents();

    this.logger.log(
      `Account created: sequence=${accountSequence.value}, username=${identity.username}`,
    );

    return {
      userSerialNum: account.accountSequence.value,
      referralCode: account.referralCode.value,
      username: account.nickname,
      avatarSvg: account.avatarUrl || identity.avatarSvg,
      accessToken: tokens.accessToken,
      refreshToken: tokens.refreshToken,
    };
  }
}
