import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';
import { CreateUserDto } from '../users/dto/create-user.dto';
import { User } from '../users/schemas/user.schema';
import { UpdateUserDto } from '../users/dto/update-user.dto';
import { ResetPasswordDto } from '../users/dto/reset-password.dto';
import { ChangePasswordDto } from '../users/dto/change-password.dto';

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

  async validateUser(email: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(email);

    if (!user) {
      return null;
    }

    const isValidPassword = await this.usersService.isValidPassword(
      pass,
      user.password,
    );

    if (isValidPassword) {
      return {
        _id: user._id,
        email: user.email,
        firstName: user.firstName,
        lastName: user.lastName,
        street: user.street,
        stNumber: user.stNumber,
        postcode: user.postcode,
        location: user.location,
        phone: user.phone,
        role: user.role,
      };
    }

    return null;
  }

  async signIn(user: {
    email: string;
    firstName: string;
    lastName: string;
    street: string;
    stNumber: string;
    postcode: number;
    location: string;
    phone: string;
    role: string;
  }) {
    return {
      accessToken: this.jwtService.sign(user),
      user,
    };
  }

  async signUp(body: CreateUserDto) {
    const hashedPassword = await this.usersService.hashPassword(body.password);
    const user = await this.usersService.create({
      ...body,
      password: hashedPassword,
    });
    const { password, ...payload } = user;
    return {
      accessToken: this.jwtService.sign(payload),
      user: {
        ...payload,
      },
    };
  }

  async update(u: User, dto: UpdateUserDto) {
    const user = await this.usersService.update(u, dto);

    return {
      accessToken: this.jwtService.sign({ ...user }),
      user,
    };
  }

  async resetPassword(body: ResetPasswordDto) {
    return this.usersService.resetPassword(body);
  }

  async initResetPassword({ email }: { email: string }) {
    const token = this.jwtService.sign({ email }, { expiresIn: '1h' });
    return this.usersService.sendResetPasswordMail(token, email);
  }

  async checkEmail({ email }: { email: string }) {
    const exists = await this.usersService.isEmailRegistered(email);
    return { exists };
  }

  async changePassword(body: ChangePasswordDto, u: User) {
    return this.usersService.changePassword(body, u);
  }
}
