import { TCString } from "@iabtechlabtcf/core";

import { findUsedDeclarations } from "./findUsedDeclarations.js";

import type { ClickableButtonsNamed } from "../types/types.js";
import type { TCModel } from "@iabtechlabtcf/core";

/**
 * When saving via an action, forward the action to the TCF model automatically. E.g. "Accept all"
 * should activate all, and "Accept only essentials" should only accept essentials + legitimate interests.
 *
 * Modifies also `consentScreen` in TCF string; currently not necessary, but just to be sure:
 *
 * - 0 = First view
 * - 1 = Second view
 * - 10 = Shortcode revoke link
 * - 20 = Content Blocker
 *
 * You need to call the returned function to get the encoded TC string as encoding is very expensive.
 */
function prepareTcfString<ButtonClicked extends ClickableButtonsNamed | "initial">(
    model: TCModel,
    buttonClicked: ButtonClicked,
): ButtonClicked extends "initial" ? void : () => string {
    const { gvl } = model;
    const mapId = ({ id }) => id;

    // Modify consents depending on clicked button
    switch (buttonClicked) {
        case "main_all":
        case "ind_all":
        case "implicit_all":
            // model.setAll(); // not usable as we do only consent to used declarations
            model.setAllVendorConsents();
            model.setAllVendorLegitimateInterests();
            model.purposeLegitimateInterests.set(findUsedDeclarations("purposes", gvl, model, "legInt").map(mapId));
            model.purposeConsents.set(findUsedDeclarations("purposes", gvl, model, "consent").map(mapId));
            model.specialFeatureOptins.set(findUsedDeclarations("specialFeatures", gvl, model, "consent").map(mapId));
            break;
        case "initial":
        case "main_essential":
        case "implicit_essential":
        case "ind_essential":
        case "ind_close_icon":
        case "main_close_icon":
        case "shortcode_revoke":
            model.unsetAll();
            model.setAllVendorLegitimateInterests();
            model.purposeLegitimateInterests.set(findUsedDeclarations("purposes", gvl, model, "legInt").map(mapId));
            break;
        case "none":
            model.unsetAll();
            break;
        default:
            break;
    }

    // Modify `consentScreen` in TCF string; currently not necessary, but just to be sure
    if (buttonClicked.startsWith("main_")) {
        model.consentScreen = 0;
    } else if (buttonClicked.startsWith("ind_")) {
        model.consentScreen = 1;
    } else if (buttonClicked === "shortcode_revoke") {
        model.consentScreen = 10;
    } else if (buttonClicked === "unblock") {
        model.consentScreen = 20;
    }

    return (buttonClicked === "initial" ? undefined : () => TCString.encode(model)) as any;
}

export { prepareTcfString };
