"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoginCommandHandler = void 0;
const UserMapper_1 = require("../../DTOs/Mappers/UserMapper");
const PasswordService_1 = require("../../Services/PasswordService");
const UserAggregate_1 = require("../../../Domain/User/UserAggregate");
const Logger_1 = require("../../Services/Logger");
class LoginCommandHandler {
    constructor(userRepo, jwtService, orgRepo) {
        this.userRepo = userRepo;
        this.jwtService = jwtService;
        this.orgRepo = orgRepo;
    }
    async execute(cmd) {
        const startTime = Date.now();
        try {
            (0, Logger_1.logAuth)('Login attempt', undefined, { username: cmd.username });
            const user = await this.userRepo.findByUsername(cmd.username) ||
                await this.userRepo.findByEmail(cmd.username);
            (0, Logger_1.logDatabase)('User lookup completed', undefined, Date.now() - startTime, {
                found: !!user,
                searchBy: cmd.username.includes('@') ? 'email' : 'username'
            });
            if (!user) {
                (0, Logger_1.logAuth)('Login failed - User not found', undefined, { username: cmd.username });
                return null;
            }
            try {
                const passwordStartTime = Date.now();
                const isPasswordValid = await PasswordService_1.PasswordService.verifyPassword(cmd.password, user.password);
                (0, Logger_1.logAuth)('Password verification completed', user.id, {
                    valid: isPasswordValid,
                    verificationTime: Date.now() - passwordStartTime
                });
                if (!isPasswordValid) {
                    (0, Logger_1.logWarning)('Login failed - Invalid password', {
                        userId: user.id,
                        username: cmd.username
                    });
                    return null;
                }
            }
            catch (error) {
                (0, Logger_1.logError)('Password verification error', error);
                return null;
            }
            const mockRes = {
                cookie: () => { }
            };
            const tokenPayload = {
                userId: user.id,
                authLevel: (user.state === UserAggregate_1.UserState.ADMIN ? 1 : 0),
                userStatus: user.state,
                orgId: user.orgid || ''
            };
            try {
                const token = this.jwtService.create(tokenPayload, mockRes);
                // Check if user belongs to an organization and needs reauthentication
                let requiresOrgReauth = false;
                let orgLoginUrl;
                let organizationName;
                if (user.orgid) {
                    const organization = await this.orgRepo.findById(user.orgid);
                    if (organization) {
                        organizationName = organization.name;
                        // Check if user has logged in to organization within the last month
                        const oneMonthAgo = new Date();
                        oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
                        const needsReauth = !user.Orglogindate || user.Orglogindate < oneMonthAgo;
                        if (needsReauth && organization.url) {
                            requiresOrgReauth = true;
                            orgLoginUrl = organization.url;
                            (0, Logger_1.logAuth)('User requires organization reauthentication', user.id, {
                                organizationId: user.orgid,
                                organizationName: organization.name,
                                lastOrgLogin: user.Orglogindate?.toISOString() || 'never',
                                orgLoginUrl: organization.url
                            });
                        }
                    }
                }
                (0, Logger_1.logAuth)('Login successful', user.id, {
                    authLevel: tokenPayload.authLevel,
                    userStatus: tokenPayload.userStatus,
                    orgId: tokenPayload.orgId,
                    requiresOrgReauth,
                    organizationName,
                    totalLoginTime: Date.now() - startTime
                });
                const response = {
                    user: UserMapper_1.UserMapper.toShortDto(user),
                    token
                };
                if (requiresOrgReauth) {
                    response.requiresOrgReauth = true;
                    response.orgLoginUrl = orgLoginUrl;
                    response.organizationName = organizationName;
                }
                return response;
            }
            catch (error) {
                (0, Logger_1.logError)('Token creation failed during login', error);
                throw new Error('Login failed due to internal error');
            }
        }
        catch (error) {
            if (error instanceof Error) {
                (0, Logger_1.logError)('Login handler error', error);
                // Handle database connection errors
                if (error.message.includes('database connection')) {
                    (0, Logger_1.logDatabase)('Database connection error during login', undefined, Date.now() - startTime);
                    throw new Error('Database connection error');
                }
                // If it's already a properly formatted error, re-throw it
                if (error.message === 'Login failed due to internal error' ||
                    error.message === 'Database connection error') {
                    throw error;
                }
            }
            // Default database error handling
            (0, Logger_1.logDatabase)('Unexpected database error during login', undefined, Date.now() - startTime);
            throw new Error('Database connection error');
        }
    }
}
exports.LoginCommandHandler = LoginCommandHandler;
//# sourceMappingURL=LoginCommandHandler.js.map