"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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
const common_1 = require("@nestjs/common");
const jwt_1 = require("@nestjs/jwt");
const bcrypt = require("bcryptjs");
const users_service_1 = require("../users/users.service");
const email_service_1 = require("./email.service");
let AuthService = class AuthService {
    constructor(usersService, jwtService, emailService) {
        this.usersService = usersService;
        this.jwtService = jwtService;
        this.emailService = emailService;
    }
    async login(dto) {
        var _a;
        const user = await this.usersService.findByEmail(dto.email);
        const mockCredentials = {
            'captain@maritime.com': 'Captain123!',
            'engineer@shipping.com': 'Engineer456!',
            'port@manager.com': 'Port789!'
        };
        let valid = false;
        let userId = user === null || user === void 0 ? void 0 : user.id;
        let userType = (user === null || user === void 0 ? void 0 : user.userType) || 'professional';
        let name = (user === null || user === void 0 ? void 0 : user.name) || dto.email.split('@')[0];
        let isEmailVerified = (_a = user === null || user === void 0 ? void 0 : user.isEmailVerified) !== null && _a !== void 0 ? _a : true;
        if (user === null || user === void 0 ? void 0 : user.passwordHash) {
            valid = await bcrypt.compare(dto.password, user.passwordHash);
            if (valid && !user.isEmailVerified) {
                throw new common_1.UnauthorizedException('Please verify your email before logging in. Check your inbox for the verification code.');
            }
        }
        else if (mockCredentials[dto.email]) {
            valid = mockCredentials[dto.email] === dto.password;
            userId = userId || '1';
            isEmailVerified = true;
        }
        if (!valid) {
            throw new common_1.UnauthorizedException('Invalid maritime credentials. Please check your email and password.');
        }
        const payload = { sub: userId, email: dto.email, userType };
        const token = await this.jwtService.signAsync(payload);
        return {
            user: { id: userId, email: dto.email, name, userType, isEmailVerified },
            token
        };
    }
    async register(dto) {
        const existingUser = await this.usersService.findByEmail(dto.email);
        if (existingUser) {
            throw new common_1.BadRequestException('User with this email already exists');
        }
        const passwordHash = await bcrypt.hash(dto.password, 10);
        const otp = this.generateOTP();
        const otpExpires = new Date(Date.now() + 10 * 60 * 1000);
        const created = await this.usersService.createUser({
            email: dto.email,
            name: dto.name,
            passwordHash,
            userType: dto.userType,
            isEmailVerified: false,
            emailVerificationToken: otp,
            emailVerificationExpires: otpExpires
        });
        await this.emailService.sendVerificationEmail(dto.email, otp);
        return {
            user: {
                id: created.id,
                email: created.email,
                name: created.name,
                userType: created.userType,
                isEmailVerified: false
            },
            message: 'Registration successful. Please check your email for verification code.'
        };
    }
    async verifyEmail(dto) {
        const user = await this.usersService.findByEmail(dto.email);
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        if (user.isEmailVerified) {
            throw new common_1.BadRequestException('Email is already verified');
        }
        if (!user.emailVerificationToken || user.emailVerificationToken !== dto.otp) {
            throw new common_1.BadRequestException('Invalid verification code');
        }
        if (!user.emailVerificationExpires || user.emailVerificationExpires < new Date()) {
            throw new common_1.BadRequestException('Verification code has expired');
        }
        await this.usersService.updateUser(user.id, {
            isEmailVerified: true,
            emailVerificationToken: undefined,
            emailVerificationExpires: undefined
        });
        const payload = { sub: user.id, email: user.email, userType: user.userType };
        const token = await this.jwtService.signAsync(payload);
        return {
            user: {
                id: user.id,
                email: user.email,
                name: user.name,
                userType: user.userType,
                isEmailVerified: true
            },
            token,
            message: 'Email verified successfully'
        };
    }
    async resendVerificationOtp(dto) {
        const user = await this.usersService.findByEmail(dto.email);
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        if (user.isEmailVerified) {
            throw new common_1.BadRequestException('Email is already verified');
        }
        const otp = this.generateOTP();
        const otpExpires = new Date(Date.now() + 10 * 60 * 1000);
        await this.usersService.updateUser(user.id, {
            emailVerificationToken: otp,
            emailVerificationExpires: otpExpires
        });
        await this.emailService.sendVerificationEmail(dto.email, otp);
        return {
            message: 'Verification code sent successfully'
        };
    }
    async forgotPassword(dto) {
        const user = await this.usersService.findByEmail(dto.email);
        if (!user) {
            return {
                message: 'If an account with this email exists, you will receive a password reset code.'
            };
        }
        const otp = this.generateOTP();
        const otpExpires = new Date(Date.now() + 10 * 60 * 1000);
        await this.usersService.updateUser(user.id, {
            passwordResetToken: otp,
            passwordResetExpires: otpExpires
        });
        await this.emailService.sendPasswordResetEmail(dto.email, otp);
        return {
            message: 'If an account with this email exists, you will receive a password reset code.'
        };
    }
    async resetPassword(dto) {
        const user = await this.usersService.findByEmail(dto.email);
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        if (!user.passwordResetToken || user.passwordResetToken !== dto.otp) {
            throw new common_1.BadRequestException('Invalid reset code');
        }
        if (!user.passwordResetExpires || user.passwordResetExpires < new Date()) {
            throw new common_1.BadRequestException('Reset code has expired');
        }
        const passwordHash = await bcrypt.hash(dto.newPassword, 10);
        await this.usersService.updateUser(user.id, {
            passwordHash,
            passwordResetToken: undefined,
            passwordResetExpires: undefined
        });
        return {
            message: 'Password reset successfully'
        };
    }
    generateOTP() {
        return Math.floor(100000 + Math.random() * 900000).toString();
    }
};
exports.AuthService = AuthService;
exports.AuthService = AuthService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [users_service_1.UsersService,
        jwt_1.JwtService,
        email_service_1.EmailService])
], AuthService);
//# sourceMappingURL=auth.service.js.map