"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.browseComments = browseComments;
exports.addComment = addComment;
exports.deleteComment = deleteComment;
const commandContext_1 = require("../commandContext");
const errors_1 = require("../errors");
const messages_1 = require("../messages");
const output_1 = require("../output");
const refs_1 = require("../refs");
function parsePositiveInteger(raw, label, command) {
    if (raw === undefined) {
        return null;
    }
    const parsed = typeof raw === 'number' ? raw : Number.parseInt(String(raw), 10);
    if (!Number.isInteger(parsed) || parsed <= 0) {
        (0, messages_1.printErrorWithHelp)(`${label} must be a positive integer.`, [], { command });
        process.exitCode = 1;
        return null;
    }
    return parsed;
}
function printComments(nodes, depth = 0) {
    const indent = '  '.repeat(depth);
    for (const node of nodes) {
        const author = node.author?.displayName || node.author?.username || 'unknown';
        const creatorBadge = node.authorIsCreator ? ' [creator]' : '';
        const body = node.isDeleted ? '[deleted]' : node.body;
        console.log(`${indent}- #${node.id} ${author}${creatorBadge} | ${(0, output_1.formatTimestamp)(node.createdAt)}`);
        console.log(`${indent}  ${body}`);
        if (Array.isArray(node.replies) && node.replies.length > 0) {
            printComments(node.replies, depth + 1);
        }
    }
}
async function browseComments(rawRef, options = {}) {
    let ref;
    try {
        ref = (0, refs_1.parseContentRef)(rawRef ?? '');
    }
    catch {
        (0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop comments browse playdrop/app/hangingout'], { command: 'comments browse' });
        process.exitCode = 1;
        return;
    }
    await (0, commandContext_1.withPublicEnvironment)('comments browse', async ({ client }) => {
        try {
            const response = await client.fetchContentComments((0, refs_1.contentKindToSavedItemKind)(ref.kind), ref.creator, ref.name);
            const items = response.comments ?? [];
            if (options.json) {
                (0, output_1.printJson)({ items });
                return;
            }
            if (items.length === 0) {
                console.log(`No comments found for "${ref.ref}".`);
                console.log('Next: run "playdrop comments add <ref> --body <text>" to start the conversation.');
                return;
            }
            console.log(`Comments for ${ref.ref}:\n`);
            printComments(items);
            console.log('\nNext: run "playdrop comments add <ref> --body <text>" to reply.');
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'comments browse', 'Comment lookup', {
                apiMessage: (apiError) => {
                    if (apiError.status === 404) {
                        return {
                            problem: `No item was found for "${ref.ref}".`,
                            suggestions: ['Check the ref and retry.', 'Run "playdrop browse" to explore available content.'],
                        };
                    }
                    if (apiError.status === 401 || apiError.status === 403) {
                        return {
                            problem: `You do not have access to comments for "${ref.ref}".`,
                            suggestions: ['Run "playdrop auth login" if this is private content you own.'],
                        };
                    }
                    return {
                        problem: `Comment lookup failed with status ${apiError.status}.`,
                        suggestions: ['Retry in a moment.'],
                    };
                },
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function addComment(rawRef, options = {}) {
    let ref;
    try {
        ref = (0, refs_1.parseContentRef)(rawRef ?? '');
    }
    catch {
        (0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop comments add playdrop/app/hangingout --body "Nice work"'], { command: 'comments add' });
        process.exitCode = 1;
        return;
    }
    const body = typeof options.body === 'string' ? options.body.trim() : '';
    if (!body) {
        (0, messages_1.printErrorWithHelp)('Comment body is required.', ['Use --body <text>.'], { command: 'comments add' });
        process.exitCode = 1;
        return;
    }
    const replyTo = parsePositiveInteger(options.replyTo, '--reply-to', 'comments add');
    if (options.replyTo !== undefined && replyTo === null) {
        return;
    }
    await (0, commandContext_1.withEnvironment)('comments add', 'Adding a comment', async ({ client }) => {
        try {
            const response = await client.createContentComment((0, refs_1.contentKindToSavedItemKind)(ref.kind), ref.creator, ref.name, {
                body,
                parentCommentId: replyTo ?? undefined,
            });
            if (options.json) {
                (0, output_1.printJson)({ comment: response.comment });
                return;
            }
            (0, output_1.printSuccess)(`Comment added to ${ref.ref}.`, ['Next: run "playdrop comments browse ' + ref.ref + '" to review the thread.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'comments add', 'Add comment', {
                apiMessage: (apiError) => {
                    if (apiError.status === 401 || apiError.status === 403) {
                        return {
                            problem: 'Adding a comment requires you to be logged in.',
                            suggestions: ['Run "playdrop auth login" and retry.'],
                        };
                    }
                    if (apiError.status === 404) {
                        return {
                            problem: `No item was found for "${ref.ref}".`,
                            suggestions: ['Check the ref and retry.'],
                        };
                    }
                    return {
                        problem: `Adding a comment failed with status ${apiError.status}.`,
                        suggestions: ['Retry in a moment.'],
                    };
                },
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function deleteComment(commentId, options = {}) {
    const numericId = parsePositiveInteger(commentId, 'Comment id', 'comments delete');
    if (numericId === null) {
        return;
    }
    await (0, commandContext_1.withEnvironment)('comments delete', 'Deleting a comment', async ({ client }) => {
        try {
            const response = await client.deleteContentComment(numericId);
            if (options.json) {
                (0, output_1.printJson)({ success: Boolean(response.success), commentId: numericId });
                return;
            }
            (0, output_1.printSuccess)(`Comment #${numericId} deleted.`, ['Next: run "playdrop comments browse <ref>" to confirm the thread state.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'comments delete', 'Delete comment', {
                apiMessage: (apiError) => {
                    if (apiError.status === 401 || apiError.status === 403) {
                        return {
                            problem: 'Deleting a comment requires a valid login with permission to manage it.',
                            suggestions: ['Run "playdrop auth login" and retry.'],
                        };
                    }
                    if (apiError.status === 404) {
                        return {
                            problem: `Comment #${numericId} was not found.`,
                            suggestions: ['Check the id and retry.'],
                        };
                    }
                    return {
                        problem: `Deleting a comment failed with status ${apiError.status}.`,
                        suggestions: ['Retry in a moment.'],
                    };
                },
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
