import { Injectable, Inject } from '@nestjs/common';
import {
  UserAccountRepository,
  USER_ACCOUNT_REPOSITORY,
} from '@/domain/repositories/user-account.repository.interface';
import { PhoneNumber, ReferralCode, ChainType } from '@/domain/value-objects';

export class ValidationResult {
  private constructor(
    public readonly isValid: boolean,
    public readonly errorMessage: string | null,
  ) {}

  static success(): ValidationResult {
    return new ValidationResult(true, null);
  }

  static failure(message: string): ValidationResult {
    return new ValidationResult(false, message);
  }
}

@Injectable()
export class UserValidatorService {
  constructor(
    @Inject(USER_ACCOUNT_REPOSITORY)
    private readonly repository: UserAccountRepository,
  ) {}

  async validatePhoneNumber(
    phoneNumber: PhoneNumber,
  ): Promise<ValidationResult> {
    const existing = await this.repository.findByPhoneNumber(phoneNumber);
    if (existing) return ValidationResult.failure('该手机号已注册');
    return ValidationResult.success();
  }

  async checkDeviceNotRegistered(deviceId: string): Promise<ValidationResult> {
    // TODO: 暂时禁用设备检查，允许同一设备创建多个账户
    return ValidationResult.success();
    // const existing = await this.repository.findByDeviceId(deviceId);
    // if (existing) return ValidationResult.failure('该设备已创建过账户');
    // return ValidationResult.success();
  }

  async validateReferralCode(
    referralCode: ReferralCode,
  ): Promise<ValidationResult> {
    const inviter = await this.repository.findByReferralCode(referralCode);
    if (!inviter) return ValidationResult.failure('推荐码不存在');
    if (!inviter.isActive)
      return ValidationResult.failure('推荐人账户已冻结或注销');
    return ValidationResult.success();
  }

  async validateWalletAddress(
    chainType: ChainType,
    address: string,
  ): Promise<ValidationResult> {
    const existing = await this.repository.findByWalletAddress(
      chainType,
      address,
    );
    if (existing) return ValidationResult.failure('该地址已被其他账户绑定');
    return ValidationResult.success();
  }
}
