from asyncio import log
from rest_framework.decorators import api_view
from django.http import JsonResponse
import os,sys
import requests
import datetime
import inspect
from datetime import timezone
import sqlite3
import pandas as pd
from collections import defaultdict
from requests.auth import HTTPBasicAuth
from django.http import JsonResponse
sys.path.append(os.path.join(os.path.dirname(__file__)))
import LogUtils
logger = LogUtils.getRootLogger()

logger.info("Starting the PPP Automation script")

# LOG_FILE = "/var/www/html/PPP_Automation/ppp_app/log/ppp_automation-log.log"

# def custom_log(level, message):
#     # Ensure directory exists
#     log_dir = os.path.dirname(LOG_FILE)
#     os.makedirs(log_dir, exist_ok=True)

#     # Get caller frame info
#     frame = inspect.currentframe().f_back
#     filename = os.path.basename(frame.f_code.co_filename)
#     lineno = frame.f_lineno
#     module = frame.f_globals.get("__name__", "unknown")

#     # Format timestamp
#     timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

#     # Format log line
#     log_line = f"{timestamp} - {module} - {level.upper():>8s} - [{filename:25s} : {lineno:3d}] - {message}\n"

#     # Write to file
#     with open(LOG_FILE, "a") as f:
#         f.write(log_line)

    

###########################################
def ce_request_validation_api(eventregistrationid):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)

    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    try:

        trit_cerequests_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_cerequests?$filter=_trit_eventregistrationid_value eq '{eventregistrationid}'"
        
        event_req=requests.get(trit_cerequests_api_url,headers=headers)
        
        dt = event_req.json().get("value")
        
        df = pd.DataFrame(dt)
        logger.info(f"ce request count {len(df)} for event registration id {eventregistrationid}")
        
        if len(df)>0:
            CE_REQ_Val = True
        elif len(df)<=0:
            CE_REQ_Val = False
        else:
            CE_REQ_Val = "Error in validation of CE Request"
        
        return CE_REQ_Val
    except Exception as e:
        logger.error(f"Error at ce_request_validation_api function and the error is: {e}")
        


####################################################################

def event_name_uuid(eventcode):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    try:

        event_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/msevtmgt_events?$filter=trit_eventcode eq '{eventcode}'"


        event_req=requests.get(event_api_url,headers=headers)

        res=event_req.json()
        
        event_id = res.get("value")[0].get("msevtmgt_eventid")
        
        msevtmgt_eventregistration_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/msevtmgt_eventregistrations?$filter=_msevtmgt_eventid_value eq '{event_id}'"
        
        msevtmgt_eventregistration_req=requests.get(msevtmgt_eventregistration_api_url,headers=headers)
        

        msevtmgt_eventregistration_res = msevtmgt_eventregistration_req.json()
        
        res1 = msevtmgt_eventregistration_res.get("value")
        

        er_list = []
        for er in res1:
            er_list.append(er.get("msevtmgt_eventregistrationid"))
        logger.info(f"event registration ids list {er_list}")
        return er_list    
    
    except Exception as e:
        logger.error(f"Error at event_name_uuid function and the error is: {e}")
        
    
####################################################################

def check_eventcode_exist(event_code):
    try:
        conn = sqlite3.connect('/var/www/html/PPP_Automation/db.sqlite3')
        cursor = conn.cursor()
        logger.info(f"Connected to SQLite database at /var/www/html/PPP_Automation/db.sqlite3")
    except Exception as e:
         logger.error(f"Error at connection sqlitedb and the error is: {e}")   

    try:     
        cursor.execute('''
        SELECT * FROM ppp_events
        WHERE qs_ppp_event_code = ?
        ''', (event_code,))

        record = cursor.fetchone()

    except Exception as e:
        logger.error(f"Error at retrieving event code and the error is: {e}")        
    
    try:
        if record:
            utc_now = datetime.datetime.now(timezone.utc)
            cursor.execute('''
            UPDATE ppp_events
            SET qs_ppp_last_modified_date = ?
            WHERE qs_ppp_event_code = ?
            ''', (utc_now, event_code))
            conn.commit()
            conn.close()
            return { "statusCode": 200,
            "message": "Event is already Trigged for PPP",
            "isEventTriggedAlready" : True,}
        
        else:
            utc_now = datetime.datetime.now(timezone.utc)
            cursor.execute('''
            INSERT INTO ppp_events (qs_ppp_event_code, qs_ppp_created_date, qs_ppp_last_modified_date)
            VALUES (?, ?, ?)
            ''', (event_code, utc_now, utc_now))
            conn.commit()
            conn.close()
            return {
            "statusCode": 200,
            "message": "Event is new to PPP",
            "isEventTriggedAlready" : False,
            }
    except Exception as e:
        logger.error(f"Error at retrieving updating the event code and the error is: {e}")
###########################################

@api_view(['GET'])
def validateapi(request):
    if request.method == "GET":
        logger.info("Received GET request at validateapi")
        eventcode = request.GET.get("eventcode")
        logger.info(f"The Event code is: {eventcode}")

        try:
            if not eventcode:
                return JsonResponse(
                    {
                        "statusCode": 400,
                        "message": "Missing ?eventcode= in query string",
                        "isEventTriggedAlready": None,
                    },
                    status=400,
                )
            
            try:
                res = check_eventcode_exist(eventcode)
            except Exception as e:
                logger.error(f"check_eventcode_exist failed: {e}")
                return JsonResponse({"statusCode": 500, "message": "Internal error at event code check"}, status=500)
            logger.info(f"Response for Eventcode {eventcode} ",res)
            
            return JsonResponse(res, safe=False)
    
            
        except Exception as e:
            logger.error(f"Error at validate api and the error is: {e}")

            return JsonResponse(
                {
                    "statusCode": 500,
                    "message": "Internal server error",
                    "isEventTriggedAlready": None,
                },
                status=500
            )

        finally:
            if eventcode:
                try:
                    url = "https://corporateallibot.scic.com/PPP-Automation"
                    payload = {
                        "eventcode": eventcode
                    }
                    headers = {
                        "Content-Type": "application/json"
                    }
                    post_response = requests.post(url, json=payload, headers=headers)
                    logger.info(f"POST to {url} completed with status {post_response.status_code} and post response {post_response}")
                    logger.info(f"POST to {url} completed with status {post_response.status_code}")
                    
                except Exception as e:
                    logger.error(f"Failed to POST to {url}: {e}")
        
        
        

###########################################

base_url = 'https://scicdev.crm.dynamics.com'

# Azure AD Application Client ID and Secret
client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'

def get_token(client_id, client_secret, tenant_id):
    token_url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/token'
    
    payload = {
        'grant_type': 'client_credentials',
        'client_id': client_id,
        'client_secret': client_secret,
        'resource': base_url,
    }

    
    response = requests.post(token_url, data=payload)
    if response.status_code == 200:
        logger.info("Token retrieved successfully")
        return response.json().get('access_token')
    else:
        logger.error(f"Failed to retrieve token: {response.text}")
        raise Exception(f"Failed to retrieve token: {response.text}")
    
####################################################################

def fetch_instructor_approval_id(product_id, state_id, delivery_method, license_type):

    """
    Fetch the instructor approval ID based on provided parameters.

    Parameters:
        product_id (str): The unique identifier for the product.
        state_id (str): The unique identifier for the state.
        delivery_method (int): The code representing the delivery method.
        license_type (int): The code representing the type of license.

    Returns:
        str or None: The instructor approval ID if found, otherwise None.
    """
    try:
    # Base URL for the API endpoint
        url = "https://webapi.scic.com/OrganizerPython/api/PythonAPI/GetInstructorapprovalId"

        # Parameters to be sent in the GET request
        params = {
            "ProductId": product_id,
            "StateId": state_id,
            "DeliveryMethod": delivery_method,
            "TypeofLicense": license_type,
        }

        
        logger.info(f"Fetching instructor approval ID with parameters: {params}")

        # Send a GET request to the API with the specified parameters
        response = requests.get(url, params=params)

        # Extract and return the 'response' field from the JSON response, or None if not present
        return response.json().get("response")
    except Exception as e:
        logger.error(f"Error fetching instructor approval ID: {e}")
        

####################################################################

def ce_request_odata(new_record):
    """
    Creates a new record in the Dynamics 365 CRM system using the OData API.

    Parameters:
        new_record (dict): The record data to be created in the CRM.

    Returns:
        dict: A dictionary containing the status of the operation.
    """
    # OAuth client details
    client_id = "6e5989aa-4fd1-4015-8648-8f75609d607b"
    client_secret = "mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS"
    tenant_id = "95f69e7d-1811-4ab9-9b5a-eba95d3eba9b"
    base_url = "https://scicdev.crm.dynamics.com"  

    try:
    # Obtain an access token
        token = get_token(client_id, client_secret, tenant_id)

    except Exception as e:
        return {"status": f"Failed to get token at function ce_request_odata and the error is - {e}"}        

    
    
    # Set headers for the API request
    headers = {
        "Authorization": "Bearer " + token,  # Include the access token for authentication
        "Prefer": "odata.maxpagesize=5000",  # Set a maximum page size preference
        "OData-MaxVersion": "4.0",          # Specify the maximum OData version
        "OData-Version": "4.0",             # Specify the OData version
    }
    
    # Construct the API endpoint URL
    ce_request_api_url = base_url + "/api/data/v9.2/trit_cerequests"
    
    # Initialize the response dictionary
    Response = {"status": "null"}
    
    try:
        # Send a POST request to create a new record in the CRM
        response = requests.post(ce_request_api_url, headers=headers, json=new_record)
        
        # Check the response status code and update the response dictionary accordingly
        if response.status_code in [200, 201]:
            logger.info("Record created successfully with status code at unction ce_request_odata: %s", response.status_code)
            Response = {"status": "Success"}
        elif response.status_code == 204:
            logger.info("No content to update at function ce_request_odata")
            Response = {"status": "Success with no changes"}
        else:
            logger.error("Failed to create record with status code %s and response: %s", response.status_code, response.text)
            Response = {
                "status": f"Failed to create record with status code {response.status_code} and response: {response.text}"
            }
    
    # Catch and handle any exceptions during the process
    except Exception as e:
        logger.error("Error at ce_request_odata function: %s", e)
        Response = {"status": f"Failed at ce_request_odata function - {e}"}

    # Return the final response
    return Response
  

####################################################################

def pc(product_id,state_id):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }
    try:

        state_approval_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_instructorapprovals?$filter=_trit_state_value eq {state_id}"

        # state_approval_api_url="https://scic.crm.dynamics.com/api/data/v9.1/trit_instructorapprovals?$top=1"

        state_approval_req=requests.get(state_approval_api_url,headers=headers)

        res=state_approval_req.json()

        data=res["value"]

        state_approval_table=pd.DataFrame(data)

        state_approval=state_approval_table[state_approval_table["_trit_product_value"]==product_id]

        stateapproval_id_lists=[]
        for _,rows in state_approval.iterrows():
            trit_name=rows["trit_name"]
            state_approvalid=rows["trit_instructorapprovalid"]
            if trit_name and (trit_name.endswith("PC") or trit_name.endswith("(PC)") or trit_name.endswith("(PC/ETH)") or trit_name.endswith("(PC/LH/ETH)") or trit_name.endswith("(PC/LH)") or trit_name.endswith("(LH/PC)") or trit_name.endswith("PC/LH") or trit_name.endswith("LH/PC") or trit_name.endswith("(LH/PC/ETH)") or trit_name.endswith("(ETH/PC/LH)") or trit_name.endswith("LH/PC/ETH") or trit_name.endswith("ETH/PC/LH") or trit_name.endswith("P/C & L/H") or trit_name.endswith("(P/C & L/H)") or trit_name.endswith("(PC/LAH/ETH)") or trit_name.endswith("PC/LAH/ETH") or trit_name.endswith("(P/C)") or trit_name.endswith("P/C")):
                dicts_of_state_approve={ "trit_name":trit_name,
                                    "Id":state_approvalid
                    }
                stateapproval_id_lists.append(dicts_of_state_approve)
        stateapproval_id = stateapproval_id_lists
        logger.info(f"State approval ID for product {product_id} in state {state_id} pc 1: {stateapproval_id}")
        stateapproval_id = stateapproval_id
        logger.info(f"State approval ID for product {product_id} in state {state_id} pc 2: {stateapproval_id}")
        
        return stateapproval_id
    except Exception as e:
        logger.error("Error at function pc: %s", e)
        
########################################################################################################

def lh(product_id,state_id):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    try: 
        state_approval_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_instructorapprovals?$filter=_trit_state_value eq {state_id}"

        state_approval_req=requests.get(state_approval_api_url,headers=headers)

        res=state_approval_req.json()

        data=res["value"]

        state_approval_table=pd.DataFrame(data)

        state_approval=state_approval_table[state_approval_table["_trit_product_value"]==product_id]

        stateapproval_id_lists=[]
        for _,rows in state_approval.iterrows():
            trit_name=rows["trit_name"]
            state_approvalid=rows["trit_instructorapprovalid"]
            if trit_name and (trit_name.endswith("LH") or trit_name.endswith("(L/H)") or trit_name.endswith("(LH/ETH)") or trit_name.endswith("(PC/LH/ETH)") or trit_name.endswith("(PC/LH)") or trit_name.endswith("(LH/LAW/REG/ETH)") or trit_name.endswith("LH (Webinar)") or trit_name.endswith("(LH/PC)") or trit_name.endswith("PC/LH") or trit_name.endswith("LH/PC") or trit_name.endswith("(LH/PC/ETH)") or trit_name.endswith("(ETH/PC/LH)") or trit_name.endswith("LH/PC/ETH") or trit_name.endswith("ETH/PC/LH") or trit_name.endswith("P/C & L/H") or trit_name.endswith("(P/C & L/H)") or trit_name.endswith("(L/H)") or trit_name.endswith("L/H")):
                dicts_of_state_approve={ "trit_name":trit_name,
                                    "Id":state_approvalid
                    }
                stateapproval_id_lists.append(dicts_of_state_approve)
        stateapproval_id = stateapproval_id_lists

        logger.info(f"State approval ID for product {product_id} in state {state_id} LH function: {stateapproval_id}")
        return stateapproval_id
    except Exception as e:
        logger.error("Error at function lh: %s", e)
        


#################################################################### 

def get_state_approval_guid(product, state, delivery_mechanism, license_type):
    
        
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }
        
    base_url = "https://scicdev.crm.dynamics.com"
    
    try:
        statefiling_api_url = (
            f"{base_url}/api/data/v9.1/trit_statefilings?"
            f"$filter=_trit_product_value eq {product} and " 
            f"_trit_state_value eq {state} and "
            f"trit_deliverymechanisms eq {delivery_mechanism}"
            f"&$select=trit_statefilingid"
        )

        token = get_token(client_id, client_secret, tenant_id)


        headers = {
            'Authorization': 'Bearer ' + token,
            'Prefer': 'odata.maxpagesize=5000',
            'OData-MaxVersion': '4.0',
            'OData-Version': '4.0'
        }
        
        state_filing_req=requests.get(statefiling_api_url,headers=headers)
        state_filing_json = state_filing_req.json().get("value")
    
    except Exception as e:
        logger.error(f"Error at get_state_approval_guid function while fetching state filing data1: {e}")
        
    
    try:
        state_filing_data = []
        for i in state_filing_json:
            a = i.get("trit_statefilingid")
            state_filing_data.append(a)
        logger.info(f"State filing data for product {product}, state {state}, delivery mechanism {delivery_mechanism}: {state_filing_data}")

    except Exception as e:
        logger.error(f"Error at get_state_approval_guid function while processing state filing data2: {e}")
        return None

    try:
        state_approval_data =[]
        for j in state_filing_data:    
        
            state_approval_api_url = (
                f"{base_url}/api/data/v9.1/trit_instructorapprovals?"
                f"$filter=_trit_statefiling_value eq '{j}' and " 
                f"trit_typeoflicense eq {license_type}" 
                f"&$select=trit_instructorapprovalid"
            )
            
            
            state_approval_req=requests.get(state_approval_api_url,headers=headers)
            state_approval_json = state_approval_req.json().get("value")
            for k in state_approval_json:
                b = k.get("trit_instructorapprovalid")
                state_approval_data.append(b)
            
            
        logger.info(f"State approval data for product {product}, state {state}, delivery mechanism {delivery_mechanism}, license type {license_type}: {state_approval_data}")
        return state_approval_data  # Return the final GUID
    except Exception as e:
        logger.error(f"Error at get_state_approval_guid function while fetching state approval data3: {e}")
        
####################################################################

# def state_approval(product_id,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid):
        
#     try:
#         stateapproval_id = None

        
#         lic_LOH = trit_license_trit_lineofauthority
#         logger.info(f"lic LOH check - {lic_LOH}")

#         if lic_LOH is not None:
#             logger.info("lic LOH is not None")
#             # pc and lh functions here
#             if lic_LOH == 314310000 or 314310001 or 314310002:
#                 stateapproval_id = get_state_approval_guid(product_id, trit_license_trit_stateid_value, delivery_mechanism, type_of_license)
#                 return stateapproval_id

#             else:
#                 logger.info("lic LOH is not None but does not match any known values")
#                 stateapproval_id = "Null"
#                 return stateapproval_id
            
#         elif lic_LOH is None or lic_LOH == 314310003:
#             logger.info(f"lic LOH is {lic_LOH}")
#             logger.info("lic LOH is None or 314310003")
#             type_of_license = 314310001

#             try:
#                 logger.info("step 1 pass")
#                 stateapproval_id = get_state_approval_guid(product_id, trit_license_trit_stateid_value, delivery_mechanism, type_of_license)
#                 logger.info("step 2 pass")
#                 logger.info("these are the state approval ids",stateapproval_id)
#             except Exception as e:
#                 logger.info(f"state approv error {e}")
#             return stateapproval_id
        
#         else:
#             logger.info("error value type in lic_LOH variable")
#         logger.info(f'state_approval_id - {stateapproval_id}')
#         return stateapproval_id

#     except Exception as e:
#         logger.info(f"Error at function state_approval function and the error is {e}")


def state_approval(product_id,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid):
        
    try:
        stateapproval_id = None

        
        lic_LOH = trit_license_trit_lineofauthority
        logger.info(f"lic LOH check - {lic_LOH}")

        if lic_LOH is not None:
            logger.info("lic LOH is not None")
            # pc and lh functions here
            if lic_LOH in [314310000, 314310001, 314310002]:
                    license_priority = []

                    # Set license type priorities based on input
                    if type_of_license == 314310000:
                        license_priority = [314310000, 314310002]
                    elif type_of_license == 314310001:
                        license_priority = [314310001, 314310002]
                    elif type_of_license == 314310002:
                        license_priority = [314310001, 314310002]
                    else:  
                        license_priority = [314310001, 314310002]

                    for license_type in license_priority:
                        stateapproval_id = get_state_approval_guid(product_id, trit_license_trit_stateid_value, delivery_mechanism, license_type)
                        if stateapproval_id:
                            return stateapproval_id

            else:
                logger.info("lic LOH is not None but does not match any known values")
                stateapproval_id = "Null"
                return stateapproval_id
            
        elif lic_LOH is None or lic_LOH == 314310003:
            logger.info(f"lic LOH is {lic_LOH}")
            logger.info("lic LOH is None or 314310003")
            type_of_license = 314310001

            try:
                logger.info("step 1 pass")
                stateapproval_id = get_state_approval_guid(product_id, trit_license_trit_stateid_value, delivery_mechanism, type_of_license)
                logger.info("step 2 pass")
                logger.info("these are the state approval ids",stateapproval_id)
            except Exception as e:
                logger.info(f"state approv error {e}")
            return stateapproval_id
        
        else:
            logger.info("error value type in lic_LOH variable")
        logger.info(f'state_approval_id - {stateapproval_id}')
        return stateapproval_id

    except Exception as e:
        logger.info(f"Error at function state_approval function and the error is {e}")



####################################################################
def check_poll_requirements(data):
    # Ensure there's valid data
    if data.empty or not any(data["trit_answered"]):
        logger.info("No valid trit_name found with trit_answered as True.")
        return "no"
    
    # Structure to hold the polls by product and hour
    polls_by_product_hour = defaultdict(lambda: defaultdict(set))

    # Process the input data
    for _, row in data.iterrows():
        trit_name = row["trit_name"]
        
        # Check if trit_name contains a ':' to split
        if ':' not in trit_name:
            logger.info(f"Invalid format, missing colon: {trit_name}")
            continue

        try:
            # Split the trit_name to extract the product and poll number
            product_hour_part = trit_name.split(':', 1)[0]  # Take the part before the ':'
            parts = product_hour_part.rsplit('-', 2)  # Split from the right to get the last two parts

            if len(parts) != 3:
                logger.info(f"Skipping invalid format: {trit_name}")
                continue

            product_hour, poll_num = parts[:-1], parts[-1]  # Get all but the last part for product
            product = '-'.join(product_hour)  # Join to get the product base
            
            # Calculate the hour based on the poll number
            hour = (int(poll_num) - 1) // 3 + 1  # Calculate the hour based on the poll number
            
            # Add the poll to the set to avoid duplicates
            polls_by_product_hour[product][hour].add(trit_name)

        except Exception as e:
            logger.info(f"Error processing {trit_name}: {e}")

    # Required polls per hour
    required_polls_per_hour = 2  # Change this to your requirement
    product_poll_summary = defaultdict(lambda: defaultdict(int))
    
    # Count total polls for each product and hour
    for product, hours in polls_by_product_hour.items():
        for hour in range(1, 5):  # Assuming there are 4 hours to check
            total_poll_count = len(hours[hour])
            product_poll_summary[product][hour] = total_poll_count

    # Create the summary DataFrame
    summary_records = []
    for product, hour_data in product_poll_summary.items():
        for hour in range(1, 5):  # Check for each hour
            total_polls = hour_data[hour]
            summary_records.append({
                "Product": product,
                "Hour": hour,
                "Required Polls": required_polls_per_hour,
                "Total Polls": total_polls,
                "Status": "Sufficient" if total_polls >= required_polls_per_hour else "Insufficient"
            })

    summary_df = pd.DataFrame(summary_records)

    # Check for insufficient polls
    if 'Status' in summary_df.columns:
        insufficient_polls = summary_df[summary_df["Status"] == "Insufficient"]
        if not insufficient_polls.empty:
            logger.info("\nProducts with insufficient polls:")
            logger.info("#####Insufficient data starts#####")
            logger.info(insufficient_polls)
            logger.info("#####Insufficient data ends#####")
            return "no"

    logger.info("This product have sufficient polls for every hour.")
    return "yes"

####################################################################


def ao_am_states(trit_product,trit_license_trit_stateid_value):
    ao=pd.read_excel("/var/www/html/PPP_Automation/ppp_app/AO and AM state and statecode.xlsx",sheet_name="AO")
    am=pd.read_excel("/var/www/html/PPP_Automation/ppp_app/AO and AM state and statecode.xlsx",sheet_name="AM")   
    cc=pd.read_excel("/var/www/html/PPP_Automation/ppp_app/AO and AM state and statecode.xlsx",sheet_name="CC")
    
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    product_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/products?$filter=productid eq {trit_product}&$select=name"
    
    
    response=requests.get(product_api_url,headers=headers)
    
    res=response.json()
    
    data=res['value']
    
    product=pd.DataFrame(data)
    logger.info(f"ao am states product table - {product}")
    AO_AM_CC = product["name"][0]
    logger.info(f"AO,AM&CC - {AO_AM_CC}")
    no_of_cerequest = 1
    try:
        if product["name"][0] == "AO":
            logger.info("This event number is in AO states")
            for index,row in ao.iterrows():
                if row["stateid"]== trit_license_trit_stateid_value:
                    trit_name=row["trit_name"]
                    logger.info(f"AO state name is {trit_name}")
                    no_of_cerequest=row["CE request"]
                    break
                
        elif product["name"][0]=="AM":
            logger.info("This event is in AM states")
            for index,row in am.iterrows():
                if row["stateid"]== trit_license_trit_stateid_value:
                    trit_name=row["trit_name"]
                    logger.info(f"AM state name is {trit_name}")
                    no_of_cerequest=row["CE request"]
                    break

        elif product["name"][0]=="CC":
            logger.info("This event is in CC states")
            for index,row in cc.iterrows():
                if row["stateid"]== trit_license_trit_stateid_value:
                    trit_name=row["trit_name"]
                    logger.info(f"CC state name is {trit_name}")
                    no_of_cerequest=row["CE request"]
                    break
                
                   
        else:
            logger.info("It doesn't comes under AO or AM product")


        return no_of_cerequest
    
    except Exception as e:
        logger.info(f"fails at ao_am_states function - {e}")
        return None

####################################################################

def process_pquestions(pquestions):
    data = pd.DataFrame(pquestions)
    grouped_data = data.groupby('_trit_courseassignment_value')
    
    results = {}
    for course_value, group in grouped_data:
        logger.info(f"\nProcessing for {course_value}:")
        valid_group = group[group["trit_answered"] == True]
        result = check_poll_requirements(valid_group)
        results[course_value] = result

    for result_yn in results.values():
        if result_yn == "yes":
            logger.info("#We can create CE request")
        elif result_yn == "no":
            logger.info("# We can't create CERequest")
        else:
            logger.info("Null in results")



####################################################################


# msevtmgt_eventregistration
def evenregistration(eventregistration_id):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    
    msevtmgt_eventregistration_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/msevtmgt_eventregistrations?$filter=msevtmgt_eventregistrationid eq {eventregistration_id}"

    try:
        response=requests.get(msevtmgt_eventregistration_api_url,headers=headers)

        res=response.json()

        data=res['value']

        msevtmgt_eventregistration=pd.DataFrame(data)

        # msevtmgt_eventregistration columns
        msevtmgt_eventid=msevtmgt_eventregistration['_msevtmgt_eventid_value'][0]
        trit_cedeclinationreason=msevtmgt_eventregistration['trit_cedeclinationreason'][0]
        msevtmgt_contactid_value=msevtmgt_eventregistration['_msevtmgt_contactid_value'][0]
        trit_lgsstate=msevtmgt_eventregistration['trit_lgsstate'][0]
        trit_lgsrequest=msevtmgt_eventregistration['trit_lgsrequest'][0]
        msevtmgt_eventregistrationid=msevtmgt_eventregistration['msevtmgt_eventregistrationid'][0]
        
        return {'msevtmgt_eventid' : msevtmgt_eventid ,'trit_cedeclinationreason':trit_cedeclinationreason
                ,'msevtmgt_contactid_value':msevtmgt_contactid_value,'trit_lgsstate':trit_lgsstate,'trit_lgsrequest':trit_lgsrequest,'msevtmgt_eventregistrationid':msevtmgt_eventregistrationid}
    except Exception as e:
        logger.error(f"Error at function evenregistration and the error is: {e}")
       

#############################################################


def msevtmgt_event(msevtmgt_eventid):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }


    msevtmgt_event_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/msevtmgt_events?$filter=msevtmgt_eventid eq {msevtmgt_eventid}"
    
    try:
        response=requests.get(msevtmgt_event_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        msevtmgt_event=pd.DataFrame(data)
        
        
        # msevtmgt_event columns
        
        trit_type = msevtmgt_event["trit_type"][0]
        trit_product = msevtmgt_event["_trit_product_value"][0]
        trit_deliverymechanisms= msevtmgt_event["trit_deliverymechanisms"][0]
        msevtmgt_eventid= msevtmgt_event["msevtmgt_eventid"][0]

        
        
        return {'trit_type':trit_type,'trit_product':trit_product,
                "trit_deliverymechanisms":trit_deliverymechanisms, "msevtmgt_eventid":msevtmgt_eventid}

    except Exception as e:
        logger.error(f"Error at function msevtmgt_event and the error is: {e}")


##############################


def contacts(msevtmgt_contactid_value):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    contacts_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/contacts?$filter=contactid eq {msevtmgt_contactid_value}"
    
    try:
        response=requests.get(contacts_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        contacts=pd.DataFrame(data)
        
        #contacts columns
        contacts_contactid=contacts["contactid"][0]
        contacts_firstname=contacts["firstname"][0]
        contacts_lastname=contacts["lastname"][0]
        contacts_fullname=contacts["fullname"][0]

        return {"contacts_contactid":contacts_contactid, "contacts_firstname":contacts_firstname, 'contacts_lastname':contacts_lastname,
                "contacts_fullname":contacts_fullname}
    except Exception as e:
        logger.error(f"Error at function contacts and the error is: {e}")

##########################################


def licenses_check(contacts_contactid):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }

    try:

        trit_license_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_licenses?$filter=_trit_contact_value eq {contacts_contactid}"

        response=requests.get(trit_license_api_url,headers=headers)

        res=response.json()

        data=res['value']

        trit_license=pd.DataFrame(data)


        trit_license=trit_license[trit_license['statecode']==0]
        trit_license=trit_license[trit_license['statuscode']==1]
        logger.info(f"length of license {len(trit_license)}")
        if len(trit_license) == 1:
            logger.info("only one license")
            licen=1
            return licen

        elif len(trit_license) == 0:
            logger.info("No license")
            licen=0
            return licen
        elif len(trit_license) > 1:
            logger.info("leave the process there are more than one license")
            licen=2
            return licen
        #trit_license columns

    except Exception as e:
        logger.error(f"Error at function licenses_check and the error is: {e}")


def licenses(contacts_contactid):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }
    
    try:
    
        trit_license_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_licenses?$filter=_trit_contact_value eq {contacts_contactid}"
        
        response=requests.get(trit_license_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        trit_license=pd.DataFrame(data)
        trit_license_trit_contact_value=trit_license["_trit_contact_value"][0]
        trit_license_statecode=trit_license["statecode"][0]
        trit_license_trit_stateid_value=trit_license['_trit_stateid_value'][0]
        trit_license_statuscode=trit_license["statuscode"][0]
        trit_rlicense=trit_license['trit_rlicense'][0]
        trit_license_trit_lineofauthority=trit_license['trit_lineofauthority'][0]
        license_id=trit_license['trit_licenseid'][0]
        Name_on_license=trit_license['trit_name'][0]
        fn=trit_license["cr726_firstnameonlicense"][0]
        ln=trit_license["cr726_lastnameonlicense"][0]
        full_name = fn+" "+ln
        trit_license_trit_typeoflicense = trit_license["trit_typeoflicense"][0]



        return {"trit_license_trit_contact_value":trit_license_trit_contact_value,
                "trit_license_statecode":trit_license_statecode,
                "trit_license_trit_stateid_value":trit_license_trit_stateid_value,
                "trit_license_statuscode":trit_license_statuscode,"trit_rlicense":trit_rlicense,
                "trit_license_trit_lineofauthority":trit_license_trit_lineofauthority,
                "license_id":license_id,"Name_on_license":full_name,"trit_typeoflicense":trit_license_trit_typeoflicense}
        
        # return trit_license
    except Exception as e:
        logger.error(f"Error at function licenses and the error is: {e}")

#########################################################


def course_assignment(course_assignment_id,event_id):
    try:
        client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
        client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
        tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
        token = get_token(client_id, client_secret, tenant_id)
    
    
        headers = {
            'Authorization': 'Bearer ' + token,
            'Prefer': 'odata.maxpagesize=5000',
            'OData-MaxVersion': '4.0',
            'OData-Version': '4.0'
        }
    
        trit_courseassignment_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_courseassignments?$filter=trit_courseassignmentid eq {course_assignment_id}"
        
        
        response=requests.get(trit_courseassignment_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        trit_courseassignment=pd.DataFrame(data)
        
        return trit_courseassignment
    except Exception as e:
        logger.error(f"Error at function course_assignment and the error is: {e}")

############################################



def pquestions(course_assignment_id):
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }
    
    try:
        trit_pollquestions_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_pollquestions?$filter=_trit_courseassignment_value eq {course_assignment_id}"
        # trit_pollquestions_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_pollquestions?$filter=_trit_courseassignment_value eq {ids}"
        
        response=requests.get(trit_pollquestions_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        trit_pollquestions=pd.DataFrame(data)
    
    
        return {"trit_name":trit_pollquestions['trit_name'], "trit_answered":trit_pollquestions['trit_answered'],"_trit_courseassignment_value": trit_pollquestions["_trit_courseassignment_value"]}
    
    except:
        logger.info(f"This Evenregistration {course_assignment_id} doesn't contains poll questions")
###########################################


def validate_lgs(state_id, contact_data):
    
    """
    Validates the designation logic based on state, designation, and contact data.

    :param state_id: The state code as a string.
    :param contact_data: The contact identifier to filter designation awards.
    :return: True if the validation conditions are met, False otherwise.
    """
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    
    try:
        # Retrieve token
        tokens = get_token(client_id, client_secret, tenant_id)
        headers = {
            'Authorization': f'Bearer {tokens}',
            'Prefer': 'odata.maxpagesize=5000',
            'OData-MaxVersion': '4.0',
            'OData-Version': '4.0'
        }

        # Fetch state data
        state_api_url = f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_states?$filter=trit_stateid eq '{state_id}'"
        
        try:
            state_response = requests.get(state_api_url, headers=headers)
            state_response.raise_for_status()
            state_data = state_response.json().get('value', [])
            
            if not state_data:
                logger.info("No state data found for the provided state_id.")
                return False
            
            state_name = state_data[0].get("trit_name")
            logger.info(f"State name retrieved: {state_name}")

            # Fetch designation awards
            designation_award_api_url = f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_designationawards?$filter=_trit_contact_value eq '{contact_data}'"
            response = requests.get(designation_award_api_url, headers=headers)
            response.raise_for_status()
            designation_data = response.json().get('value', [])
            
            if not designation_data:
                logger.info("No designation awards found for the contact data.")
                return False
            
            designation_df = pd.DataFrame(designation_data)
            designation_df["state"] = state_name

            logger.info(f"info of designation df: {designation_df}")

        except requests.RequestException as e:
            logger.error(f"API request failed: {e}")

        # Validate each row
        for idx, row in designation_df.iterrows():
            try:
                award_date_str = row["trit_awarddate"]
                if award_date_str:
                    logger.info(f"awarded date {award_date_str}")
                    award_date = datetime.datetime.strptime(award_date_str, "%Y-%m-%d")
                    logger.info(f"awarded date {award_date}")
                else:
                    # Handle the case when award_date_str is None or empty
                    award_date = None  # Or some default date
                    # Optionally log or raise an exception if this is unexpected
                designation = row["_trit_designation_value"]
                row_state_name = row["state"]

                # Validation conditions
                if (
                    (row_state_name == "AL" and "c75f2772-389c-e911-a819-000d3a1ca508" in designation and award_date.year < 2013) or
                    (row_state_name == "NJ" and "c75f2772-389c-e911-a819-000d3a1ca508" in designation) or
                    (row_state_name == "NJ" and "89a1dfa4-cd65-ef11-bfe2-000d3a99f7aa" in designation) or
                    (row_state_name == "NV" and "c75f2772-389c-e911-a819-000d3a1ca508" in designation) or
                    (row_state_name == "UT" and "c75f2772-389c-e911-a819-000d3a1ca508" in designation) or
                    (row_state_name == "UT" and "cb5f2772-389c-e911-a819-000d3a1ca508" in designation)
                ):
                    designation_df.at[idx, "LGS"] = True
                    logger.info(f"Row {idx}: Validated as True (LGS).")
                else:
                    designation_df.at[idx, "LGS"] = False
                    logger.info(f"Row {idx}: Validated as False (LGS).")

            except Exception as row_error:
                logger.error(f"Error processing row {idx}: {row_error} for contact {contact_data}")
                designation_df.at[idx, "LGS"] = False

        # Summarize results
        group_designation = designation_df["LGS"].sum()
        logger.info(f"Total valid LGS entries: {group_designation}")

        return group_designation > 0

    except requests.RequestException as api_error:
        logger.error(f"API request failed: {api_error}")
        return False
    except Exception as general_error:
        logger.error(f"Unexpected error: {general_error}")
        return False

############################################

def fetch_poll_questions(trit_courseassignment):
    """
    Fetch poll questions for each course assignment and return a dictionary of DataFrames.

    Parameters:
        trit_courseassignment (DataFrame): DataFrame containing course assignments.
        client_id (str): Client ID for authentication.
        client_secret (str): Client Secret for authentication.
        tenant_id (str): Tenant ID for authentication.

    Returns:
        dict: A dictionary where keys are `ca_id` and values are DataFrames containing poll questions.
    """
    dataframes = {}  # Dictionary to store dataframes for each ca_id
    
    # Helper function to get the token
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    token = get_token(client_id, client_secret, tenant_id)

    try:

        for index, row in trit_courseassignment.iterrows():
            ca_id = row["trit_courseassignmentid"]
            trit_pollquestions_api_url = f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_pollquestions?$filter=_trit_courseassignment_value eq {ca_id}"
            
            headers = {
                'Authorization': 'Bearer ' + token,
                'Prefer': 'odata.maxpagesize=5000',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
            
            response = requests.get(trit_pollquestions_api_url, headers=headers)
            
            if response.status_code == 200:  # Ensure the request was successful
                res = response.json()
                data = res.get('value', [])  # Get the data, defaulting to an empty list
                
            
            # Create a new DataFrame for the current ca_id
                df = pd.DataFrame(data)
                dataframes[ca_id] = df  # Store it in the dictionary with ca_id as the key
            else:
                logger.info(f"Failed to fetch data for ca_id: {ca_id}. Status Code: {response.status_code}")

        return dataframes
    except Exception as e:
        logger.error(f"Error in fetch_poll_questions: {e}")
        return {}

#############################################

def course_assignment_df(event_reg_id):
    '''
    This is used to retrieve all course assignments records based on event registration ID
    
    '''
    trit_courseassignment_api_url=f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_courseassignments?$filter=_trit_eventregistrationid_value eq {event_reg_id}"
    
    client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
    client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
    tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
    
    token = get_token(client_id, client_secret, tenant_id)


    headers = {
        'Authorization': 'Bearer ' + token,
        'Prefer': 'odata.maxpagesize=5000',
        'OData-MaxVersion': '4.0',
        'OData-Version': '4.0'
    }
    
    try:
        response=requests.get(trit_courseassignment_api_url,headers=headers)
        
        res=response.json()
        
        data=res['value']
        
        trit_courseassignment=pd.DataFrame(data)
        
        return trit_courseassignment
    except Exception as e:
        logger.error(f"Error at function course_assignment_df and the error is: {e}")
        return pd.DataFrame()
############################################


def process_course_assignments(test_fpq):
    """
    Process course assignments and generate a structured dictionary.

    Args:
        test_fpq (dict): A dictionary where keys are `ca_id` and values are DataFrames.
        client_id (str): Client ID for API authentication.
        client_secret (str): Client Secret for API authentication.
        tenant_id (str): Tenant ID for API authentication.

    Returns:
        dict: Processed data for all course assignments.
    """
    try:

        result_data = {}
        
        for ca_id, df in test_fpq.items():  
            
            client_id = '6e5989aa-4fd1-4015-8648-8f75609d607b'
            client_secret = 'mUv8Q~1u3JtjdAdw.ov1sRfjzTm3yS.f~cC6wcQS'
            tenant_id = '95f69e7d-1811-4ab9-9b5a-eba95d3eba9b'
            
            token = get_token(client_id, client_secret, tenant_id)
    
            headers = {
                'Authorization': 'Bearer ' + token,
                'Prefer': 'odata.maxpagesize=5000',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
            
            trit_courseassignment_api_url = (
                f"https://scicdev.crm.dynamics.com/api/data/v9.1/trit_courseassignments?$filter=trit_courseassignmentid eq {ca_id}"
            )

            response = requests.get(trit_courseassignment_api_url, headers=headers)
            
            res = response.json()
    
            data = res.get('value', [])
            comments_retrieval_course_assignment = pd.DataFrame(data)
            trit_admincomment = comments_retrieval_course_assignment.get('trit_admincomment', pd.Series(dtype=object))
    
            pq = {
                "trit_name": [],
                "trit_answered": [],
                "_trit_courseassignment_value": []
            }
    
            if isinstance(df, pd.DataFrame):  # Ensure the value is a DataFrame
                for _, row in df.iterrows():  # Iterate over DataFrame rows
                    pq["trit_name"].append(row['trit_name'])
                    pq["trit_answered"].append(row['trit_answered'])
                    pq["_trit_courseassignment_value"].append(row["_trit_courseassignment_value"])
    
                    if not trit_admincomment.empty:  # Check if 'trit_admincomment' is not empty
                        for i in trit_admincomment:
                            if i:  # Ensure `i` is not None or empty
                                result = i.split("-")[:3]
                                joined_data = "-".join(result) + ": question"
                                
                                pq["trit_name"].append(joined_data)
                                pq['trit_answered'].append(True)
                                pq['_trit_courseassignment_value'].append(ca_id)
    
            result_data[ca_id] = pq
    
        return result_data
    
    except Exception as e:
        logger.error(f"Error at function course_assignment_df and the error is: {e}")
        return pd.DataFrame()

#############################################

    
def cerequest_check(eventregistration_id): 
    '''
    SS type - 314310000

    Not a SS type - 314310001

    Delivery Mechanism - 314310001 - Webinar

    Trit ce declination other than "314310000 - Credit Already Satisfied","314310001 - GrandFathered","Not Licensed - 314310002"s
    '''
    # Initialize the variable to store the number of CE requests
    no_of_cerequest = None
    try:
        logger.info(f"entered cerequest_check function for {eventregistration_id}")

        # Reinitialize no_of_cerequest to None, can be modified during processing if needed
        no_of_cerequest = None

        # Placeholder for information after percentage check failure (no info fetched in this case)
        info_after_percentage_check= "No info acquired due to condition fail"

        # Retrieve course assignment DataFrame based on event registration ID
        ca_df = course_assignment_df(eventregistration_id)
        logger.info(f'course assign - {ca_df}')
        
        # Fetch poll questions related to the course assignment
        fpq = fetch_poll_questions(ca_df)
        
        # Process the fetched poll questions and course assignments
        pca = process_course_assignments(fpq)

        # Initialize an empty list to store CE request information for the event registration ID
        overall_ce_request_event_reg_id=[]    

        # Iterate over the processed course assignments (pca is a dictionary where ca_id is the key)    
        for ca_id, df in pca.items():
            logger.info(f"Processing DataFrame for ca_id: {ca_id}")

            # Retrieve event registration details based on the event registration ID
            er=evenregistration(eventregistration_id)

            # Fetch event registration details based on the event registration ID 
            msevtmgt_contactid_value = er["msevtmgt_contactid_value"] # Retrieve the contact ID value from the event registration details
            msevtmgt_eventid=er['msevtmgt_eventid']# Extract the event ID from the retrieved event registration details

            # Fetch event details based on the event ID
            ev = msevtmgt_event(msevtmgt_eventid)
            
            delivery_mechanism = ev["trit_deliverymechanisms"] # Extract the delivery mechanism for the event
            trit_product = ev['trit_product'] # Extract the product associated with the event          

            # Fetch license details based on the contact ID
            lic = licenses(msevtmgt_contactid_value)
            license_id = lic.get("license_id")
            license_name=lic.get("Name_on_license")
            trit_license_trit_stateid_value=lic.get('trit_license_trit_stateid_value')            
            type_of_license = lic.get("trit_typeoflicense")
            trit_license_trit_lineofauthority=lic.get("trit_license_trit_lineofauthority")

            # Use the extracted product, state ID, delivery mechanism, license type, and line of authority to check state approval
            state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,license_id)
            
            # Validate LGS based on the state ID and contact ID
            val_LGS = validate_lgs(trit_license_trit_stateid_value, msevtmgt_contactid_value)

            logger.info(f"LGS Validated - {val_LGS}")

            # Retrieve contact details based on the provided contact ID
            cont = contacts(msevtmgt_contactid_value)

            # Fetch course assignment details based on course assignment ID and event registration ID
            ca = course_assignment(ca_id,eventregistration_id)

            # Extract the percentage of attendance from the course assignment data
            percentage_attendance_check = ca["trit_percentattended"][0]
            logger.info(f"percentage_attendance_check - {percentage_attendance_check}")

            # Initialize a flag for CE request creation
            ce_request_created = False

            # Check if the attendance percentage is available (not None)
            if percentage_attendance_check is not None:
                logger.info("came into percentage_attendance_check")

                # Assign the attendance percentage value to a variable for further use
                percentage_check = percentage_attendance_check
                logger.info(f"In courseassignment attendance percentage value present and it is {percentage_check} ")

                # Extract the contact ID from the contact details
                contacts_contactid = cont["contacts_contactid"]
                logger.info(f"contactID - {contacts_contactid}")

                # Check license status using the extracted contact ID
                lic_check=licenses_check(contacts_contactid)
                logger.info(f"license check {lic_check}")

                # This is where we retrieve License details
                try:
                    # Retrieve license details using the contact ID
                    lic = licenses(contacts_contactid)   
                    
                    # Extract Type of License from license
                    trit_license_trit_licensetype=lic.get('trit_typeoflicense')
                    logger.info(f"License type - {trit_license_trit_licensetype}")

                    # Extract Residence license from license
                    trit_rlicense=lic.get("trit_rlicense")
                    logger.info(f"Resident License {trit_rlicense}")

                    # Extract state id from license
                    trit_license_trit_stateid_value=lic.get('trit_license_trit_stateid_value')
                    logger.info(f"State id - {trit_license_trit_stateid_value}")

                    # Extract Line of Authority from license
                    trit_license_trit_lineofauthority=lic.get("trit_license_trit_lineofauthority")
                    logger.info(f"line of authority - {trit_license_trit_lineofauthority}")

                    # Extract Line of Authority from license
                    license_id = lic.get("license_id")
                    trit_licenseid = lic.get("trit_licenseid")

                    # Extract Type Of License from license
                    type_of_license = lic.get("trit_typeoflicense")
                    logger.info(f"Type of License - {type_of_license}")

                    # Validate the LGS using the state ID and contact ID
                    val_LGS = validate_lgs(trit_license_trit_stateid_value, contacts_contactid)
                    logger.info(f"LGS Validated - {val_LGS}")


                except Exception as e:
                     # If there's an issue
                    logger.error("This is where we retrieve License details  - comment to check")
                    logger.error(f"Exception raised in cerequest_check function, while trying to get the license details - {e}")

                # Check if there is exactly one license
                if lic_check == 1:
                    logger.info("Satisfied lic_check = 1 condition")
                    logger.info("one License")

                    # Retrieve event registration details
                    er=evenregistration(eventregistration_id)
                    msevtmgt_eventid=er['msevtmgt_eventid']

                    # Retrieve event details using the event ID
                    ev = msevtmgt_event(msevtmgt_eventid)
                    
                    # Condition where we check ss type, ce declination and delivery mechanism
                    try:

                        # Condition where we check ss type
                        try:
                            # Check if the event type is SS type
                            if ev['trit_type'] == 314310000:
                                logger.info("The sales channel is SS type")
                                sales_channel_type = "SS or 314310000"
                            elif ev['trit_type'] == 314310001:
                                logger.info("The sales channel is High School type")
                                sales_channel_type = "High School or 314310001"
                            elif ev['trit_type'] == 314310002:
                                logger.info("The sales channel is LS type")
                                sales_channel_type = "LS or 314310002"   
                            elif ev['trit_type'] == 314310009:
                                logger.info("The sales channel is UNIV type")
                                sales_channel_type = "UNIV or 314310009"  
                            else:
                                logger.info("The Sales channel is is None or other than these 314310000, 314310001, 314310002 or 314310009")

                        except Exception as e:
                            logger.info("Condition where we check ss type - comment to check")
                            logger.info(f"Exception in checking ss type {e}")
                            raise

                        # Condition where we check ce declination
                        try:
                            # Check if the CE declination reason is not in the specified list
                            if er['trit_cedeclinationreason'] not in ["314310000", "314310001", "314310002"]:
                                logger.info("ce declination is none")
                                ce_decli = None
                            elif er['trit_cedeclinationreason'] == 314310000:
                                logger.info("ce declination is Credits Already Satisfied")
                                ce_decli = "Credits Already Satisfied"
                            elif er['trit_cedeclinationreason'] == 314310001:
                                logger.info("ce declination is Grandfathered")
                                ce_decli = "Grandfathered"
                            elif er['trit_cedeclinationreason'] == 314310002:
                                logger.info("ce declination is Not Licensed")
                                ce_decli = "Not Licensed"
                            else:
                                logger.info("The CE declination reason is not None neither they are these 314310000, 314310001 or 314310002")

                        except Exception as e:
                            logger.info("Condition where we check ce declination - comment to check")
                            logger.info(f"Exception in ce declination - {e}")
                            raise
                        
                        # Condition where we check delivery mechanism
                        try:
                            # Check if the delivery mechanism is webinar
                            if ev["trit_deliverymechanisms"] == 314310001:
                                logger.info("Delivery Mechanism is webinar")
                                Del_Mech = "Webinar"
                            elif ev["trit_deliverymechanisms"] == 314310000:
                                logger.info("Delivery Mechanism is Classroom")
                                Del_Mech = "Classroom"
                            elif ev["trit_deliverymechanisms"] == 314310002:
                                logger.info("Delivery Mechanism is Self-Paced")
                                Del_Mech = "Self-Paced"
                            elif ev["trit_deliverymechanisms"] == 314310003:
                                logger.info("Delivery Mechanism is Blended")
                                Del_Mech = "Blended"
                            elif ev["trit_deliverymechanisms"] == 314310004:
                                logger.info("Delivery Mechanism is Corp-WB")
                                Del_Mech = "Corp-WB"
                            elif ev["trit_deliverymechanisms"] == 314310005:
                                logger.info("Delivery Mechanism is Corp-Class")
                                Del_Mech = "Corp-Class"
                            else:
                                logger.info("The Delivery Mechanism is not in any of these 314310000, 314310001, 314310002, 314310003, 314310004 or 314310005")

                        except Exception as e:
                            logger.info("Condition where we check delivery mechanism - comment to check")
                            logger.info(f"Exception in delivery mechanism - {e}")
                            raise
                    
                        Sc_CE_dec_del_mech = {"Sales Channel":sales_channel_type,"CE Declination reason":ce_decli, "Delivery Mechanism":Del_Mech}
                        logger.info(f"Returning Sales Channel, CE Declination reason and Delivery Mechanism - {Sc_CE_dec_del_mech}")
                    except Exception as e:
                        logger.info("Condition where we check ss type, ce declination and delivery mechanism - comment to check")
                        logger.info(f"Exception in checking ss type, ce declination and delivery mechanism - {e}")

                                       

                    # Retrieve the Delivery Mechanism
                    delivery_mechanism = ev["trit_deliverymechanisms"]
                    logger.info(f"Delivery Mechanisms - {delivery_mechanism}")

                    # Retrieve the CE Declination Reason 
                    dm=er['trit_cedeclinationreason']
                    logger.info(f"ce declination reason {dm}")

                    t_type=ev['trit_type']

                    logger.info(f"Event ID - {msevtmgt_eventid}")
                    logger.info(f"Event Registration id - {eventregistration_id}")

                    # Details_before_entering_condition_trit_rlicense_equal_to_1
                    try:
                        Details_before_entering_condition_trit_rlicense_equal_to_1 = { "Event Registration id" : eventregistration_id ,
                        "Event ID" : msevtmgt_eventid,"Contact ID" : contacts_contactid, "License ID" : license_id,
                        " Name on License" : license_name , "Type Of License" : type_of_license , "State ID in License" : trit_license_trit_stateid_value ,
                        "Sc_CE_dec_del_mech" : Sc_CE_dec_del_mech, "Validated LGS" : val_LGS, "Line Of Authority" : trit_license_trit_lineofauthority,
                        "Resident License" : trit_rlicense, "Active License": 1
                        }
                        logger.info(f"Dictionary of values Details_before_entering_condition_trit_rlicense_equal_to_1 {Details_before_entering_condition_trit_rlicense_equal_to_1}")
                    except Exception as e:
                        logger.info("Details_before_entering_condition_trit_rlicense_equal_to_1 - comment to check")
                        logger.info(f"Exception in Details_before_entering_condition_trit_rlicense_equal_to_1 {e}")

                    # Check if the trit_rlicense value is 1, indicating it's a resident license
                    if trit_rlicense == 1:
                        logger.info("it is a resident license")

                        # Check if trit_type is 314310000 (SS type), trit_cedeclinationreason is not in the list, and the delivery mechanism is Webinar (314310001)
                        if ev['trit_type'] == 314310000 and er['trit_cedeclinationreason'] not in [314310000,314310001,314310002] and delivery_mechanism == 314310001:
                            logger.info(f"This {eventregistration_id} satisfied trit_type as SS & trit_cedeclinationreason is None and delivery method Webinar - {delivery_mechanism}")

                             # Extract the contacts_contactid from the cont object
                            contacts_contactid = cont["contacts_contactid"]

                            # Try to get the license information for the contact
                            try:
                                lic = licenses(contacts_contactid) 
                                trit_license_trit_licensetype=lic['trit_typeoflicense']
                                trit_license_trit_stateid_value=lic['trit_license_trit_stateid_value']

                                logger.info(f"{lic}")
                            except Exception as e:
                                logger.info("Try to get the license information for the contact - comment to check")
                                logger.info(f"Exception in Try to get the license information for the contact - {e}")

                            # Check if the license state code is 0 or Active (valid license)
                            if lic['trit_license_statecode'] == 0:
                                logger.info(f"This {eventregistration_id} have only one license")

                                # Check if the license has a valid state id value
                                if lic['trit_license_trit_stateid_value'] is not None:
                                    logger.info(f"This {eventregistration_id} have stateid value")

                                    # LGS Validation inside - Check if the license has a valid state id value
                                    try:  
                                        val_LGS = validate_lgs(trit_license_trit_stateid_value, contacts_contactid)
                                        logger.info(f"LGS Validated - {val_LGS}")
                                    except Exception as e:
                                        logger.info("LGS Validation inside - Check if the license has a valid state id value - comment to check")
                                        logger.info(f"Exception in LGS Validation inside - Check if the license has a valid state id value - {e}")

                                    # Check if val_LGS is False, indicating the state is not LGS
                                    if val_LGS == False:
                                        logger.info(f" This {eventregistration_id}'s State comes under Non-LGS states")

                                        # Define the set of specified states and state codes
                                        specified_states = {'9544192b-a600-ea11-a827-000d3a1cac04', 
                                                            '881d0c2a-a600-ea11-a825-000d3a1cadb6', 
                                                            '861d0c2a-a600-ea11-a825-000d3a1cadb6', 
                                                            '33805427-a600-ea11-a826-000d3a1ca610'}
                                        
                                        # List of state codes
                                        State_Code=[                                        
                                            '8b44192b-a600-ea11-a827-000d3a1cac04',
                                            'd21d0c2a-a600-ea11-a825-000d3a1cadb6',
                                            'cb1d0c2a-a600-ea11-a825-000d3a1cadb6',
                                            'c91d0c2a-a600-ea11-a825-000d3a1cadb6',
                                            'ab1d0c2a-a600-ea11-a825-000d3a1cadb6',                                                                          
                                            '7c1d0c2a-a600-ea11-a825-000d3a1cadb6',
                                            '40805427-a600-ea11-a826-000d3a1ca610',
                                            '3c805427-a600-ea11-a826-000d3a1ca610',                                       
                                        ]
                                        
                                        # Set the initial value for ce_request_created to False
                                        ce_request_created = False
                                        
                                        # Get course assignment details based on ca_id and eventregistration_id
                                        ca = course_assignment(ca_id,eventregistration_id)
                                        
                                        # Get the trit_product value from the event
                                        trit_product = ev['trit_product']
                                        logger.info(f"prod - {trit_product}")

                                        # Check if the license state is a specific value and the attendance percentage meets the threshold
                                        if trit_license_trit_stateid_value == '7c1d0c2a-a600-ea11-a825-000d3a1cadb6' and percentage_attendance_check >= 70:
                                                logger.info("PR state 70%")
                                                logger.info(f"# Check for AO&AM products - based on percentage 1 {percentage_attendance_check}")

                                                # Get the number of CE requests based on the product and state
                                                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                logger.info(f"no of ce requests {no_of_cerequest}")

                                                # Store the information after the percentage check
                                                info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}

                                                # Append the number of CE requests to the overall list
                                                overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                # Get the license name from the license object
                                                license_name = lic.get("Name_on_license")

                                                # Get state approval IDs based on product, state, and delivery method
                                                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)
                                                
                                                # Loop through the state approval IDs and create a CE request for each one
                                                for sal in state_approval_id[:no_of_cerequest]:
                                                    logger.info("ce creation")

                                                    try:
                                                        logger.info(sal.get("Id"))
                                                    except:
                                                        logger.info("no approv id exception")
                                                    # Extract the state approval ID
                                                    state_approval_id = sal
                                                    logger.info(state_approval_id)

                                                    # Create the new record for the CE request
                                                    new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",    
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})", 
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 1
                                                    }
                                                    
                                                    try:
                                                        ce_request_odata(new_record)

                                                        # Mark that a CE request was created
                                                        ce_request_created = True
                                                    except Exception as e:
                                                        logger.error(f"Failed to submit record: {new_record}")
                                                        logger.error(f"Error: {e}")

                                                return (no_of_cerequest,ce_request_created,eventregistration_id)
                                        
                                        elif trit_license_trit_stateid_value in {"8b44192b-a600-ea11-a827-000d3a1cac04", "3c805427-a600-ea11-a826-000d3a1ca610"} and percentage_attendance_check >= 85:
                                                logger.info("HI or VA State & >= 85%")
                                                logger.info(f"# Check for AO&AM products - based on percentage 2 {percentage_attendance_check}")
                                                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                logger.info(f"no of ce requests {no_of_cerequest}")
                                                ce_request_created = True
                                                
                                                # Store the information after the percentage check
                                                info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}

                                                # Append the number of CE requests to the overall list
                                                overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                # Get the license name from the license object
                                                license_name = lic.get("Name_on_license")

                                                # Get state approval IDs based on product, state, and delivery method                             
                                                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)
                                               
                                                # Loop through the state approval IDs and create a CE request for each one
                                                for sal in state_approval_id[:no_of_cerequest]:
                                                    logger.info("ce creation")

                                                    try:
                                                        logger.info(sal.get("Id"))
                                                    except:
                                                        logger.info("no approv id exception")
                                                    # Extract the state approval ID
                                                    state_approval_id = sal
                                                    logger.info(state_approval_id)

                                                    # Create the new record for the CE request
                                                    new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",    
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})", 
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 1
                                                    }
                                                    
                                                    try:
                                                        ce_request_odata(new_record)
                                                    except Exception as e:
                                                        logger.info(f"Failed to submit record: {new_record}")
                                                        logger.info(f"Error: {e}")
                                                return (no_of_cerequest,ce_request_created,eventregistration_id)
                                            
                                        elif trit_license_trit_stateid_value in {"40805427-a600-ea11-a826-000d3a1ca610", "ab1d0c2a-a600-ea11-a825-000d3a1cadb6"} and percentage_attendance_check >= 90:
                                                logger.info("TX, ND >= 90%")
                                                logger.info(f"# Check for AO&AM products - based on percentage 3 {percentage_attendance_check}")
                                                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                logger.info(f"no of ce requests {no_of_cerequest}")
                                                ce_request_created = True
                                                
                                                # Store the information after the percentage check
                                                info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}

                                                # Append the number of CE requests to the overall list
                                                overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                license_name=lic.get("Name_on_license")

                                                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)

                                                # Loop through the state approval IDs and create a CE request for each one
                                                for sal in state_approval_id[:no_of_cerequest]:
                                                    logger.info("ce creation")

                                                    try:
                                                        logger.info(sal.get("Id"))
                                                    except:
                                                        logger.info("no approv id exception")
                                                    # Extract the state approval ID
                                                    state_approval_id = sal
                                                    
                                                    
                                                    # Create the new record for the CE request
                                                    new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",    
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})", 
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 1
                                                    }
                                                    
                                                    try:
                                                        ce_request_odata(new_record)
                                                    except Exception as e:
                                                        logger.info(f"Failed to submit record: {new_record}")
                                                        logger.info(f"Error: {e}")

                                                return (no_of_cerequest,ce_request_created,eventregistration_id)
                                            
                                        elif trit_license_trit_stateid_value in {"d21d0c2a-a600-ea11-a825-000d3a1cadb6", "cb1d0c2a-a600-ea11-a825-000d3a1cadb6", "c91d0c2a-a600-ea11-a825-000d3a1cadb6"} and percentage_attendance_check == 100:
                                                logger.info("MD, MI, MN state and = 100 %")
                                                logger.info(f"# Check for AO&AM products - based on percentage 4 {percentage_attendance_check}")
                                                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                logger.info(f"no of ce requests {no_of_cerequest}")
                                                ce_request_created = True
                                                
                                                # Store the information after the percentage check
                                                info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}
                                                
                                                # Append the number of CE requests to the overall list
                                                overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                # Get the license name from the license object
                                                license_name = lic.get("Name_on_license")

                                                # Get state approval IDs based on product, state, and delivery method
                                                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)

                                                # Loop through the state approval IDs and create a CE request for each one
                                                for sal in state_approval_id[:no_of_cerequest]:
                                                    logger.info("ce creation")
                                                    try:
                                                        logger.info(sal.get("Id"))
                                                    except:
                                                        logger.info("no approv id exception")
                                                    # Extract the state approval ID
                                                    state_approval_id = sal
                                                    
                                                    # Create the new record for the CE request
                                                    new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})",
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 1
                                                    }
                                                    
                                                    try:
                                                        ce_request_odata(new_record)
                                                    except Exception as e:
                                                        logger.info(f"Failed to submit record: {new_record}")
                                                        logger.info(f"Error: {e}")

                                                return (no_of_cerequest,ce_request_created,eventregistration_id)
                                            
                                        elif (trit_license_trit_stateid_value not in State_Code or trit_license_trit_stateid_value in specified_states) and percentage_attendance_check >= 80:
                                                logger.info(f"# Check for AO&AM products - based on percentage 5 {percentage_attendance_check}")
                                                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                logger.info(f"no of ce requests {no_of_cerequest}")
                                                ce_request_created = True
                                                
                                                # Store the information after the percentage check
                                                info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}

                                                # Append the number of CE requests to the overall list
                                                overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                # Get the license name from the license object
                                                license_name=lic.get("Name_on_license")

                                                # Get state approval IDs based on product, state, and delivery method
                                                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)
                                                logger.info(f'type of state_approval_id - {type(state_approval_id)}')
                                                logger.info(f"Length of state_approval_id: {len(state_approval_id)}")
                                                logger.info(f"state approval list - {state_approval_id}")

                                                # Loop through the state approval IDs and create a CE request for each one
                                                for sal in state_approval_id[:no_of_cerequest]:

                                                    logger.info("ce creation")

                                                    try:
                                                        state_approval_id = sal
                                                        logger.info(f"Extracted state approval ID: {state_approval_id}")
                                                    except Exception as e:
                                                        logger.info(f"no approv id exception - {e}")

                                                    state_approval_id = sal    
                                                    
                                                    
                                                    # Create the new record for the CE request
                                                    new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})",
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 1
                                                    }
                                                    logger.info(new_record)

                                                    try:
                                                        ce_request_odata(new_record)
                                                    except Exception as e:
                                                        logger.info(f"Failed to submit record: {new_record}")
                                                        logger.info(f"Error: {e}")
                                                return (no_of_cerequest,ce_request_created)
                                                
                                        # Check if the state ID is in the specified_states set
                                        elif trit_license_trit_stateid_value in specified_states:
                                                # Define attendance thresholds based on instruction hours
                                                attendance_thresholds = {
                                                16: 98,  # 98% for 16 hours
                                                7:  95,  # 95% for 7 hours
                                                4:  92,  # 92% for 4 hours
                                                3:  89,  # 89% for 3 hours
                                                2:  83,  # 83% for 2 hours
                                                1:  67   # 67% for 1 hour
                                                }
                                            
                                                # Get the instruction hours and corresponding attendance threshold
                                                instruction_hours = ca["trit_courseassignment_trit_instructionhours"]
                                                required_percentage = attendance_thresholds.get(instruction_hours)
                                                
                                                # Check if a valid attendance threshold exists
                                                if required_percentage:
                                                    # Check if the percentage attendance meets or exceeds the threshold
                                                    if percentage_attendance_check >= required_percentage:
                                                        logger.info(f"# Attendance meets the threshold of {required_percentage}% for {instruction_hours} hours.")

                                                        # Calculate the number of CE requests based on the product and license state ID
                                                        no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                        logger.info(f"Number of CE requests: {no_of_cerequest}")

                                                        # Mark that a CE request was created
                                                        ce_request_created = True
                                                
                                                    # Store the information after the percentage check
                                                    info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}
                                                    

                                                    # Append the number of CE requests to the overall list
                                                    overall_ce_request_event_reg_id.append(no_of_cerequest)

                                                    # Get the license name from the license object
                                                    license_name=lic.get("Name_on_license")
                                                    
                                                    # Get state approval IDs based on product, state, and delivery method
                                                    state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)

                                                    # Loop through the state approval IDs and create a CE request for each one
                                                    for sal in state_approval_id[:no_of_cerequest]:
                                                        logger.info("ce creation")

                                                        try:
                                                            logger.info(sal)
                                                        except:
                                                            logger.info("no approv id exception")
                                                        # Extract the state approval ID
                                                        state_approval_id = sal
                                                        
                                                        # Create the new record for the CE request
                                                        new_record = {
                                                            "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                            "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                            "trit_name":f"{license_name}",
                                                            "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",
                                                            "trit_ProductId@odata.bind":f"/products({trit_product})",
                                                            "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                            "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                            "statuscode": 1
                                                        }
                                                        logger.info(new_record)

                                                        try:
                                                            ce_request_odata(new_record)
                                                        except Exception as e:
                                                            logger.info(f"Failed to submit record: {new_record}")
                                                            logger.info(f"Error: {e}")
                                                        return (no_of_cerequest,ce_request_created)
                                                    else:
                                                        logger.info(f"# Attendance does NOT meet the required {required_percentage}% for {instruction_hours} hours.")
                                                        # Optionally, handle the case where attendance doesn't meet the threshold.
                                                        logger.info(ce_request_created)
                                                elif not ce_request_created and df:
                                                    # Process polls only for these states if percentage criteria fails
                                                    process_pquestions(df)
                                                    logger.info("# Created cerequest based on polls for specified state")
                                                    no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                                    logger.info(f"no of ce requests {no_of_cerequest}")
                                                    ce_request_created = True
                                                    if lic.get("trit_license_trit_lineofauthority") == 314310000:
                                                        logger.info("P/C")
                                                        license_id=lic.get("trit_licenseid")
                                                        
                                                        LOA = pc(license_id,trit_product,trit_license_trit_stateid_value)
                                                    elif lic.get("trit_license_trit_lineofauthority")   == 314310001:
                                                        logger.info("L/H")
                                                        license_id=lic.get("trit_licenseid")
                                                        LOA = lh(license_id,trit_product,trit_license_trit_stateid_value)
                                                    
                                                    elif lic.get("trit_license_trit_lineofauthority") == 314310002:
                                                        logger.info("P/C & L/H")
                                                        try:
                                                            license_id=lic.get("trit_licenseid")
                                                            LOA = pc(license_id,trit_product,trit_license_trit_stateid_value)
                                                        except:
                                                            license_id=lic.get("trit_licenseid")
                                                            LOA = pc(license_id,trit_product,trit_license_trit_stateid_value)
                                                    else:
                                                        logger.info("Null")
                                                        LOA = "Null"
                                                    # Store the information after the percentage check
                                                    info_after_percentage_check={"Course_Assignment_ID" : ca_id, 
                                                      "Licensee details" : Details_before_entering_condition_trit_rlicense_equal_to_1, 
                                                      "Licensee have active license or not(0 - Active License)" : lic['trit_license_statecode'] ,
                                                      "Product_ID" : trit_product, "Percentage" : percentage_attendance_check ,
                                                      "ce_request_created": ce_request_created,
                                                      "No of CE Request": no_of_cerequest}
                                                    
                                                    return (no_of_cerequest,ce_request_created,eventregistration_id)
                                                    
                                                else:
                                                    logger.info("Ce request declined with both attendance percentage and poll count conditions failing ")
                                                    logger.info(ce_request_created)

                                                
                                        elif (trit_license_trit_stateid_value not in State_Code or trit_license_trit_stateid_value in specified_states) and percentage_attendance_check < 80:
                                            logger.info("into 6")

                                            no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])
                                            logger.info(f"into 6 - {no_of_cerequest}")

                                            # Get the license name from the license object                                        
                                            license_name = lic.get("Name_on_license")

                                            # Get state approval IDs based on product, state, and delivery method
                                            state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,trit_licenseid)
                                            logger.info(f"into 6 - {state_approval_id}")

                                            # Loop through the state approval IDs and create a CE request for each one
                                            for sal in state_approval_id[:no_of_cerequest]:
                                                
                                                try:
                                                    logger.info(sal)
                                                except:
                                                    logger.info("no approv id exception")
                                                # Extract the state approval ID
                                                state_approval_id = sal

                                                logger.info("into the loop")

                                                # Create the new record for the CE request
                                                new_record = {
                                                        "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                                                        "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                                                        "trit_name":f"{license_name}",
                                                        "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",    
                                                        "trit_ProductId@odata.bind":f"/products({trit_product})", 
                                                        "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                                                        "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                                                        "statuscode": 314310003, "statecode":1 
                                                    }
                                                logger.info(new_record)

                                                try:
                                                    
                                                    ce_request_odata(new_record)
                                                    logger.info("passed the else statement")
                                                except Exception as e:
                                                    logger.info(f"Failed to submit record: {new_record}")
                                                    logger.info(f"Error: {e}")
                                                logger.info(ce_request_created)

                                            # create CE request
                                            logger.info(ce_request_created)

                                        else:
                                            logger.info("Ce request declined due to attendance percentage in Non-LGS")

                                    elif val_LGS == True:
                                        logger.info(f"This Event Registration ID - {eventregistration_id} comes under LGS state, So no CE Request can be created")

                                else:
                                    logger.info("failed at trit_license_trit_residentstate is none")
                                    logger.info(ce_request_created)
                            else:
                                logger.info("trit_license_statecode either have no license or multiple license")
                                logger.info(ce_request_created)

                        else:
                            logger.info("It failed trit_type == 314310000 or trit_cedeclinationreason is None or delivery method is not webinar")
                            logger.info(ce_request_created)

                    else:
                        logger.info("it is a non-resident license")
                        logger.info(ce_request_created)

                elif lic_check > 1:
                    logger.info("More than one license so CE requests can not be created")
                    logger.info(ce_request_created)

                elif lic_check==0:
                    logger.info("No License")
            else:
                logger.info("Attendance percentage is none so no CE request can be created escaped in the first condition itself")

                # create CE request
                no_of_cerequest = ao_am_states(trit_product, lic['trit_license_trit_stateid_value'])

                # Get the license name from the license object
                license_name = lic.get("Name_on_license")
                
                # Get state approval IDs based on product, state, and delivery method
                state_approval_id = state_approval(trit_product,trit_license_trit_stateid_value,delivery_mechanism,type_of_license,trit_license_trit_lineofauthority,license_id)
                license_id = license_id
                logger.info(f"into 7 - {state_approval_id}")

                # Loop through the state approval IDs and create a CE request for each one
                for sal in state_approval_id[:no_of_cerequest]:
                    try:
                        logger.info(sal)
                    except:
                        logger.info("no approv id exception")
                    # Extract the state approval ID
                    state_approval_id = sal

                    # Create the new record for the CE request
                    new_record = {
                            "trit_EventRegistrationId@odata.bind": f"/msevtmgt_eventregistrations({eventregistration_id})",
                            "trit_msevtmgt_Event@odata.bind": f"/msevtmgt_events({msevtmgt_eventid})",
                            "trit_name":f"{license_name}",
                            "trit_ParticipantId@odata.bind":f"/contacts({msevtmgt_contactid_value})",    
                            "trit_ProductId@odata.bind":f"/products({trit_product})", 
                            "trit_ParticipantLicenseId@odata.bind":f"/trit_licenses({license_id})",
                            "cr726_StateApproval@odata.bind":f"/trit_instructorapprovals({state_approval_id})",
                            "statuscode": 314310003, "statecode":1 
                        }
                    
                    try:
                        # if statusreason_courseassignment == 314310001 or 314310000:
                        ce_request_odata(new_record)
                    except Exception as e:
                        logger.info(f"Failed to submit record: {new_record}")
                        logger.info(f"Error: {e}")
                    logger.info(ce_request_created)

            return (no_of_cerequest,ce_request_created,eventregistration_id)
            
    except Exception as e:
        logger.info(e)


def ce_request_last_check(eventregistration_id):
    try:
        ce = cerequest_check(eventregistration_id)  # Call the cerequest_check function
        # Handle if ce is None
        if ce is None:
            logger.info(f"cerequest_check returned None: {ce} for eventregistration_id: {eventregistration_id}")
            return ce
        if ce[1] == True:
            logger.info(f"cerequest_check returned True: {ce} for eventregistration_id: {eventregistration_id}")
            return ce
        elif ce[1] == False:
            logger.info(f"cerequest_check returned False: {ce} for eventregistration_id: {eventregistration_id}")
            return ce
        else:
            logger.info(f"Cannot create CE request for this event registration ID {eventregistration_id}")
            return ce
    except Exception as e:
        logger.error(f"Error in ce_request_last_check {e}")
        return JsonResponse(f"Error in ce_request_last_check {e}")

@api_view(['POST'])
def index_ce_request(request):
    try:
        if request.method == "POST":
            eventregistration_id = request.data.get('eventreg_id')
            ce=ce_request_last_check(eventregistration_id)      
            logger.info(ce)      
            return JsonResponse({"response": ce})
    except Exception as e:
        logger.info(e)
        return JsonResponse({"error": str(e)}, status=500)




@api_view(['POST'])
def index(request):
    try:
        if request.method == "POST":
            eventcode = request.data.get('eventcode')
            event_reg_ids = event_name_uuid(eventcode)
            logger.info(f"event registration id list index function {event_reg_ids}")

            invalid_ce_list = []
            already_exists_list = []
            valid_ids = []

            for ers in event_reg_ids:
                logger.info(f"Event Registration ID: {ers}")
                logger.info(f"Event Registration ID: {ers}")

                try:
                    is_valid = ce_request_validation_api(ers)
                    if is_valid is False:
                        logger.info(f"event registration ids false: {ers}")
                        ce = ce_request_last_check(ers)
                        invalid_ce_list.append({"id": ers, "last_check": ce})
                    elif is_valid is True:
                        logger.info(f"event registration ids true: {ers}")
                        already_exists_list.append(ers)
                    else:
                        logger.info(f"event registration ids else: {ers}")
                        logger.info(f"This Event Registration ID has unexpected result: {ers} - {is_valid}")
                except Exception as e:
                    logger.error(f"Error in event registration id {ers}: {e}")
                    invalid_ce_list.append({"id": ers, "error": str(e)})

            result = {
                "event reg ids": event_reg_ids,
                "eligible to check ce list": invalid_ce_list,
                "already_exists_list": already_exists_list,
            }
            return JsonResponse({"invalid_ce_list": invalid_ce_list})

    except Exception as e:
        logger.info(e)
        logger.info(f"error at index exception {e}")
        return JsonResponse({"error": str(e)}, status=500)
