"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.browseNotifications = browseNotifications;
exports.readNotification = readNotification;
exports.readAllNotifications = readAllNotifications;
const commandContext_1 = require("../commandContext");
const errors_1 = require("../errors");
const messages_1 = require("../messages");
const output_1 = require("../output");
function parseStatus(raw) {
    if (!raw || raw.trim().length === 0) {
        return 'unread';
    }
    const normalized = raw.trim().toLowerCase();
    if (normalized === 'all' || normalized === 'read' || normalized === 'unread') {
        return normalized;
    }
    return null;
}
function parsePositiveInteger(raw, label, fallback) {
    if (raw === undefined) {
        return fallback;
    }
    const parsed = typeof raw === 'number' ? raw : Number.parseInt(String(raw), 10);
    if (!Number.isInteger(parsed) || parsed < 0) {
        return null;
    }
    if (label === 'limit' && parsed <= 0) {
        return null;
    }
    return parsed;
}
async function fetchNotificationsByStatus(fetchPage, status, limit, offset) {
    if (status === 'all' || status === 'unread') {
        return fetchPage(status, limit, offset);
    }
    const pageSize = Math.max(limit, 50);
    const collected = [];
    let unreadCount = 0;
    let cursor = 0;
    let hasMore = true;
    while (hasMore && collected.length < offset + limit) {
        const response = await fetchPage('all', pageSize, cursor);
        unreadCount = response.unreadCount;
        const matching = response.notifications.filter((notification) => notification.readAt !== null);
        collected.push(...matching);
        if (!response.pagination.hasMore || response.notifications.length === 0) {
            hasMore = false;
            break;
        }
        cursor += response.notifications.length;
    }
    const notifications = collected.slice(offset, offset + limit);
    return {
        notifications,
        unreadCount,
        pagination: {
            limit,
            offset,
            count: notifications.length,
            hasMore: collected.length > offset + limit || hasMore,
        },
    };
}
async function browseNotifications(options = {}) {
    const status = parseStatus(options.status);
    if (!status) {
        (0, messages_1.printErrorWithHelp)(`Status "${options.status ?? ''}" is not supported.`, ['Use one of: unread, read, all.'], { command: 'notifications browse' });
        process.exitCode = 1;
        return;
    }
    const limit = parsePositiveInteger(options.limit, 'limit', 20);
    if (limit === null) {
        (0, messages_1.printErrorWithHelp)('The --limit value must be a positive integer.', ['Example: --limit 20'], { command: 'notifications browse' });
        process.exitCode = 1;
        return;
    }
    const offset = parsePositiveInteger(options.offset, 'offset', 0);
    if (offset === null) {
        (0, messages_1.printErrorWithHelp)('The --offset value must be zero or a positive integer.', ['Example: --offset 20'], { command: 'notifications browse' });
        process.exitCode = 1;
        return;
    }
    await (0, commandContext_1.withEnvironment)('notifications browse', 'Checking your notifications', async ({ client }) => {
        try {
            const response = await fetchNotificationsByStatus(async (requestStatus, requestLimit, requestOffset) => client.fetchNotifications({
                status: requestStatus,
                limit: requestLimit,
                offset: requestOffset,
            }), status, limit, offset);
            if (options.json) {
                (0, output_1.printJson)({
                    notifications: response.notifications,
                    unreadCount: response.unreadCount,
                    pagination: response.pagination,
                });
                return;
            }
            if (response.notifications.length === 0) {
                console.log(`No ${status} notifications found.`);
                console.log('Next: run "playdrop browse" or "playdrop creations browse" to check recent activity.');
                return;
            }
            console.log(`Notifications (${status}):\n`);
            for (const notification of response.notifications) {
                const state = notification.readAt ? 'read' : 'unread';
                console.log(`#${notification.id} | ${state} | ${(0, output_1.formatTimestamp)(notification.createdAt)}`);
                console.log(`  ${notification.title}`);
                if (notification.body) {
                    console.log(`  ${notification.body}`);
                }
            }
            console.log('\nNext: run "playdrop notifications read <id>" or "playdrop notifications read-all".');
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'notifications browse', 'Notification lookup', {
                apiMessage: (apiError) => ({
                    problem: `Notification lookup failed with status ${apiError.status}.`,
                    suggestions: ['Run "playdrop auth login" and retry.'],
                }),
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function readNotification(rawId, options = {}) {
    const id = parsePositiveInteger(rawId, 'Notification id', 0);
    if (id === null || id === 0) {
        (0, messages_1.printErrorWithHelp)('Notification id must be a positive integer.', ['Example: playdrop notifications read 42'], { command: 'notifications read' });
        process.exitCode = 1;
        return;
    }
    await (0, commandContext_1.withEnvironment)('notifications read', 'Marking a notification as read', async ({ client }) => {
        try {
            const response = await client.markNotificationRead(id);
            if (options.json) {
                (0, output_1.printJson)({ success: Boolean(response.success), unreadCount: response.unreadCount });
                return;
            }
            (0, output_1.printSuccess)(`Notification #${id} marked as read.`, ['Next: run "playdrop notifications browse --status unread" to review what remains.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'notifications read', 'Notification update', {
                apiMessage: (apiError) => ({
                    problem: `Notification update failed with status ${apiError.status}.`,
                    suggestions: ['Run "playdrop auth login" and retry.'],
                }),
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
async function readAllNotifications(options = {}) {
    await (0, commandContext_1.withEnvironment)('notifications read-all', 'Marking all notifications as read', async ({ client }) => {
        try {
            const response = await client.markAllNotificationsRead();
            if (options.json) {
                (0, output_1.printJson)({ success: Boolean(response.success), unreadCount: response.unreadCount });
                return;
            }
            (0, output_1.printSuccess)('All notifications marked as read.', ['Next: run "playdrop notifications browse --status unread" to confirm your inbox is clear.']);
        }
        catch (error) {
            const handled = (0, errors_1.handleCommandFailure)(error, 'notifications read-all', 'Notification update', {
                apiMessage: (apiError) => ({
                    problem: `Notification update failed with status ${apiError.status}.`,
                    suggestions: ['Run "playdrop auth login" and retry.'],
                }),
            });
            if (!handled) {
                throw error;
            }
        }
    });
}
