import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ConfigurationService } from '../../config/configuration.service';
import { ErrorService } from '../../error/error.service';
import { Roles, UserEntity } from '../user/entities/user.entity';
import { UserService } from '../user/user.service';
import { AuthLoginDto } from './dto/auth-login.dto';

@Injectable()
export class AuthService {
  constructor(
    private userService: UserService,
    private error: ErrorService,
    private config: ConfigurationService,
    private jwtService: JwtService,
  ) {}

  async login(dto: AuthLoginDto) {
    const user = await this.userService.getUserPanelAccessByEmailOrMobile(
      dto.emailOrMobile,
    );

    if (!user) {
      this.error.unprocessableEntity(['نام کاربری یا کلمه عبور اشتباه است']);
    }

    if (!user.isCorrectEncryptPassword(dto.password)) {
      this.error.unprocessableEntity(['نام کاربری یا کلمه عبور اشتباه است']);
    }

    return user;
  }

  /**
   * Preparing the user info and an access token for responding to signup and login requests
   * Generating the JWT access token, if the user is verified
   */
  async prepareUserResponse(user: UserEntity, rememberMe = false) {
    const accessToken = await this._generateAccessToken(user, rememberMe);

    return {
      user: {
        id: user.id,
        roleId: user.roleId,
        role: user.role,
        roleType: Roles[user.roleId],
        email: user.email,
        mobile: user.mobile,
        gender: user.gender,
        birthday: user.birthday,
        fullName: `${user.name} ${user.surName}`.trim(),
      },
      accessToken,
    };
  }

  /**
   * Generating the JWT access token based on the user's ID and email
   */
  private async _generateAccessToken(user: UserEntity, rememberMe = false) {
    return await this.jwtService.sign(
      {
        id: user.id,
        email: user.email,
        mobile: user.mobile,
        roleId: user.roleId,
        role: Roles[user.roleId],
      },
      {
        expiresIn: rememberMe
          ? this.config.auth.expiresLifetime
          : this.config.auth.expires,
      },
    );
  }
}
