import { Context, NextFunction } from "grammy";
/**
 * This library is a middleware for the grammy bot library. It allows you to create a referral system for your bot.
 * Simple to use and easy to understand.
 * Straight to the point.
 */


/**
 * The main function that creates the middleware for the referral system
 * @param {object} options The options for the referral system
 * @param {integer} options.referrerBonus The amount of money the referrer gets when someone uses their referral link
 * @param {integer} options.referreeBonus The amount of money the referree gets when they use a referral link
 * @param {integer} options.startupBonus The amount of money the user gets when they start the bot
 * @param {function} options.userExists A function that checks if a user exists in the database
 * @param {function} options.addBalance A function that adds balance to a user
 * @param {function} options.onReferral A function that is called when a user uses a referral link
 * @param {function} options.onStartUp A function that is called when a user starts the bot
 * 
 * @returns {function} The middleware function that can be used in the bot
 */
function refer(options: {
    referrerBonus: number,
    referreeBonus: number,
    startupBonus: number,
    userExists: (id: number | undefined) => Promise<boolean> | boolean,
    addBalance: (id: number | undefined, amount: number) => Promise<void> | void,
    onReferral: (referrer: number, referree: Context) => Promise<void> | void,
    onStartUp: (ctx: Context) => Promise<void> | void,
} = {
    referrerBonus: 0,
    referreeBonus: 0,
    startupBonus: 0,
    userExists: () => false,
    addBalance: () => {},
    onReferral: () => {},
    onStartUp: () => {},
}) {
    const middlewareFn = async (ctx: Context, next: NextFunction) => {
        if (!ctx.hasChatType("private")) return await next()
        if (!ctx.hasCommand("start")) return await next()
        if (await options.userExists(ctx.from?.id)) {
            await next()
            return;
        } else {
            await options.onStartUp(ctx);
        }

        const referrer = parseInt(ctx.msg?.text?.split(" ")[1] || "");

        if (isNaN(referrer) || !await options.userExists(referrer)) {
            await options.addBalance(ctx.from?.id, options.startupBonus);
        } else {
            await options.addBalance(referrer, options.referrerBonus);
            await options.onReferral(referrer, ctx);
            await options.addBalance(referrer, options.referreeBonus);
        }
        await next()

    }
    return middlewareFn;
}

export { refer as default };