package ai.causalfoundry.rnsdk.loyalty;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import ai.causalfoundry.android.sdk.loyalty.builders.CfLogLevelEvent;
import ai.causalfoundry.android.sdk.loyalty.builders.CfLogMilestoneEvent;
import ai.causalfoundry.android.sdk.loyalty.builders.CfLogPromoEvent;
import ai.causalfoundry.android.sdk.loyalty.builders.CfLogRewardEvent;
import ai.causalfoundry.android.sdk.loyalty.builders.CfLogSurveyEvent;
import ai.causalfoundry.android.sdk.loyalty.catalog.CfLoyaltyCatalog;

public class CfLogLoyalty extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;

    public CfLogLoyalty(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return "CfLogLoyalty";
    }

    /**
     * logLevelEvent is to log list events for loyalty modules. This can be used when opening a
     * viewing a challenge or reward or completing a challenge
     *
     * @param previous_level    is required to set the previous score/level number for the user.
     * @param new_level         is required to set the new score/level number for the user. This
     *                          can be from any source, e-learning or e-commerce, or even social.
     * @param moduleId          is for specific use-case when the update of level is from e-learning.
     *                          In such case module id is required, otherwise, you can pass null for
     *                          this as well.
     * @param meta              is to send any other data you want to send with the ingest, can be null.
     * @param updateImmediately is default set to true, you can use that to log events when the app
     *                          goes in the background or closed.
     */
    @ReactMethod
    public void logLevelEvent(int previous_level, int new_level, String moduleId,
                              String meta, Boolean updateImmediately) {
        new CfLogLevelEvent.Builder()
                .setPreviousLevel(previous_level).setNewLevel(new_level)
                .setModuleId(moduleId)
                .setMeta(meta).updateImmediately(updateImmediately)
                .build();
    }

    /**
     * logMilestoneEvent is to log list events for loyalty modules. This can be used when opening
     * a viewing a challenge or reward or completing a challenge
     *
     * @param milestoneId       is required for logging the milestone user achieved. The is should
     *                          be in a string format and must be per the catalog provided.
     * @param action            is required to set the Action type for the Milestone event. SDK
     *                          provides enum classes to support available log types. 1 main is
     *                          achieved. SDK provides 2 approaches to log this event, one being
     *                          enum type and the other is string type.
     * @param meta              is to send any other data you want to send with the ingest, can be null.
     * @param updateImmediately is default set to true, you can use that to log events when the app
     *                          goes in the background or closed.
     */
    @ReactMethod
    public void logMilestoneEvent(String milestoneId, String action,
                                  String meta, Boolean updateImmediately) {
        new CfLogMilestoneEvent.Builder()
                .setMilestoneId(milestoneId).setAction(action)
                .setMeta(meta).updateImmediately(updateImmediately)
                .build();
    }

    /**
     * logPromoEvent is to log the events associated of the promo lists and promo items and when they are clicked on.
     *
     * @param promoId           is required to set the Id of the promo
     * @param action            is required to set the action for the promo
     * @param title             is required to set the title of the promo (if any)
     * @param type              is required to set the type of the promo
     * @param promoItemsList    to add the whole list to the log at once, the format should be
     *                          ArrayList<PromoItemObject> to log the event successfully.
     * @param meta              is to send any other data you want to send with the ingest, can be null.
     * @param updateImmediately is default set to true, you can use that to log events when the app
     *                          goes in the background or closed.
     */
    @ReactMethod
    public void logPromoEvent(String promoId, String action, String title,
                              String type, String promoItemsList,
                              String meta, Boolean updateImmediately) {
        new CfLogPromoEvent.Builder()
                .setPromoId(promoId)
                .setPromoAction(action)
                .setPromoType(type)
                .setPromoTitle(title)
                .addItemList(promoItemsList)
                .setMeta(meta).updateImmediately(updateImmediately)
                .build();
    }


    /**
     * logSurveyEvent is to log the user viewing, attempting the survey.
     *
     * @param action            is required to set the Action type for the Survey Action.
     * @param surveyObject      is for the providing item info details about survey. The object
     *                          should be based on the SurveyObject or a string that can be
     *                          converted to the object with proper param names.
     * @param responseList      is for the providing responses item details about survey. The
     *                          object should be based on the SurveyResponseItem List or a
     *                          string list that can be converted to the object with proper param names.
     * @param meta              is to send any other data you want to send with the ingest, can be null.
     * @param updateImmediately is default set to true, you can use that to log events when the app
     *                          goes in the background or closed.
     */
    @ReactMethod
    public void logSurveyEvent(String action, String surveyObject, String responseList,
                               String meta, Boolean updateImmediately) {
        new CfLogSurveyEvent.Builder()
                .setAction(action)
                .setSurveyObject(surveyObject)
                .setResponseList(responseList)
                .setMeta(meta).updateImmediately(updateImmediately)
                .build();
    }


    /**
     * logRewardEvent is to log the reward related events for user, which includes viewing,
     * redeeming, adding.
     *
     * @param rewardId          is for the providing Id for the reward event. Can be userId if the
     *                          reward is not redeemed individually.
     * @param action            is required to set the Action type for the Reward Action.
     * @param acc_points        is for the providing achieved points in case of add reward event.
     * @param total_points      logs the total points achieved so far by the user.
     * @param redeemObject      is for the providing details about reward redeeming. The object
     *                          should be based on the RedeemObject or a string that can be
     *                          converted to the object with proper param names.
     * @param meta              is to send any other data you want to send with the ingest, can be null.
     * @param updateImmediately is default set to true, you can use that to log events when the app
     *                          goes in the background or closed.
     */
    @ReactMethod
    public void logRewardEvent(String rewardId, String action, float acc_points,
                               float total_points, String redeemObject,
                               String meta, Boolean updateImmediately) {
        CfLogRewardEvent.Builder cfLogRewardEvent = new CfLogRewardEvent.Builder()
                .setRewardId(rewardId)
                .setAction(action)
                .setAccumulatedPoints(acc_points)
                .setTotalPoints(total_points)
                .setMeta(meta).updateImmediately(updateImmediately);

        if (redeemObject != null) {
            cfLogRewardEvent.setRedeemObject(redeemObject);
        }

        cfLogRewardEvent.build();
    }


    /**
     * Survey catalog values
     *
     * @param surveyId        Survey id in the system
     * @param surveyItemModel Props for the Survey item
     */
    @ReactMethod
    public void updateSurveyCatalog(String surveyId, String surveyItemModel) {

        CfLoyaltyCatalog.INSTANCE.updateSurveyCatalog(surveyId, surveyItemModel);
    }

    /**
     * Reward catalog values
     *
     * @param rewardId        Reward id in the system
     * @param rewardItemModel Props for the Reward item
     */
    @ReactMethod
    public void updateRewardCatalog(String rewardId, String rewardItemModel) {

        CfLoyaltyCatalog.INSTANCE.updateRewardCatalog(rewardId, rewardItemModel);
    }

}