"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
const bcrypt_1 = __importDefault(require("bcrypt"));
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const user_model_1 = require("../model/user-model");
const validation_1 = require("../validation/validation");
const auth_validation_1 = require("../validation/auth-validation");
class AuthService {
    static register(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the registration request
            const registerRequest = validation_1.Validation.validate(auth_validation_1.AuthValidation.REGISTER, request);
            // Check if the email already exists
            const existingUser = yield database_1.db.queryOne('SELECT id FROM user WHERE email = ? LIMIT 1', [
                registerRequest.email,
            ]);
            if (existingUser) {
                throw new response_error_1.ResponseError(400, 'Email sudah terdaftar');
            }
            // Hash the password before storing it
            const hashedPassword = yield bcrypt_1.default.hash(registerRequest.password, 10);
            // Generate a new UUID for the user ID
            const userId = (0, uuid_1.v4)();
            // Insert the new user into the database
            yield database_1.db.query('INSERT INTO user (id, full_name, email, whatsapp_number, password) VALUES (?, ?, ?, ?, ?)', [
                userId,
                registerRequest.full_name,
                registerRequest.email,
                registerRequest.whatsapp_number,
                hashedPassword,
            ]);
            // Retrieve the newly created user by the email
            const user = yield database_1.db.queryOne('SELECT * FROM user WHERE id = ? LIMIT 1', [userId]);
            if (!user) {
                throw new response_error_1.ResponseError(500, 'Gagal melakukan registrasi user');
            }
            return (0, user_model_1.toUserResponse)(user);
        });
    }
    static login(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the login request
            const loginRequest = validation_1.Validation.validate(auth_validation_1.AuthValidation.LOGIN, request);
            // Find the user by email
            const user = yield database_1.db.queryOne('SELECT * FROM user WHERE email = ? LIMIT 1', [loginRequest.email]);
            if (!user) {
                throw new response_error_1.ResponseError(400, 'Email atau password salah');
            }
            // Compare the password
            const passwordMatch = yield bcrypt_1.default.compare(loginRequest.password, user.password);
            if (!passwordMatch) {
                throw new response_error_1.ResponseError(400, 'Email atau password salah');
            }
            // Generate a JWT token
            const token = jsonwebtoken_1.default.sign({
                id: user.id,
                email: user.email,
                full_name: user.full_name,
                whatsapp_number: user.whatsapp_number,
                role: user.role,
            }, String(process.env.JWT_SECRET), {
                expiresIn: '24h',
            });
            // Format the user response
            const response = (0, user_model_1.toUserResponse)(user);
            response.token = token;
            return response;
        });
    }
}
exports.AuthService = AuthService;
