import { LogError } from '@memberjunction/core';
import { ResourcePermissionEngine } from '../ResourcePermissions/ResourcePermissionEngine.js';
let registeredHandler = null;
/**
 * Register a custom dispatcher (e.g., one backed by `NotificationEngine.SendNotification`).
 * Typically called once at server startup. Subsequent calls replace the handler.
 * Passing `null` restores the default in-app-only behavior.
 */
export function RegisterShareNotificationHandler(handler) {
    registeredHandler = handler;
}
/**
 * Create and deliver a share notification. If a custom handler has been
 * registered via {@link RegisterShareNotificationHandler}, it's called first;
 * otherwise (and as a fallback on handler error) we write an in-app
 * `MJ: User Notifications` row directly.
 *
 * Returns `true` when the notification was delivered successfully. Never
 * throws — sharing succeeds even if notification delivery fails.
 */
export async function CreateShareNotification(input) {
    // Self-shares are a no-op (guards against duplicate-notification loops on seeded data).
    if (input.GrantorUserID === input.GranteeUserID)
        return true;
    if (!input.GranteeUserID || !input.ResourceRecordID)
        return true;
    if (registeredHandler) {
        try {
            return await registeredHandler(input);
        }
        catch (err) {
            LogError(`Share notification handler threw; falling back to in-app only delivery: ${err instanceof Error ? err.message : String(err)}`);
            // Fall through to default implementation below
        }
    }
    return defaultInAppDispatch(input);
}
/**
 * Default dispatcher: saves a single `MJ: User Notifications` row. No email /
 * SMS delivery. Used when no custom handler is registered (e.g., on the client,
 * or before the server startup wires up the NotificationEngine handler).
 */
async function defaultInAppDispatch(input) {
    try {
        const grantor = await input.Provider.GetEntityObject('MJ: Users', input.ContextUser);
        await grantor.Load(input.GrantorUserID);
        const grantorName = grantor.Name || grantor.Email || 'Another user';
        const notification = await input.Provider.GetEntityObject('MJ: User Notifications', input.ContextUser);
        const resourceLabel = input.ResourceName
            ? `"${input.ResourceName}"`
            : `a ${input.ResourceTypeLabel.toLowerCase()}`;
        notification.UserID = input.GranteeUserID;
        notification.Title = input.Title ?? `${grantorName} shared ${resourceLabel} with you`;
        notification.Message =
            input.Message ??
                (input.ActionsSummary
                    ? `${grantorName} shared ${resourceLabel} with you (${input.ActionsSummary}).`
                    : `${grantorName} shared ${resourceLabel} with you.`);
        notification.Unread = true;
        const resolvedTypeId = await resolveResourceTypeId(input.ResourceTypeName, input.ContextUser);
        if (resolvedTypeId)
            notification.ResourceTypeID = resolvedTypeId;
        notification.ResourceRecordID = input.ResourceRecordID;
        notification.ResourceConfiguration = JSON.stringify({
            DomainName: input.ResourceTypeLabel,
            ...input.ExtraConfiguration,
        });
        const saved = await notification.Save();
        if (!saved) {
            LogError(`CreateShareNotification (default): save failed — ${notification.LatestResult?.CompleteMessage ?? 'unknown error'}`);
            return false;
        }
        return true;
    }
    catch (err) {
        LogError(`CreateShareNotification (default): ${err instanceof Error ? err.message : String(err)}`);
        return false;
    }
}
/**
 * Ensure the `ResourcePermissionEngine` is configured, then resolve
 * `MJ: Resource Type.Name → ID`. Returns null when the engine fails to load or
 * the type isn't in the catalog.
 */
async function resolveResourceTypeId(name, contextUser) {
    if (!name)
        return null;
    try {
        const engine = ResourcePermissionEngine.Instance;
        await engine.Config(false, contextUser);
        return engine.ResourceTypeIdByName(name);
    }
    catch (err) {
        LogError(`resolveResourceTypeId('${name}'): ${err instanceof Error ? err.message : String(err)}`);
        return null;
    }
}
//# sourceMappingURL=shareNotification.js.map