import { Injectable, Inject, BadRequestException, NotFoundException } from '@nestjs/common';
import {
  USER_REPOSITORY,
  UserRepository,
  AccountSequence,
} from '@/domain';

export interface SetTradePasswordDto {
  accountSequence: string;
  loginPassword: string; // 需要验证登录密码
  tradePassword: string;
}

export interface ChangeTradePasswordDto {
  accountSequence: string;
  oldTradePassword: string;
  newTradePassword: string;
}

export interface VerifyTradePasswordDto {
  accountSequence: string;
  tradePassword: string;
}

export interface TradePasswordStatusDto {
  hasTradePassword: boolean;
}

@Injectable()
export class TradePasswordService {
  constructor(
    @Inject(USER_REPOSITORY)
    private readonly userRepository: UserRepository,
  ) {}

  /**
   * 获取支付密码状态
   */
  async getStatus(accountSequence: string): Promise<TradePasswordStatusDto> {
    const user = await this.userRepository.findByAccountSequence(
      AccountSequence.create(accountSequence),
    );

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

    return {
      hasTradePassword: user.hasTradePassword,
    };
  }

  /**
   * 设置支付密码（首次设置或修改）
   * 首次设置需要验证登录密码
   */
  async setTradePassword(dto: SetTradePasswordDto): Promise<void> {
    const user = await this.userRepository.findByAccountSequence(
      AccountSequence.create(dto.accountSequence),
    );

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

    // 验证登录密码
    const isLoginPasswordValid = await user.verifyPassword(dto.loginPassword);
    if (!isLoginPasswordValid) {
      throw new BadRequestException('登录密码错误');
    }

    // 支付密码不能与登录密码相同
    const isSameAsLogin = await user.verifyPassword(dto.tradePassword);
    if (isSameAsLogin) {
      throw new BadRequestException('支付密码不能与登录密码相同');
    }

    // 验证密码格式（6位数字）
    if (!/^\d{6}$/.test(dto.tradePassword)) {
      throw new BadRequestException('支付密码必须是6位数字');
    }

    // 设置支付密码
    await user.setTradePassword(dto.tradePassword);
    await this.userRepository.save(user);
  }

  /**
   * 修改支付密码（需要验证旧密码）
   */
  async changeTradePassword(dto: ChangeTradePasswordDto): Promise<void> {
    const user = await this.userRepository.findByAccountSequence(
      AccountSequence.create(dto.accountSequence),
    );

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

    if (!user.hasTradePassword) {
      throw new BadRequestException('尚未设置支付密码');
    }

    // 验证旧支付密码
    const isOldPasswordValid = await user.verifyTradePassword(dto.oldTradePassword);
    if (!isOldPasswordValid) {
      throw new BadRequestException('原支付密码错误');
    }

    // 新密码不能与旧密码相同
    if (dto.oldTradePassword === dto.newTradePassword) {
      throw new BadRequestException('新密码不能与原密码相同');
    }

    // 验证新密码格式（6位数字）
    if (!/^\d{6}$/.test(dto.newTradePassword)) {
      throw new BadRequestException('支付密码必须是6位数字');
    }

    // 设置新支付密码
    await user.setTradePassword(dto.newTradePassword);
    await this.userRepository.save(user);
  }

  /**
   * 验证支付密码
   */
  async verifyTradePassword(dto: VerifyTradePasswordDto): Promise<boolean> {
    const user = await this.userRepository.findByAccountSequence(
      AccountSequence.create(dto.accountSequence),
    );

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

    if (!user.hasTradePassword) {
      // 未设置支付密码，视为验证通过（允许交易）
      return true;
    }

    return user.verifyTradePassword(dto.tradePassword);
  }
}
