"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var AuthService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const jwt_1 = require("@nestjs/jwt");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const typeorm_2 = require("typeorm");
const user_entity_1 = require("../user.entity");
const sms_service_1 = require("../../smsgetway/sms.service");
const otp_email_service_1 = require("../../emailotp/otp-email.service");
const admin = require("firebase-admin");
let AuthService = AuthService_1 = class AuthService {
    constructor(userRepository, dataSource, smsService, emailOtpService, jwtService) {
        this.userRepository = userRepository;
        this.dataSource = dataSource;
        this.smsService = smsService;
        this.emailOtpService = emailOtpService;
        this.jwtService = jwtService;
        this.logger = new common_1.Logger(AuthService_1.name);
    }
    async comparePassword(plainPassword, hashedPassword) {
        return await bcrypt.compare(plainPassword, hashedPassword);
    }
    async validateUser(identifier, credential) {
        this.logger.log(`Validating user with identifier: ${identifier}`);
        const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(identifier);
        const user = isEmail
            ? await this.userRepository.findOne({
                where: { email: identifier },
            })
            : await this.userRepository.findOne({
                where: { mobileNumber: identifier },
            });
        if (!user) {
            this.logger.error(`User not found with email: ${identifier}`);
            throw new common_1.UnauthorizedException('User not found with this email');
        }
        const isPasswordValid = await this.comparePassword(credential, user.password);
        if (!isPasswordValid) {
            this.logger.error(`Invalid password for user: ${identifier}`);
            throw new common_1.UnauthorizedException('Invalid email or password');
        }
        this.logger.log(`User validated with mobile: ${identifier}`);
        return user;
    }
    async login(user) {
        const payload = { userId: user.id, email: user.email, mobileNumber: user.mobileNumber, roles: user.roles };
        const secretKey = 'cars27x7appbkKD';
        const token = jwt.sign(payload, secretKey);
        const roles = user.roles;
        let accessModule = [];
        let planDetail = {};
        if (roles.includes('vendor')) {
            planDetail = await this.dataSource
                .createQueryBuilder()
                .select('vp')
                .from('vendor_plan', 'vp')
                .where('vp.vendorId = :vendorId', { vendorId: user.id })
                .orderBy('vp.createdAt', 'DESC')
                .limit(1)
                .getRawOne() ?? {};
            if (planDetail?.vp_status == 'active') {
                accessModule = await this.dataSource.query(`
          SELECT rp.permissionId, rp.roleId, p.* 
          FROM role_permissions rp
          LEFT JOIN permissions p ON rp.permissionId = p.id
          WHERE rp.roleId = 3
        `);
            }
            else {
                accessModule = [{
                        "permissionId": 0,
                        "roleId": 3,
                        "name": "Document upload",
                        "key": "document_upload",
                        "id": 1,
                        "moduleId": 0
                    }];
            }
        }
        if (roles.includes('admin')) {
            accessModule = await this.dataSource.query(`
        SELECT rp.permissionId, rp.roleId, p.* 
        FROM role_permissions rp
        LEFT JOIN permissions p ON rp.permissionId = p.id
        WHERE rp.roleId = 2
      `);
        }
        if (roles.includes('super_admin')) {
            accessModule = await this.dataSource.query(`
        SELECT rp.permissionId, rp.roleId, p.* 
        FROM role_permissions rp
        LEFT JOIN permissions p ON rp.permissionId = p.id
        WHERE rp.roleId = 1
      `);
        }
        return {
            accessToken: token,
            userdata: user,
            accessModule: accessModule,
            status: true,
            socialLogin: false,
            message: "Login successfully"
        };
    }
    async socialLoginWithFirebase(idToken) {
        if (!idToken) {
            throw new common_1.BadRequestException('Firebase idToken is required');
        }
        if (!admin.apps.length) {
            throw new common_1.UnauthorizedException('Firebase Admin is not initialised');
        }
        let decoded;
        try {
            decoded = await admin.auth().verifyIdToken(idToken);
        }
        catch (e) {
            this.logger.error(`Firebase token verification failed: ${e.message}`);
            throw new common_1.UnauthorizedException('Invalid Firebase token');
        }
        const provider = decoded.firebase?.sign_in_provider;
        const uid = decoded.uid;
        const name = decoded.name || (decoded.email ? decoded.email.split('@')[0] : 'User');
        const email = decoded.email || `${provider === 'apple.com' ? 'apple' : 'google'}_${uid}@cars247.ae`;
        let user = null;
        if (provider === 'apple.com') {
            user = await this.userRepository.findOne({ where: { appleId: uid } });
        }
        else {
            user = await this.userRepository.findOne({ where: { googleId: uid } });
        }
        if (!user) {
            user = await this.userRepository.findOne({ where: { email } });
        }
        if (!user) {
            const timestamp = Date.now();
            const emailInitials = email.slice(0, 2).toUpperCase();
            const year = new Date().getFullYear();
            const userId = `${name.replace(/\s+/g, '').toLowerCase()}${emailInitials}${year}${timestamp}`;
            user = this.userRepository.create({
                userId,
                name,
                email,
                roles: [user_entity_1.UserRole.USER],
                userVerified: true,
                otpStatus: true,
                ...(provider === 'apple.com' ? { appleId: uid } : { googleId: uid }),
            });
            user = await this.userRepository.save(user);
        }
        else {
            let dirty = false;
            if (provider === 'apple.com' && !user.appleId) {
                user.appleId = uid;
                dirty = true;
            }
            else if (provider !== 'apple.com' && !user.googleId) {
                user.googleId = uid;
                dirty = true;
            }
            if (dirty)
                user = await this.userRepository.save(user);
        }
        const result = await this.login(user);
        result.socialLogin = true;
        return result;
    }
    async forgotPassword(identifier) {
        const isEmails = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(identifier);
        const user = isEmails
            ? await this.userRepository.findOne({
                where: { email: identifier },
            })
            : await this.userRepository.findOne({
                where: { mobileNumber: identifier },
            });
        if (!user)
            return { message: 'If account exists, password reset link will be sent.' };
        const payload = { userId: user.id, email: user.email, mobileNumber: user.mobileNumber, roles: user.roles };
        const secretKey = 'cars27x7appbkKD';
        const token = jwt.sign(payload, secretKey);
        let resetLink = '';
        if (user.roles.includes(user_entity_1.UserRole.VENDOR) || user.roles.includes(user_entity_1.UserRole.ADMIN)) {
            resetLink = `https://cars247.ae/cars24x7admin/authentication/change-password?token=${token}&deviceType=web`;
        }
        else {
            resetLink = `https://cars247.ae/cars24x7user/change-password?token=${token}&deviceType=app`;
        }
        if (!isEmails) {
        }
        else {
            await this.emailOtpService.sendLinkForgotPassword(user.email, resetLink);
        }
        return { message: 'Password reset link sent successfully.' };
    }
};
exports.AuthService = AuthService;
exports.AuthService = AuthService = AuthService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(user_entity_1.User)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.DataSource,
        sms_service_1.SmsService,
        otp_email_service_1.emailOtpService,
        jwt_1.JwtService])
], AuthService);
//# sourceMappingURL=auth.service.js.map