"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.listBots = listBots;
exports.getBot = getBot;
exports.createBot = createBot;
exports.updateBot = updateBot;
exports.deleteBot = deleteBot;
exports.getBotRoles = getBotRoles;
exports.addBotRole = addBotRole;
exports.removeBotRole = removeBotRole;
exports.listBotKeys = listBotKeys;
exports.createBotKey = createBotKey;
exports.revokeBotKey = revokeBotKey;
const iam = __importStar(require("../services/iam"));
const user_1 = require("../services/user");
/**
 * List all bot accounts with pagination.
 *
 * @param input.limit — maximum number of bots to return (default 50)
 * @param input.offset — number of bots to skip for pagination (default 0)
 * @returns `{ status: 200, data: Bot[] }` paginated list of bots
 */
async function listBots(input) {
    try {
        const limit = input.limit ?? 50;
        const offset = input.offset ?? 0;
        const result = await iam.listBots(limit, offset);
        return { status: 200, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Retrieve a single bot account by ID.
 *
 * @param input.id — unique identifier of the bot
 * @returns `{ status: 200, data: Bot }` the bot record, or 404 if not found
 */
async function getBot(input) {
    try {
        const bot = await iam.getBot(input.id);
        if (!bot) {
            return { status: 404, error: 'Bot not found' };
        }
        return { status: 200, data: bot };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Create a new bot account with optional roles.
 *
 * Validates that each provided role has a valid type (superadmin, admin, member).
 * Returns 409 if a bot with the same name already exists.
 *
 * @param input.name — unique bot name (required)
 * @param input.description — optional text description of the bot
 * @param input.display_name — optional human-friendly display name
 * @param input.roles — optional list of roles to assign at creation, each with a role name and type
 * @param auth — authenticated user context; userId is recorded as the bot creator
 * @returns `{ status: 201, data: Bot }` the newly created bot record
 */
async function createBot(input, auth) {
    try {
        if (!input.name) {
            return { status: 400, error: 'name is required' };
        }
        if (input.roles) {
            for (const r of input.roles) {
                if (!r.role || !r.type || !(0, user_1.isValidRoleType)(r.type)) {
                    return {
                        status: 400,
                        error: 'Each role must have a role name and type (superadmin, admin, member)',
                    };
                }
            }
        }
        const bot = await iam.createBot({
            name: input.name,
            description: input.description,
            display_name: input.display_name,
            roles: input.roles,
            created_by: auth?.userId,
        });
        return { status: 201, data: bot };
    }
    catch (err) {
        if (err.code === '23505') {
            return { status: 409, error: 'Bot with this name already exists' };
        }
        return { status: 500, error: err.message };
    }
}
/**
 * Update mutable fields on an existing bot account.
 *
 * @param input.id — unique identifier of the bot to update
 * @param input.display_name — new display name
 * @param input.description — new description
 * @param input.status — new status value
 * @returns `{ status: 200, data: Bot }` the updated bot record, or 404 if not found
 */
async function updateBot(input) {
    try {
        const { id, ...fields } = input;
        const bot = await iam.updateBot(id, fields);
        if (!bot) {
            return { status: 404, error: 'Bot not found' };
        }
        return { status: 200, data: bot };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Delete a bot account by ID.
 *
 * @param input.id — unique identifier of the bot to delete
 * @returns `{ status: 200, data: { deleted: true } }` on success, or 404 if not found
 */
async function deleteBot(input) {
    try {
        const deleted = await iam.deleteBot(input.id);
        if (!deleted) {
            return { status: 404, error: 'Bot not found' };
        }
        return { status: 200, data: { deleted: true } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * List all roles assigned to a bot account.
 *
 * @param input.id — unique identifier of the bot
 * @returns `{ status: 200, data: { roles: Role[] } }` the bot's roles, or 404 if bot not found
 */
async function getBotRoles(input) {
    try {
        const bot = await iam.getBot(input.id);
        if (!bot) {
            return { status: 404, error: 'Bot not found' };
        }
        const roles = await iam.getBotRoles(input.id);
        return { status: 200, data: { roles } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Assign a role to a bot account.
 *
 * Validates that the role type is one of superadmin, admin, or member.
 *
 * @param input.id — unique identifier of the bot
 * @param input.role — role name to assign
 * @param input.type — role type (superadmin, admin, or member)
 * @returns `{ status: 201, data: Role }` the newly assigned role, or 404 if bot not found
 */
async function addBotRole(input) {
    try {
        if (!input.role || !input.type) {
            return { status: 400, error: 'role and type are required' };
        }
        if (!(0, user_1.isValidRoleType)(input.type)) {
            return { status: 400, error: 'type must be superadmin, admin, or member' };
        }
        const bot = await iam.getBot(input.id);
        if (!bot) {
            return { status: 404, error: 'Bot not found' };
        }
        const result = await iam.addBotRole(input.id, input.role, input.type);
        return { status: 201, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Remove a role from a bot account.
 *
 * @param input.id — unique identifier of the bot
 * @param input.role — role name to remove
 * @returns `{ status: 200, data: { removed: true } }` on success, or 404 if role not found
 */
async function removeBotRole(input) {
    try {
        const removed = await iam.removeBotRole(input.id, input.role);
        if (!removed) {
            return { status: 404, error: 'Role not found' };
        }
        return { status: 200, data: { removed: true } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * List all API keys for a bot account.
 *
 * @param input.id — unique identifier of the bot
 * @returns `{ status: 200, data: { keys: ApiKey[] } }` the bot's API keys, or 404 if bot not found
 */
async function listBotKeys(input) {
    try {
        const bot = await iam.getBot(input.id);
        if (!bot) {
            return { status: 404, error: 'Bot not found' };
        }
        const keys = await iam.listBotKeys(input.id);
        return { status: 200, data: { keys } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Create a new API key for a bot account.
 *
 * Returns 409 if an API key with the same name already exists for this bot.
 *
 * @param input.id — unique identifier of the bot
 * @param input.name — human-readable name for the API key (required)
 * @param input.scopes — optional list of permission scopes to restrict the key
 * @param input.expires_at — optional ISO 8601 expiration timestamp
 * @returns `{ status: 201, data: ApiKey }` the newly created API key (includes the secret)
 */
async function createBotKey(input) {
    try {
        if (!input.name) {
            return { status: 400, error: 'name is required' };
        }
        const expiresAt = input.expires_at ? new Date(input.expires_at) : undefined;
        const result = await iam.createBotKey(input.id, input.name, input.scopes || [], expiresAt);
        return { status: 201, data: result };
    }
    catch (err) {
        if (err.message === 'Bot not found') {
            return { status: 404, error: err.message };
        }
        if (err.code === '23505') {
            return { status: 409, error: 'API key with this name already exists for this bot' };
        }
        return { status: 500, error: err.message };
    }
}
/**
 * Revoke an existing bot API key.
 *
 * @param input.keyId — unique identifier of the API key to revoke
 * @returns `{ status: 200, data: { revoked: true } }` on success, or 404 if key not found
 */
async function revokeBotKey(input) {
    try {
        const revoked = await iam.revokeBotKey(input.keyId);
        if (!revoked) {
            return { status: 404, error: 'API key not found' };
        }
        return { status: 200, data: { revoked: true } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
