import { FlowExecCtx } from "@/core/flow.execution.context";
import { okAsync } from "neverthrow";
import {
    NotificationFilters,
    PaginationOptions,
} from "./data";
import { NotificationRepository } from "./repository";
import { db } from "@pkg/db";

export class NotificationController {
    constructor(private notifsRepo: NotificationRepository) {}

    getNotifications(
        fctx: FlowExecCtx,
        filters: NotificationFilters,
        pagination: PaginationOptions,
    ) {
        return this.notifsRepo.getNotifications(fctx, filters, pagination);
    }

    markAsRead(
        fctx: FlowExecCtx,
        notificationIds: number[],
        userId: string,
    ) {
        return this.notifsRepo.markAsRead(fctx, notificationIds, userId);
    }

    markAsUnread(
        fctx: FlowExecCtx,
        notificationIds: number[],
        userId: string,
    ) {
        return this.notifsRepo.markAsUnread(fctx, notificationIds, userId);
    }

    archive(
        fctx: FlowExecCtx,
        notificationIds: number[],
        userId: string,
    ) {
        return this.notifsRepo.archive(fctx, notificationIds, userId);
    }

    unarchive(
        fctx: FlowExecCtx,
        notificationIds: number[],
        userId: string,
    ) {
        return this.notifsRepo.unarchive(fctx, notificationIds, userId);
    }

    deleteNotifications(
        fctx: FlowExecCtx,
        notificationIds: number[],
        userId: string,
    ) {
        return this.notifsRepo.deleteNotifications(fctx, notificationIds, userId);
    }

    getUnreadCount(
        fctx: FlowExecCtx,
        userId: string,
    ) {
        return this.notifsRepo.getUnreadCount(fctx, userId);
    }

    markAllAsRead(
        fctx: FlowExecCtx,
        userId: string,
    ) {
        // Get all unread notification IDs for this user
        const filters: NotificationFilters = {
            userId,
            isRead: false,
            isArchived: false,
        };

        // Get a large number to handle bulk operations
        const pagination: PaginationOptions = { page: 1, pageSize: 1000 };

        return this.notifsRepo
            .getNotifications(fctx, filters, pagination)
            .map((paginated) => paginated.data.map((n) => n.id))
            .andThen((notificationIds) => {
                if (notificationIds.length === 0) {
                    return okAsync(true);
                }
                return this.notifsRepo.markAsRead(fctx, notificationIds, userId);
            });
    }
}

export function getNotificationController(): NotificationController {
    return new NotificationController(new NotificationRepository(db));
}
