# A class used for automatically sending offers to customers based user behavior and data.
import random
from services.firebase.firestore_service import FirestoreService
from environment import Environment
from services.scheduling.scheduling_service import SchedulingService

class Autopilot:

    # define enums for events
    SIGNUP = "signup"
    ACCEPTANCE = "acceptance"
    CONTENT_VERIFICATION = "content_verification"
    
    SORTED_CONTENT_TYPES = ["ugc", "instagramStory", "instagramPost", "instagramReel"] # content types sorted from easiest to hardest

    @staticmethod
    def send_targeted_offer(phone_number, event, client_id=None, prev_offer_id=None, prev_multiplier=None):
        if phone_number is None:
            raise ValueError("phone_number must be provided")
        if event == Autopilot.SIGNUP:
            Autopilot.choose_offer_for_signup_trigger(phone_number, client_id)
        elif event == Autopilot.ACCEPTANCE:
            Autopilot.choose_offer_for_acceptance_trigger(phone_number, prev_offer_id, prev_multiplier)
        elif event == Autopilot.CONTENT_VERIFICATION:
            Autopilot.choose_offer_for_content_verification_trigger(phone_number)
        else:
            raise ValueError("Invalid event type")
        
    @staticmethod
    def choose_offer_for_signup_trigger(phone_number, client_id):
        if client_id is None:
            raise ValueError("client_id must be provided for signup event")

        # pull the user's acceptedOffers and ensure they haven't already accepted an offer from the client
        user_file = FirestoreService.get_user_file(phone_number).to_dict()
        accepted_offers = user_file["acceptedOffers"]
        for offer in accepted_offers:
            if offer["clientID"] == client_id and not offer.get("autoAdded"):
                print("Canceling signup trigger: user already accepted an offer from this client")
                return

        autopilot_file = FirestoreService.get_autopilot_file(client_id).to_dict()
        # Hit the person with a slightly better than intro offer (prefer the easiest content type)
        easiest_available_content_type = Autopilot.get_easiest_available_content_type(autopilot_file)
        
        targeted_offer_id = autopilot_file[easiest_available_content_type][Autopilot.randomly_pick_percent_or_cash()]
        multiplier = .80 # give a bit above the standard of .75 multiplier
        
        # send the offer to the user's wallet
        FirestoreService.send_offer_to_wallet(phone_number, targeted_offer_id, multiplier)
    
    # Send an offer with the same content type as the accepted offer, but with a slightly better reward (also try switching from cash to percent or vice versa)
    @staticmethod
    def choose_offer_for_acceptance_trigger(phone_number, prev_offer_id, prev_multiplier):
        if prev_offer_id is None:
            raise ValueError("prev_offer_id must be provided for acceptance event")
        if prev_multiplier is None:
            raise ValueError("prev_multiplier must be provided for acceptance event")

        # pull the user's acceptedOffers and ensure they haven't already been verified for the offer they accepted
        user_file = FirestoreService.get_user_file(phone_number).to_dict()
        accepted_offers = user_file["acceptedOffers"]
        for offer in accepted_offers:
            if offer["offerID"] == prev_offer_id and offer["finalValidation"]:
                print("Canceling acceptance trigger: offer already approved")
                return
        
        targeted_offer_id = prev_offer_id # use the same offer as last time (same content type, as they already expressed interest)
        multiplier = max(prev_multiplier + .05, 1) # boost the multiplier by a bit (but don't exceed 1)
        
        # send the offer to the user's wallet
        FirestoreService.send_offer_to_wallet(phone_number, targeted_offer_id, multiplier)

    @staticmethod
    def choose_offer_for_content_verification_trigger(phone_number, prev_offer_id, prev_multiplier):
        if prev_offer_id is None:
            raise ValueError("prev_offer_id must be provided for content_verification event")
        if prev_multiplier is None:
            raise ValueError("prev_multiplier must be provided for content_verification event")
            
        targeted_offer_id = prev_offer_id # use the same offer as last time (same content type, as they already expressed interest)
        multiplier = prev_multiplier # keep the same multiplier

        # send the offer to the user's wallet
        FirestoreService.send_offer_to_wallet(phone_number, targeted_offer_id, multiplier)
        

    @staticmethod
    def get_easiest_available_content_type(autopilot_file):
        for content_type in Autopilot.SORTED_CONTENT_TYPES:
            if content_type in autopilot_file and autopilot_file[content_type]["isActive"]:
                return content_type
        return None

    # randomly choose either the string "offerID$" or "offerID%"
    @staticmethod
    def randomly_pick_percent_or_cash():
        return "offerID$" if random.random() > 0.5 else "offerID%"
    
        
