"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendFeedback = sendFeedback;
exports.browseFeedback = browseFeedback;
exports.deleteFeedbackEntry = deleteFeedbackEntry;
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
const types_1 = require("@playdrop/types");
const commandContext_1 = require("../commandContext");
const errors_1 = require("../errors");
const messages_1 = require("../messages");
const output_1 = require("../output");
const clientInfo_1 = require("../clientInfo");
const MAX_FEEDBACK_TITLE_LENGTH = 70;
const MAX_FEEDBACK_COMMENT_LENGTH = 10000;
const FEEDBACK_CATEGORY_SET = new Set(types_1.FEEDBACK_CATEGORY_VALUES);
function parsePositiveInteger(raw, label, command, options = {}) {
    if (raw === undefined) {
        return null;
    }
    const parsed = typeof raw === 'number' ? raw : Number.parseInt(String(raw), 10);
    if (!Number.isInteger(parsed) || parsed < 0 || (!options.zeroAllowed && parsed === 0)) {
        (0, messages_1.printErrorWithHelp)(`${label} must be ${options.zeroAllowed ? 'zero or a positive integer' : 'a positive integer'}.`, [], { command });
        process.exitCode = 1;
        return null;
    }
    return parsed;
}
function parseFeedbackCategory(raw, command) {
    const normalized = typeof raw === 'string' && raw.trim().length > 0 ? raw.trim() : 'other';
    if (!FEEDBACK_CATEGORY_SET.has(normalized)) {
        (0, messages_1.printErrorWithHelp)(`Feedback category must be one of: ${types_1.FEEDBACK_CATEGORY_VALUES.join(', ')}.`, [], { command });
        process.exitCode = 1;
        return null;
    }
    return normalized;
}
async function loadCommentFromFile(filePath) {
    const absolute = node_path_1.default.resolve(filePath);
    try {
        const contents = await node_fs_1.promises.readFile(absolute, 'utf8');
        const trimmed = contents.trim();
        return trimmed.length > 0 ? trimmed : null;
    }
    catch {
        return null;
    }
}
async function sendFeedback(options = {}) {
    const title = typeof options.title === 'string' ? options.title.trim() : '';
    if (!title) {
        (0, messages_1.printErrorWithHelp)('Feedback title is required.', ['Use --title <title>.'], { command: 'feedback send' });
        process.exitCode = 1;
        return;
    }
    if (title.length > MAX_FEEDBACK_TITLE_LENGTH) {
        (0, messages_1.printErrorWithHelp)(`Feedback title must be ${MAX_FEEDBACK_TITLE_LENGTH} characters or fewer.`, [], { command: 'feedback send' });
        process.exitCode = 1;
        return;
    }
    const commentParts = [];
    if (typeof options.comment === 'string' && options.comment.trim().length > 0) {
        commentParts.push(options.comment.trim());
    }
    if (typeof options.file === 'string' && options.file.trim().length > 0) {
        const fileComment = await loadCommentFromFile(options.file.trim());
        if (!fileComment) {
            (0, messages_1.printErrorWithHelp)(`Could not read feedback text from "${options.file}".`, ['Provide a readable file or use --comment <text>.'], { command: 'feedback send' });
            process.exitCode = 1;
            return;
        }
        commentParts.push(fileComment);
    }
    const comment = commentParts.join('\n\n').trim();
    if (!comment) {
        (0, messages_1.printErrorWithHelp)('Feedback text is required.', ['Use --comment <text> or --file <path>.'], { command: 'feedback send' });
        process.exitCode = 1;
        return;
    }
    if (comment.length > MAX_FEEDBACK_COMMENT_LENGTH) {
        (0, messages_1.printErrorWithHelp)(`Feedback text must be ${MAX_FEEDBACK_COMMENT_LENGTH} characters or fewer.`, [], { command: 'feedback send' });
        process.exitCode = 1;
        return;
    }
    const category = parseFeedbackCategory(options.category, 'feedback send');
    if (!category) {
        return;
    }
    await (0, commandContext_1.withEnvironment)('feedback send', 'Sending feedback', async ({ client }) => {
        try {
            const response = await client.submitFeedback({
                title,
                comment,
                client: 'cli',
                category,
                version: (0, clientInfo_1.getCliVersion)(),
                build: String((0, clientInfo_1.getCliBuild)()),
            });
            if (options.json) {
                (0, output_1.printJson)({ success: true, response });
                return;
            }
            (0, output_1.printSuccess)('Feedback sent.', ['Next: run "playdrop feedback browse" if you want to review your submitted feedback.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'feedback send', 'Feedback send', {
                apiMessage: (apiError) => ({
                    problem: `Feedback send failed with status ${apiError.status}.`,
                    suggestions: ['Check the provided fields and retry.', 'Run "playdrop auth login" if your session may be stale.'],
                }),
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function browseFeedback(options = {}) {
    const limit = options.limit !== undefined ? parsePositiveInteger(options.limit, '--limit', 'feedback browse') : null;
    if (options.limit !== undefined && limit === null) {
        return;
    }
    const offset = options.offset !== undefined ? parsePositiveInteger(options.offset, '--offset', 'feedback browse', { zeroAllowed: true }) : null;
    if (options.offset !== undefined && offset === null) {
        return;
    }
    const userId = options.userId !== undefined ? parsePositiveInteger(options.userId, '--user-id', 'feedback browse') : null;
    if (options.userId !== undefined && userId === null) {
        return;
    }
    const clientFilter = typeof options.client === 'string' && options.client.trim().length > 0 ? options.client.trim() : undefined;
    if (clientFilter && clientFilter !== 'cli') {
        (0, messages_1.printErrorWithHelp)('CLI feedback browse only supports --client cli.', [], { command: 'feedback browse' });
        process.exitCode = 1;
        return;
    }
    await (0, commandContext_1.withEnvironment)('feedback browse', 'Browsing feedback', async ({ client }) => {
        try {
            const response = await client.listFeedback({
                limit: limit ?? undefined,
                offset: offset ?? undefined,
                client: clientFilter,
                userId: userId ?? undefined,
            });
            const items = response.feedback ?? [];
            if (options.json) {
                (0, output_1.printJson)({ items, pagination: response.pagination });
                return;
            }
            if (items.length === 0) {
                console.log('No feedback entries found.');
                return;
            }
            console.log('Feedback:\n');
            for (const item of items) {
                console.log(`#${item.id} | ${item.username} | ${(0, output_1.formatTimestamp)(item.createdAt)}`);
                console.log(`  ${item.title}`);
                console.log(`  ${item.comment}`);
            }
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'feedback browse', 'Feedback browse', {
                apiMessage: (apiError) => {
                    if (apiError.status === 403) {
                        return {
                            problem: 'You can only browse your own feedback unless you are an admin.',
                            suggestions: ['Drop --user-id or use your own user id, then retry.'],
                        };
                    }
                    return {
                        problem: `Feedback browse failed with status ${apiError.status}.`,
                        suggestions: ['Ensure you are logged in with a valid Playdrop session.'],
                    };
                },
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function deleteFeedbackEntry(rawId, options = {}) {
    const id = parsePositiveInteger(rawId, 'Feedback id', 'feedback delete');
    if (id === null) {
        return;
    }
    await (0, commandContext_1.withEnvironment)('feedback delete', 'Deleting feedback', async ({ client }) => {
        try {
            const response = await client.deleteFeedback(id);
            if (options.json) {
                (0, output_1.printJson)({ success: Boolean(response.success), id });
                return;
            }
            (0, output_1.printSuccess)(`Feedback #${id} deleted.`, ['Next: run "playdrop feedback browse" to review the remaining entries.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'feedback delete', 'Feedback delete', {
                apiMessage: (apiError) => {
                    if (apiError.status === 403) {
                        return {
                            problem: 'Only admins can delete feedback.',
                            suggestions: [],
                        };
                    }
                    return {
                        problem: `Feedback delete failed with status ${apiError.status}.`,
                        suggestions: ['Check the id and your permissions, then retry.'],
                    };
                },
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
