"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.TokenSource = void 0;
exports.recordTokenUsage = recordTokenUsage;
exports.allocateTokens = allocateTokens;
exports.getAvailableTokens = getAvailableTokens;
exports.getAllocatedTokens = getAllocatedTokens;
exports.getTokenStats = getTokenStats;
const axios_1 = __importDefault(require("axios"));
const https_1 = __importDefault(require("https"));
const utils_1 = require("../utils");
const workspace_1 = require("../controllers/workspace");
const cliconfig_1 = require("../database/cliconfig");
/**
 * Create an axios instance with appropriate SSL configuration based on environment
 * @param config Optional axios request configuration
 * @returns Configured axios instance
 */
function createAxiosInstance(config = {}) {
    // Only disable certificate verification in non-production environments
    if (process.env.NODE_ENV !== 'production') {
        const httpsAgent = new https_1.default.Agent({
            rejectUnauthorized: false // Ignore certificate verification errors
        });
        return axios_1.default.create(Object.assign(Object.assign({}, config), { httpsAgent }));
    }
    return axios_1.default.create(config);
}
/**
 * Enum for token sources
 */
var TokenSource;
(function (TokenSource) {
    TokenSource["PURCHASE"] = "PURCHASE";
    TokenSource["PROMOTION"] = "PROMOTION";
    TokenSource["FREE_TIER"] = "FREE_TIER";
    TokenSource["REFUND"] = "REFUND";
    TokenSource["ADMIN"] = "ADMIN";
})(TokenSource || (exports.TokenSource = TokenSource = {}));
/**
 * Get the base URL for token API calls
 * @param apptileBackendUrl The backend URL from app config
 * @returns The base URL for token API calls
 */
function getTokenApiBaseUrl(apptileBackendUrl) {
    return process.env.NODE_ENV === "production" ? `${apptileBackendUrl}/admin/api/tokens` : `${apptileBackendUrl}/api/tokens`;
}
/**
 * Record token usage for an app
 * @param tokenUsageBody The token usage data
 * @param appId The app ID
 * @returns Promise with the token usage response
 */
function recordTokenUsage(tokenUsageBody, appId) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
            if (!openedApp) {
                throw new Error(`App with ID ${appId} not found or not open`);
            }
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {
                'Content-Type': 'application/json'
            });
            const baseUrl = getTokenApiBaseUrl(apptileConfig.APPTILE_BACKEND_URL);
            const response = yield createAxiosInstance().post(`${baseUrl}/usage`, tokenUsageBody, headers);
            if (response.status >= 400) {
                throw new Error(`Failed to record token usage: ${response.data}`);
            }
            console.info(`Token usage recorded successfully for app ${appId}`);
            return response.data;
        }
        catch (error) {
            console.info(`Error recording token usage: ${error.message}`);
            return undefined;
        }
    });
}
/**
 * Add tokens to an organization
 * @param tokenAllocation The token allocation data
 * @param appId The app ID (used to get authentication)
 * @returns Promise with the token allocation response
 */
function allocateTokens(tokenAllocation, appId) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
            if (!openedApp) {
                throw new Error(`App with ID ${appId} not found or not open`);
            }
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {
                'Content-Type': 'application/json'
            });
            const baseUrl = getTokenApiBaseUrl(apptileConfig.APPTILE_BACKEND_URL);
            const response = yield createAxiosInstance().post(`${baseUrl}/allocate`, tokenAllocation, headers);
            if (response.status >= 400) {
                throw new Error(`Failed to allocate tokens: ${response.data}`);
            }
            console.info(`Tokens allocated successfully for organization ${tokenAllocation.organizationId}`);
            return response.data;
        }
        catch (error) {
            console.info(`Error allocating tokens: ${error.message}`);
            return undefined;
        }
    });
}
/**
 * Get available tokens for an organization
 * @param organizationId The organization ID
 * @param appId The app ID (used to get authentication)
 * @returns Promise with the available tokens response
 */
function getAvailableTokens(organizationId, appId) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
            if (!openedApp) {
                throw new Error(`App with ID ${appId} not found or not open`);
            }
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {});
            const baseUrl = getTokenApiBaseUrl(apptileConfig.APPTILE_BACKEND_URL);
            const response = yield createAxiosInstance().get(`${baseUrl}/available/${organizationId}`, headers);
            if (response.status >= 400) {
                throw new Error(`Failed to get available tokens: ${response.data}`);
            }
            return response.data;
        }
        catch (error) {
            console.info(`Error getting available tokens: ${error.message}`);
            return undefined;
        }
    });
}
/**
 * Get allocated tokens for an organization
 * @param organizationId The organization ID
 * @param appId The app ID (used to get authentication)
 * @returns Promise with the allocated tokens response
 */
function getAllocatedTokens(organizationId, appId) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
            if (!openedApp) {
                throw new Error(`App with ID ${appId} not found or not open`);
            }
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {});
            const baseUrl = getTokenApiBaseUrl(apptileConfig.APPTILE_BACKEND_URL);
            const response = yield createAxiosInstance().get(`${baseUrl}/allocated/${organizationId}`, headers);
            if (response.status >= 400) {
                throw new Error(`Failed to get allocated tokens: ${response.data}`);
            }
            return response.data;
        }
        catch (error) {
            console.info(`Error getting allocated tokens: ${error.message}`);
            return undefined;
        }
    });
}
/**
 * Get token usage statistics for an organization
 * @param organizationId The organization ID
 * @param appId The app ID (used to get authentication)
 * @returns Promise with the token stats response
 */
function getTokenStats(organizationId, appId) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
            if (!openedApp) {
                throw new Error(`App with ID ${appId} not found or not open`);
            }
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {});
            const baseUrl = getTokenApiBaseUrl(apptileConfig.APPTILE_BACKEND_URL);
            const response = yield createAxiosInstance().get(`${baseUrl}/stats/${organizationId}`, headers);
            if (response.status >= 400) {
                throw new Error(`Failed to get token stats: ${response.data}`);
            }
            return response.data;
        }
        catch (error) {
            console.info(`Error getting token stats: ${error.message}`);
            return undefined;
        }
    });
}
