"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 __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _a, _MitraRequestService_checkMitraRequestExist;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MitraRequestService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const mitra_request_model_1 = require("../model/mitra-request-model");
const mitra_request_validation_1 = require("../validation/mitra-request-validation");
const validation_1 = require("../validation/validation");
class MitraRequestService {
    static create(user, request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(mitra_request_validation_1.MitraRequestValidation.CREATE, request);
            // Generate a UUID for the new mitra request
            const mitraRequestId = (0, uuid_1.v4)();
            // Insert the new mitra request into the database with the UUID
            yield database_1.db.query('INSERT INTO mitra_request (id, ktp, upgrade_amount, payment_proof, status, user_id) VALUES (?, ?, ?, ?, ?, ?)', [mitraRequestId, createRequest.ktp, createRequest.upgrade_amount, createRequest.payment_proof, 'PENDING', user.id]);
            // Return the UUID of the new mitra request
            return mitraRequestId;
        });
    }
    static get(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Query the database for the mitra request with the given ID
            const mitraRequest = yield database_1.db.queryOne('SELECT * FROM mitra_request WHERE id = ?', [
                id,
            ]);
            // If no mitra request is found, throw a 404 error
            if (!mitraRequest) {
                throw new response_error_1.ResponseError(404, 'Mitra request tidak ditemukan');
            }
            // get the user data from the database
            const user = yield database_1.db.queryOne('SELECT * FROM user WHERE id = ?', [mitraRequest.user_id]);
            // If no user is found, throw a 404 error
            if (!user) {
                throw new response_error_1.ResponseError(404, 'User tidak ditemukan');
            }
            // Add the user data to the mitra request
            mitraRequest.User = user;
            // Return the mitra request response
            return (0, mitra_request_model_1.toMitraRequestResponse)(mitraRequest);
        });
    }
    static getStatusByUser(user) {
        return __awaiter(this, void 0, void 0, function* () {
            // Query the database for the most recent mitra request for the given user
            const mitraRequest = yield database_1.db.queryOne('SELECT status FROM mitra_request WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [user.id]);
            // If no mitra request is found, throw a 404 error
            if (!mitraRequest) {
                throw new response_error_1.ResponseError(404, 'Mitra request tidak ditemukan');
            }
            // Return the status of the mitra request
            return mitraRequest.status;
        });
    }
    static getAll(queryParams) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the query parameters
            const queryRequest = validation_1.Validation.validate(mitra_request_validation_1.MitraRequestValidation.QUERY, queryParams);
            // Calculate the offset for pagination
            const skip = (queryRequest.page - 1) * queryRequest.limit;
            // Create the WHERE clause
            let filterQuery = 'WHERE 1 = 1';
            const filterParams = [];
            if (queryRequest.status) {
                filterQuery += ' AND status = ?';
                filterParams.push(queryRequest.status);
            }
            if (queryRequest.search) {
                const searchTerm = `%${queryRequest.search}%`;
                filterQuery += ' AND (u.full_name LIKE ? OR u.email LIKE ? OR u.whatsapp_number LIKE ?)';
                filterParams.push(searchTerm, searchTerm, searchTerm);
            }
            // Create the ORDER BY clause
            const sortField = queryRequest.sort || 'created_at';
            const sortOrder = queryRequest.order || 'desc';
            // Execute the query to get the mitra requests
            const mitraPackages = yield database_1.db.query(`
      SELECT 
        mr.*,
        JSON_OBJECT(
          'id', u.id,
          'full_name', u.full_name,
          'email', u.email,
          'whatsapp_number', u.whatsapp_number,
          'role', u.role,
          'created_at', u.created_at,
          'updated_at', u.updated_at
        ) AS user
      FROM mitra_request mr
      JOIN user u ON mr.user_id = u.id
      ${filterQuery}
      ORDER BY ${sortField} ${sortOrder}
      LIMIT ? OFFSET ?
    `, [...filterParams, queryRequest.limit, skip]);
            // Parse the user data from JSON
            mitraPackages.forEach((mitraPackage) => {
                mitraPackage.user = JSON.parse(mitraPackage.user);
            });
            // Get the total count
            const count = yield database_1.db.queryOne(`SELECT COUNT(*) AS total FROM mitra_request mr JOIN user u ON mr.user_id = u.id ${filterQuery}`, filterParams);
            if (!count) {
                throw new response_error_1.ResponseError(404, 'Mitra request tidak ditemukan');
            }
            return {
                data: mitraPackages.map(mitra_request_model_1.toMitraRequestResponse),
                pagination: {
                    total: count.total,
                    current_page: queryRequest.page,
                    total_pages: Math.ceil(count.total / queryRequest.limit),
                    limit: queryRequest.limit,
                },
            };
        });
    }
    static updateStatus(id, status) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the update status request
            const statusRequest = validation_1.Validation.validate(mitra_request_validation_1.MitraRequestValidation.UPDATE_STATUS, status);
            // Check if the mitra request exists
            yield __classPrivateFieldGet(this, _a, "m", _MitraRequestService_checkMitraRequestExist).call(this, id);
            // Update the status of the mitra request in the database
            yield database_1.db.query('UPDATE mitra_request SET status = ? WHERE id = ?', [statusRequest.status, id]);
            // If the status is 'APPROVED', update the user role to 'MITRA'
            if (statusRequest.status === 'APPROVED') {
                yield database_1.db.query('UPDATE user SET role = ? WHERE id = (SELECT user_id FROM mitra_request WHERE id = ?)', [
                    'MITRA',
                    id,
                ]);
            }
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if the mitra request exists
            yield __classPrivateFieldGet(this, _a, "m", _MitraRequestService_checkMitraRequestExist).call(this, id);
            // Delete the mitra request from the database
            yield database_1.db.query('DELETE FROM mitra_request WHERE id = ?', [id]);
        });
    }
}
exports.MitraRequestService = MitraRequestService;
_a = MitraRequestService, _MitraRequestService_checkMitraRequestExist = function _MitraRequestService_checkMitraRequestExist(id) {
    return __awaiter(this, void 0, void 0, function* () {
        // Query the database for the mitra request with the given ID
        const mitraRequest = yield database_1.db.queryOne('SELECT * FROM mitra_request WHERE id = ?', [id]);
        if (!mitraRequest) {
            throw new response_error_1.ResponseError(404, 'Mitra request tidak ditemukan');
        }
    });
};
