"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.listUsers = listUsers;
exports.getUser = getUser;
exports.createUser = createUser;
exports.updateUser = updateUser;
exports.deleteUser = deleteUser;
exports.getUserRoles = getUserRoles;
exports.addUserRole = addUserRole;
exports.removeUserRole = removeUserRole;
const userService = __importStar(require("../services/user"));
/**
 * List users with optional filters for role, role type, status, and pagination.
 *
 * @param input.role — filter by role name
 * @param input.roleType — filter by role type (superadmin, admin, member)
 * @param input.status — filter by user status
 * @param input.limit — maximum number of users to return
 * @param input.offset — number of users to skip for pagination
 * @returns `{ status: 200, data: User[] }` on success
 */
async function listUsers(input) {
    try {
        const result = await userService.listUsers(input);
        return { status: 200, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Retrieve a single user by ID.
 *
 * @param input.id — the user's unique identifier
 * @returns `{ status: 200, data: User }` on success, or `{ status: 404 }` if not found
 */
async function getUser(input) {
    try {
        const user = await userService.getUser(input.id);
        if (!user) {
            return { status: 404, error: 'User not found' };
        }
        return { status: 200, data: user };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Create a new user. Requires admin privileges.
 *
 * Validates that external_id is present and that any provided roles have valid
 * names and types. Returns 409 if a user with the same external_id already exists.
 *
 * @param input.external_id — external system identifier (required)
 * @param input.email — user's email address
 * @param input.display_name — user's display name
 * @param input.roles — initial role assignments, each with a role name and type (superadmin, admin, member)
 * @param input.metadata — arbitrary key-value metadata to attach to the user
 * @returns `{ status: 201, data: User }` on success, or `{ status: 409 }` on duplicate external_id
 */
async function createUser(input) {
    try {
        if (!input.external_id) {
            return { status: 400, error: 'external_id is required' };
        }
        if (input.roles) {
            for (const r of input.roles) {
                if (!r.role || !r.type || !userService.isValidRoleType(r.type)) {
                    return {
                        status: 400,
                        error: 'Each role must have a role name and type (superadmin, admin, member)',
                    };
                }
            }
        }
        const user = await userService.createUser({
            external_id: input.external_id,
            email: input.email,
            display_name: input.display_name,
            password: input.password,
            roles: input.roles,
            metadata: input.metadata,
        });
        return { status: 201, data: user };
    }
    catch (err) {
        if (err.code === '23505') {
            return { status: 409, error: 'User with this external_id already exists' };
        }
        return { status: 500, error: err.message };
    }
}
/**
 * Update an existing user's profile fields. Requires admin privileges.
 *
 * Only the provided fields are updated; omitted fields remain unchanged.
 *
 * @param input.id — the user's unique identifier (required)
 * @param input.email — new email address
 * @param input.display_name — new display name
 * @param input.status — new user status
 * @param input.metadata — replacement metadata object
 * @returns `{ status: 200, data: User }` on success, or `{ status: 404 }` if not found
 */
async function updateUser(input) {
    try {
        const { id, ...fields } = input;
        const user = await userService.updateUser(id, fields);
        if (!user) {
            return { status: 404, error: 'User not found' };
        }
        return { status: 200, data: user };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Delete a user by ID. Requires admin privileges.
 *
 * @param input.id — the user's unique identifier
 * @returns `{ status: 200, data: { deleted: true } }` on success, or `{ status: 404 }` if not found
 */
async function deleteUser(input) {
    try {
        const deleted = await userService.deleteUser(input.id);
        if (!deleted) {
            return { status: 404, error: 'User not found' };
        }
        return { status: 200, data: { deleted: true } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Retrieve all roles assigned to a user.
 *
 * @param input.id — the user's unique identifier
 * @returns `{ status: 200, data: { roles: Role[] } }` on success
 */
async function getUserRoles(input) {
    try {
        const roles = await userService.getUserRoles(input.id);
        return { status: 200, data: { roles } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Assign a role to a user. Requires admin privileges.
 *
 * Validates that both role and type are provided and that the type is one of
 * superadmin, admin, or member.
 *
 * @param input.id — the user's unique identifier
 * @param input.role — the role name to assign
 * @param input.type — the role type (superadmin, admin, or member)
 * @returns `{ status: 201, data: UserRole }` on success
 */
async function addUserRole(input) {
    try {
        if (!input.role || !input.type) {
            return { status: 400, error: 'role and type are required' };
        }
        if (!userService.isValidRoleType(input.type)) {
            return { status: 400, error: 'type must be superadmin, admin, or member' };
        }
        const result = await userService.addUserRole(input.id, input.role, input.type);
        return { status: 201, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Remove a role from a user. Requires admin privileges.
 *
 * @param input.id — the user's unique identifier
 * @param input.role — the role name to remove
 * @returns `{ status: 200, data: { removed: true } }` on success, or `{ status: 404 }` if role not found
 */
async function removeUserRole(input) {
    try {
        const removed = await userService.removeUserRole(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 };
    }
}
