import { Inject, Injectable, Logger } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-local';
import { DomainException, normalizeVietnamPhone, UnauthorizedException } from '@modules/shared';
import { USER_REPOSITORY, type IUserRepository } from '../../domain/repositories/user.repository';

export interface LocalStrategyResult {
  id: string;
  phone: string;
  role: string;
  isMfaRequired: boolean;
}

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  private readonly logger = new Logger(LocalStrategy.name);

  constructor(
    @Inject(USER_REPOSITORY)
    private readonly userRepo: IUserRepository,
  ) {
    super({ usernameField: 'phone', passwordField: 'password' });
  }

  async validate(phone: string, password: string): Promise<LocalStrategyResult> {
    try {
      if (!phone || !password) {
        throw new UnauthorizedException('Số điện thoại hoặc mật khẩu không đúng');
      }

      const normalizedPhone = normalizeVietnamPhone(phone);
      if (!normalizedPhone) {
        throw new UnauthorizedException('Số điện thoại không hợp lệ');
      }
      const user = await this.userRepo.findByPhone(normalizedPhone);

      if (!user || !user.passwordHash) {
        throw new UnauthorizedException('Số điện thoại hoặc mật khẩu không đúng');
      }

      if (!user.isActive) {
        throw new UnauthorizedException('Tài khoản đã bị vô hiệu hóa');
      }

      if (user.deletedAt !== null) {
        throw new UnauthorizedException('Tài khoản đã bị xóa');
      }

      const isValid = await user.passwordHash.compare(password);
      if (!isValid) {
        throw new UnauthorizedException('Số điện thoại hoặc mật khẩu không đúng');
      }

      return {
        id: user.id,
        phone: user.phone.value,
        role: user.role,
        isMfaRequired: user.totpEnabled,
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Authentication failed: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw new UnauthorizedException('Số điện thoại hoặc mật khẩu không đúng');
    }
  }
}
