import {
    bulkNotificationIdsSchema,
    getNotificationsSchema,
} from "@pkg/logic/domains/notifications/data";
import { getNotificationController } from "@pkg/logic/domains/notifications/controller";
import {
    getFlowExecCtxForRemoteFuncs,
    unauthorized,
} from "$lib/core/server.utils";
import { command, getRequestEvent, query } from "$app/server";
import * as v from "valibot";

const nc = getNotificationController();

export const getNotificationsSQ = query(
    getNotificationsSchema,
    async (input) => {
        const event = getRequestEvent();
        const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
        if (!fctx.userId) {
            return unauthorized(fctx);
        }
        const res = await nc.getNotifications(
            fctx,
            { ...input.filters, userId: fctx.userId },
            input.pagination,
        );
        return res.isOk()
            ? { data: res.value, error: null }
            : { data: null, error: res.error };
    },
);

export const markReadSC = command(
    bulkNotificationIdsSchema,
    async (payload) => {
        const event = getRequestEvent();
        const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
        if (!fctx.userId) {
            return unauthorized(fctx);
        }

        const res = await nc.markAsRead(
            fctx,
            [...payload.notificationIds],
            fctx.userId,
        );
        return res.isOk()
            ? { data: res.value, error: null }
            : { data: null, error: res.error };
    },
);

export const markUnreadSC = command(
    bulkNotificationIdsSchema,
    async (payload) => {
        const event = getRequestEvent();
        const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
        if (!fctx.userId) {
            return unauthorized(fctx);
        }

        const res = await nc.markAsUnread(
            fctx,
            [...payload.notificationIds],
            fctx.userId,
        );
        return res.isOk()
            ? { data: res.value, error: null }
            : { data: null, error: res.error };
    },
);

export const archiveSC = command(bulkNotificationIdsSchema, async (payload) => {
    const event = getRequestEvent();
    const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
    if (!fctx.userId) {
        return unauthorized(fctx);
    }

    const res = await nc.archive(
        fctx,
        [...payload.notificationIds],
        fctx.userId,
    );
    return res.isOk()
        ? { data: res.value, error: null }
        : { data: null, error: res.error };
});

export const unarchiveSC = command(
    bulkNotificationIdsSchema,
    async (payload) => {
        const event = getRequestEvent();
        const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
        if (!fctx.userId) {
            return unauthorized(fctx);
        }

        const res = await nc.unarchive(
            fctx,
            [...payload.notificationIds],
            fctx.userId,
        );
        return res.isOk()
            ? { data: res.value, error: null }
            : { data: null, error: res.error };
    },
);

export const deleteNotificationsSC = command(
    bulkNotificationIdsSchema,
    async (payload) => {
        const event = getRequestEvent();
        const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
        if (!fctx.userId) {
            return unauthorized(fctx);
        }

        const res = await nc.deleteNotifications(
            fctx,
            [...payload.notificationIds],
            fctx.userId,
        );
        return res.isOk()
            ? { data: res.value, error: null }
            : { data: null, error: res.error };
    },
);

export const markAllReadSC = command(v.object({}), async () => {
    const event = getRequestEvent();
    const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
    if (!fctx.userId) {
        return unauthorized(fctx);
    }

    const res = await nc.markAllAsRead(fctx, fctx.userId);
    return res.isOk()
        ? { data: res.value, error: null }
        : { data: null, error: res.error };
});

export const getUnreadCountSQ = query(async () => {
    const event = getRequestEvent();
    const fctx = await getFlowExecCtxForRemoteFuncs(event.locals);
    if (!fctx.userId) {
        return unauthorized(fctx);
    }

    const res = await nc.getUnreadCount(fctx, fctx.userId);
    return res.isOk()
        ? { data: res.value, error: null }
        : { data: null, error: res.error };
});
