import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { CreateOtpDto } from './dto/create-otp.dto';
import { UpdateOtpDto } from './dto/update-otp.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Otp } from './entities/otp.entity';
import { Utilisateur } from '../utilisateurs/entities/utilisateur.entity';
import * as crypto from 'crypto';
import { UtilisateursService } from '../utilisateurs/utilisateurs.service';

@Injectable()
export class OtpService {

  constructor(
    @InjectRepository(Otp)
    private otpRepository: Repository<Otp>,
  ) {}

  async generateOtp(userId: Utilisateur): Promise<Otp> {
    const user = userId; //await this.userService.findOne(userId);
    if (!user) throw new NotFoundException('Utilisateur non trouvé');

    const otp = this.otpRepository.create({
      user,
      code: this.generateRandomCode(6),
      expired: new Date(Date.now() + 5 * 60 * 1000), // expire dans 5 minutes
    });

    return await this.otpRepository.save(otp);
  }

  async verifyOtp(userId: number, code: string): Promise<boolean> {
    const otp = await this.otpRepository.findOne({
      where: { user: { id: userId }, code, verified: false },
    });
    console.log(userId);
    console.log(code);
    
    if (!otp) throw new NotFoundException('Code OTP invalide');
    if (otp.expired < new Date()) throw new BadRequestException('Code OTP expiré');

    otp.verified = true;
    await this.otpRepository.save(otp);

    return true;
  }

  private generateRandomCode(length: number): string {
    return crypto.randomInt(100000, 999999).toString(); // 6 chiffres
  }
  
  create(createOtpDto: CreateOtpDto) {
    return 'This action adds a new otp';
  }

  findAll() {
    return `This action returns all otp`;
  }

  findOne(id: number) {
    return `This action returns a #${id} otp`;
  }

  update(id: number, updateOtpDto: UpdateOtpDto) {
    return `This action updates a #${id} otp`;
  }

  remove(id: number) {
    return `This action removes a #${id} otp`;
  }
}
