import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';
import { MailService } from '../mail/mail.service';
import { CreateUserDto } from "../users/dto/create-user.dto";
import { RegisterAuthDto } from "./dto/register-auth.dto";

@Injectable()
export class AuthService {
  constructor(
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService,
    private prisma: PrismaService,
    private mailService: MailService,
  ) {}

  async validateUser(email: string, pass: string): Promise<any> {
    // const user = await this.usersService.findOne(email);
    const user = await this.prisma.user.findFirst({ where: { email } });
    const isMatch = await bcrypt.compare(pass, user.password);
    if (user && isMatch) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { id: user.id, email: user.email, name: user.name };
    if (payload) {
      return {
        token: this.jwtService.sign(payload),
      };
    } else {
      throw new HttpException('Not Correct!', HttpStatus.NOT_ACCEPTABLE);
    }
  }

  async register(createUserDto: RegisterAuthDto) {
    try {
      const role = await this.prisma.role.findFirst({
        where: {
          name: 'user'
        },
        select: {
          id: true
        }
      })
      const saltOrRounds = 10;
      const hash = await bcrypt.hash(createUserDto.password, saltOrRounds);
      const user = this.prisma.user.create({
        data: {
          phone: createUserDto.phone,
          email: createUserDto.email,
          password: hash,
          role_id: role.id,
          userDetail: {
            create: {
              first_name: createUserDto.first_name,
              last_name: createUserDto.last_name,
            },
          },
        },
        select: {
          id: true,
          phone: true,
          email: true,
          status: false,
          createdAt: true,
          userDetail: {
            select: {
              first_name: true,
              last_name: true,
            },
          },
        },
      });
      return user;
    } catch (e) {
      return e.errors;
    }
  }

  check(id: string) {
    const user = this.prisma.user.findFirst({
      where: { id },
    });
    if (user) {
      return {
        isLogin: true,
      };
    }
    return {
      isLogin: false,
    };
  }

  async forgetpassword(email: string) {
    const this_user = await this.prisma.user.findFirst({
      where: { email },
      select: {
        email: true,
        userDetail: {
          select: {
            first_name: true,
            last_name: true,
          },
        },
      },
    });

    if (this_user) {
      try {
        await this.prisma.resetPassowrd.delete({
          where: { email },
        });
      } catch (e) {}

      const token = Math.floor(100000 + Math.random() * 900000).toString();

      const user = {
        email: this_user.email,
        first_name: this_user.userDetail.first_name,
        last_name: this_user.userDetail.last_name,
      };
      await this.mailService.sendResetPassword(user, token);
      await this.prisma.resetPassowrd.create({
        data: {
          email: email,
          token: token,
        },
      });
      return true;
    }
    return false;
  }

  async resetpassword(data: {
    email: string;
    token: string | number;
    password: string;
  }) {
    try {
      const checktoken = await this.prisma.resetPassowrd.findFirst({
        where: { email: data.email },
      });
      if (checktoken.token == data.token) {
        const saltOrRounds = 10;
        const hash = await bcrypt.hash(data.password, saltOrRounds);
        await this.prisma.user.update({
          where: { email: data.email },
          data: {
            password: hash,
          },
        });
        await this.prisma.resetPassowrd.delete({
          where: { email: data.email },
        });
        return true;
      } else {
        throw new HttpException(
          'Code Is Not Correct!',
          HttpStatus.NOT_ACCEPTABLE,
        );
      }
    } catch (e) {}
    throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
  }
}
