import { Injectable, Inject, BadRequestException, NotFoundException } from '@nestjs/common';
import {
  Phone,
  USER_REPOSITORY,
  UserRepository,
  SYNCED_LEGACY_USER_REPOSITORY,
  SyncedLegacyUserRepository,
  SMS_VERIFICATION_REPOSITORY,
  SmsVerificationRepository,
  SmsVerificationType,
} from '@/domain';

export interface ResetPasswordDto {
  phone: string;
  smsCode: string;
  newPassword: string;
}

export interface ChangePasswordDto {
  accountSequence: string;
  oldPassword: string;
  newPassword: string;
}

@Injectable()
export class PasswordService {
  constructor(
    @Inject(USER_REPOSITORY)
    private readonly userRepository: UserRepository,
    @Inject(SYNCED_LEGACY_USER_REPOSITORY)
    private readonly syncedLegacyUserRepository: SyncedLegacyUserRepository,
    @Inject(SMS_VERIFICATION_REPOSITORY)
    private readonly smsVerificationRepository: SmsVerificationRepository,
  ) {}

  /**
   * 重置密码（通过短信验证码）
   */
  async resetPassword(dto: ResetPasswordDto): Promise<void> {
    const phone = Phone.create(dto.phone);

    // 验证短信验证码
    const verification = await this.smsVerificationRepository.findLatestValid(
      phone,
      SmsVerificationType.RESET_PASSWORD,
    );

    if (!verification || verification.code !== dto.smsCode) {
      throw new BadRequestException('验证码错误或已过期');
    }

    // 标记验证码已使用
    await this.smsVerificationRepository.markAsVerified(verification.id);

    // 查找用户
    const user = await this.userRepository.findByPhone(phone);
    if (!user) {
      // 检查是否为未迁移的 V1 用户
      const legacyUser = await this.syncedLegacyUserRepository.findByPhone(phone);
      if (legacyUser && !legacyUser.migratedToV2) {
        throw new BadRequestException('请先登录以完成账户迁移，再修改密码');
      }
      throw new NotFoundException('用户不存在');
    }

    // 修改密码
    await user.changePassword(dto.newPassword);
    await this.userRepository.save(user);
  }

  /**
   * 修改密码（需要验证旧密码）
   */
  async changePassword(dto: ChangePasswordDto): Promise<void> {
    const user = await this.userRepository.findByAccountSequence(
      new (await import('@/domain')).AccountSequence(dto.accountSequence),
    );

    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    // 验证旧密码
    const isValid = await user.verifyPassword(dto.oldPassword);
    if (!isValid) {
      throw new BadRequestException('原密码错误');
    }

    // 新密码不能与旧密码相同
    const isSame = await user.verifyPassword(dto.newPassword);
    if (isSame) {
      throw new BadRequestException('新密码不能与原密码相同');
    }

    // 修改密码
    await user.changePassword(dto.newPassword);
    await this.userRepository.save(user);
  }
}
