import { Config, RequestData, Type } from '@ko-fi/types';

/**
 * Expects the json string of the 'data' field.
 * Returns a http status code.
 */
export const kofiHandler = async <TConfig>(data: string, config: Config<TConfig>, ctx: TConfig) => {
    let parsed: RequestData;

    // Parse JSON
    try {
        parsed = JSON.parse(data);
    } catch (_) {
        await config.onError?.(Error.JSON, ctx);
        return 400;
    }

    // Check verification token
    if (config.verificationToken && parsed.verification_token !== config.verificationToken) {
        await config.onError?.(Error.VERIFICATION_TOKEN, ctx);
        return 401;
    }

    // Call data handler based on the data type
    try {
        await config.onData?.(parsed, ctx);

        switch (parsed.type) {
            case Type.Commission:
                await config.onCommission?.(parsed, ctx);
                break;
            case Type.Donation:
                await config.onDonation?.(parsed, ctx);
                break;
            case Type.ShopOrder:
                await config.onShopOrder?.(parsed, ctx);
                break;
            case Type.Subscription:
                await config.onSubscription?.(parsed, ctx);
                break;
        }
    } catch (_) {
        await config.onError?.(Error.DATA_HANDLER, ctx);
        return 400;
    }

    return 200;
}

export enum Error {
    VERIFICATION_TOKEN = 'Ko-fi invalid verification token',
    JSON = 'Ko-fi invalid JSON object',
    DATA_HANDLER = 'Ko-fi data handler failed',
}
