from appservices.common.util import *

patterns_configuarations = Blueprint("patterns_configuarations",__name__)

############### Patterns ################

@patterns_configuarations.route("/add_pattern",methods=["POST","GET"])
def add_pattern():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        loginBrowser = request.headers.get("Sec-Ch-Ua")
        if loginBrowser:
            loginBrowseData = loginBrowser.split(";")
            browser = loginBrowseData[0]
        else:
            loginBrowseData = request.headers.get('User-Agent').split(";")
            browser = loginBrowseData[0]

        client_ip=0
        # Extracting client IP address
        if request.headers.getlist("X-Forwarded-For"): 
            client_ip = request.headers.getlist("X-Forwarded-For")[0]
        else:
            client_ip = request.remote_addr

        actionDate=datetime.datetime.now()

        permissionsList = check_permissions(adminId,"patternPermissions")
        if "add" in permissionsList:
            if request.method == "POST":
                action = request.form.get("action", "HI").strip()
               
                data = request.form.to_dict()
                # Step 1: Handle OTP Generation
                if action == "generate":
                    mail_type = data.get("mailType", "").strip()
                    print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                    if not mail_type:
                        return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                    return jsonify(generate_otp_helper(mail_type))

                # tep 2: Handle OTP Verification
                elif action == "verify":
                    otp_check_id = request.form.get("otpCheckId","SAI")
                    otp_code = request.form.get("otpCode","K")

                    print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                    print(otp_code,"((((((((OTP CODE????????????))))))))")

                    if not otp_check_id or not otp_code:
                        return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                    return jsonify(verify_otp_helper(otp_check_id, otp_code))

                elif action == "update":
                    otp_check_id = request.form.get("otpCheckId", "")
                    otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                    admin_id = request.form.get("adminId", "")
                   
                    otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
        
                    if not otpcheck_queryset:
                        return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                    # Update OTP status to 2 after verification
                    otpcheck_queryset.update(status=2)
                    return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

                

                name = request.form.get("name","")
                rank = request.form.get("rank",0)
                description = request.form.get("description","")
                code = request.form.get("code","")
                isUserWise = request.form.get("isUserWise")
                isAllow = request.form.get("isAllow")
                isCommission = request.form.get("isCommission")
                isSuperDistributor = request.form.get("isSuperDistributor")
                userPermissionId = request.form.get("userPermissionId","")
                payoutPaymentGatewayId = request.form.get("payoutPaymentGatewayId","")
                payinPaymentGatewaysList = request.form.getlist("payinPaymentGatewaysList")
                payinEnable = request.form.get("payinEnable")
                payoutEnable = request.form.get("payoutEnable")
                defaultProfile = request.form.get("defaultProfile")
                defaultPayinPaymentGatewayId = request.form.get("defaultPayinPaymentGatewayId")
                defaultPayoutPaymentGatewayId = request.form.get("defaultPayoutPaymentGatewayId")

                jsonData = request.form.to_dict(flat=True)
                requestData = [jsonData]
                updatedrequestData = [jsonData]

                if name and rank and description and code and userPermissionId:
                    try:
                        admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                        if admin_queryset:
                            message=admin_queryset.userName+" "+name+" Profile created successfully!"
                            save_admin_log_table = save_admin_logs_data(adminId,None,None,"add_pattern","create",actionDate,client_ip,browser,message,requestData,updatedrequestData) 

                        if isUserWise == "True":
                            isUserWise=True
                        else:
                            isUserWise=False

                        if isAllow == "True":
                            isAllow=True
                        else:
                            isAllow=False

                        if isCommission == "True":
                            isCommission=True
                        else:
                            isCommission=False

                        if isSuperDistributor == "True":
                            isSuperDistributor=True
                        else:
                            isSuperDistributor=False

                        if payinPaymentGatewaysList:
                            payinPaymentGatewaysList=[ObjectId(each_payin_pg) for each_payin_pg in payinPaymentGatewaysList]
                        else:
                            payinPaymentGatewaysList = []

                        if payoutPaymentGatewayId:
                            payoutPaymentGatewayId=ObjectId(payoutPaymentGatewayId)
                        else:
                            payoutPaymentGatewayId = ""

                        if payinEnable == "True":
                            payinEnable=True
                        else:
                            payinEnable=False 

                        if payoutEnable == "True":
                            payoutEnable=True
                        else:
                            payoutEnable=False

                        if defaultProfile == "True":
                            defaultProfile=True
                            profiles_queryset = Patterns.objects(status__in=[0,1])
                            profiles_queryset.update(defaultProfile=False)
                        else:
                            defaultProfile=False


                        patterns_table = Patterns(
                            adminId=adminId,
                            name = name,
                            rank = rank,
                            description = description,
                            code = code,
                            isUserWise = isUserWise,
                            isAllow = isAllow,
                            isCommission = isCommission,
                            isSuperDistributor = isSuperDistributor,
                            payinPaymentGatewaysList = payinPaymentGatewaysList,
                            payoutPaymentGatewayId = payoutPaymentGatewayId,
                            payinEnable = payinEnable,
                            payoutEnable = payoutEnable,
                            defaultProfile = defaultProfile,
                            userPermissionId = userPermissionId,
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            )
                        save_table = patterns_table.save()

                        flash("Profile saved successfully!")
                        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
                    except Exception as e:
                        flash("Unable to save profile details!!")
                        app.logger.error(traceback.format_exc())
                        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
                else:
                    flash("Required fields are missing!")
                    return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
        else:
            flash("Staff member does not have given create pattern permissions!!")
            return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to save pattern details!!"
        return render_template("super_admin_templates/patterns_configuarations_list.html",error=error,redirectTo="Pattern")


@patterns_configuarations.route("/update_pattern",methods=["POST","GET"])
def update_pattern():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")   
     
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    existing_record = ""
    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()
    permissionsList = check_permissions(session.get("adminId"),"patternPermissions")
    if "edit" in permissionsList:
        try:
            patternId = request.args.get("patternId","")
            if request.method == "POST":
                action = request.form.get("action", "HI").strip()
                data = request.form.to_dict()
                # Step 1: Handle OTP Generation
                if action == "generate":
                    mail_type = data.get("mailType", "").strip()
                    print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                    if not mail_type:
                        return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                    return jsonify(generate_otp_helper(mail_type))

                # tep 2: Handle OTP Verification
                elif action == "verify":
                    otp_check_id = request.form.get("otpCheckId","SAI")
                    otp_code = request.form.get("otpCode","K")

                    if not otp_check_id or not otp_code:
                        return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                    return jsonify(verify_otp_helper(otp_check_id, otp_code))

                elif action == "update":
                    otp_check_id = request.form.get("otpCheckId", "")
                    otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                    admin_id = request.form.get("adminId", "")

                    otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
                   
                    if not otpcheck_queryset:
                        return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                    # Update OTP status to 2 after verification
                    otpcheck_queryset.update(status=2)
                    return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

                

                name = request.form.get("name","")
                rank = request.form.get("rank")
                description = request.form.get("description","")
                userPermissionId = request.form.get("userPermissionId","")
                code = request.form.get("code","")
                isUserWise = request.form.get("isUserWise")
                isAllow = request.form.get("isAllow")
                isCommission = request.form.get("isCommission")
                isSuperDistributor = request.form.get("isSuperDistributor")
                payoutPaymentGatewayId = request.form.get("payoutPaymentGatewayId")
                payinPaymentGatewaysList = request.form.getlist("payinPaymentGatewaysList")
                payinEnable = request.form.get("payinEnable")
                payoutEnable = request.form.get("payoutEnable")
                defaultProfile = request.form.get("defaultProfile")
                defaultPayinPaymentGatewayId = request.form.get("defaultPayinPaymentGatewayId")
                # defaultPayoutPaymentGatewayId = request.form.get("defaultPayoutPaymentGatewayId")
                jsonData = request.form.to_dict(flat=True)
                remark = request.form.get("remark","")

                if name and rank and description and code and userPermissionId:
                    pattern_queryset = Patterns.objects(id=patternId,status__in=[0,1]).first()
                    existing_record = pattern_queryset.to_json()
                    message=pattern_queryset.adminId.userName+" "+name+" Profile updated successfully!"
                    requestData=[existing_record]
                    updatedrequestData=[jsonData]
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_pattern","update",actionDate,client_ip,browser,message,requestData,updatedrequestData)
                    save_remarks_data=save_admin_remarks_data(patternId,adminId,remark,"Profile") 

                    if pattern_queryset:
                        if isUserWise == "True":
                            isUserWiseval=True
                        else:
                            isUserWiseval=False

                        if isAllow == "True":
                            isAllowval=True
                        else:
                            isAllowval=False

                        if isCommission == "True":
                            isCommissionval=True
                        else:
                            isCommissionval=False

                        if isSuperDistributor == "True":
                            isSuperDistributorval=True
                        else:
                            isSuperDistributorval=False

                        if payinEnable == "True":
                            payinEnable=True
                            defaultPayinPaymentGatewayId=ObjectId(defaultPayinPaymentGatewayId)
                        else:
                            payinEnable=False
                            defaultPayinPaymentGatewayId=None

                        if payoutEnable == "True":
                            payoutEnable=True
                            payoutPaymentGatewayId=ObjectId(payoutPaymentGatewayId)
                        else:
                            payoutEnable=False
                            payoutPaymentGatewayId=None

                        if defaultProfile == "True":
                            defaultProfile=True
                            profiles_queryset = Patterns.objects(status__in=[0,1])
                            profiles_queryset.update(defaultProfile=False)
                        else:
                            defaultProfile=False

                        pattern_queryset.update(
                            name = name,
                            rank = rank,
                            description = description,
                            isUserWise = isUserWiseval,
                            isAllow = isAllowval,
                            isCommission = isCommissionval,
                            isSuperDistributor = isSuperDistributorval,
                            userPermissionId = ObjectId(userPermissionId),
                            payinEnable = payinEnable,
                            payoutEnable = payoutEnable,
                            defaultProfile = defaultProfile,
                            payoutPaymentGatewayId = payoutPaymentGatewayId,
                            defaultPayinPaymentGatewayId = defaultPayinPaymentGatewayId,
                            code = code
                            )
                        if payinPaymentGatewaysList:
                            pattern_queryset.update(payinPaymentGatewaysList=[ObjectId(each_payin_pg) for each_payin_pg in payinPaymentGatewaysList])

                        flash("Pattern updated successfully!")
                        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
                    else:
                        flash("Invaild id!!")
                        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
                else:
                    flash("Required fields are missing!!")
                    return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to update pattern details!!"
            flash(error)
            return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
    else:
        flash("Staff member does not have given update pattern permissions!!")
        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))

@patterns_configuarations.route("/get_patterns_configuarations_list",methods=["POST","GET"])
def get_patterns_configuarations_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    patternsList = []
    userpermissionsList =[]
    transactionAPIsList =[]
    payinEnableList =[]
    payoutEnableList =[]

    
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"),"patternPermissions")
    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo","Pattern")
            if redirectTo:
                redirectval = redirectTo
            else:
                redirectval = "Pattern"
            search_element = request.form.get("search_element","")

            patterns_queryset = Patterns.objects(status__in=[0,1]).order_by("-id")
            if search_element:
                patterns_queryset = patterns_queryset.filter(Q(name__icontains=search_element))

            for each_pattern in patterns_queryset:
               pattern_dict = fetching_pattern_details(each_pattern)
               patternsList.append(pattern_dict)

            user_permissions_queryset = UserPermissions.objects(status__in=[0,1]).order_by("-id")
            for each_user_permission in user_permissions_queryset:
                permission_dict = {
                "id":str(each_user_permission.id),
                "permissionName":each_user_permission.permissionName
                }
                userpermissionsList.append(permission_dict)

            transaction_API_queryset = TransactionAPI.objects(status=1).order_by('-id').all()
            for each_transaction_api in transaction_API_queryset:
                transactionapiDict = {
                "id":str(each_transaction_api.id),
                "apiName":each_transaction_api.apiName,
                "transactionType":each_transaction_api.transactionType
                }
                transactionAPIsList.append(transactionapiDict)

            payout_enable_queryset = TransactionAPI.objects(transactionType="Payout",status=1).order_by('-id')
            for each_payout_enable in payout_enable_queryset:
                payoutDict = fetching_transaction_api_details(each_payout_enable)
                payoutEnableList.append(payoutDict)

            payin_enable_queryset = TransactionAPI.objects(transactionType="PaymentGateway",status=1).order_by('-id')
            for each_payin_enable in payin_enable_queryset:
                payinDict = fetching_transaction_api_details(each_payin_enable)
                payinEnableList.append(payinDict)


            return render_template("super_admin_templates/patterns_configuarations_list.html",
                userpermissionsList=userpermissionsList,
                patternsList=patternsList,
                transactionAPIsList=transactionAPIsList,
                payinEnableList=payinEnableList,
                payoutEnableList=payoutEnableList,
                redirectval=redirectval,
                search_element=search_element
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch patterns details!!"
            return render_template("super_admin_templates/patterns_configuarations_list.html", 
                error=error,
                userpermissionsList=userpermissionsList,
                patternsList=patternsList,
                transactionAPIsList=transactionAPIsList,
                payinEnableList=payinEnableList,
                payoutEnableList=payoutEnableList,
                search_element=search_element
                )
    else:
        flash("Staff member does not have given view pattern permissions!!")
        return render_template("super_admin_templates/patterns_configuarations_list.html")

@patterns_configuarations.route("/update_pattern_status",methods=["POST","GET"])
def update_pattern_status():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()

    jsonData = request.form.to_dict(flat=True)

    existing_record = ""
    updatedrequestData = [jsonData]
    remark = request.form.get("remark","")

    permissionsList = check_permissions(session.get("adminId"),"patternPermissions")
    if "edit" in permissionsList:
        patternId = request.args.get("patternId","")

        if patternId:
            try:
                pattern_queryset = Patterns.objects(id=patternId,status__in=[0,1]).first()
                existing_record = pattern_queryset.to_json()
                requestData = [existing_record]
                if pattern_queryset:
                    if pattern_queryset.status == 0:
                        pattern_queryset.update(status=1)
                        flash("Pattern activated successfully!")
                        message=pattern_queryset.adminId.userName+" "+pattern_queryset.name+" Pattern activated successfully!"
                    elif pattern_queryset.status == 1:
                        pattern_queryset.update(status=0)
                        flash("Pattern deactivated successfully!")
                        message=pattern_queryset.adminId.userName+" "+pattern_queryset.name+" Pattern deactivated successfully!"
                    save_remarks_data=save_admin_remarks_data(patternId,adminId,remark,"Pattern Status")
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_pattern_status","updatestatus",actionDate,client_ip,browser,message,requestData,updatedrequestData)
                    return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
                else:
                    flash("Invaild id!!")
                    return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
            except Exception as e:
                app.logger.error(traceback.format_exc())
                return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
        else:
            flash("Required field is missing!!")
            return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))
    else:
        flash("Staff member does not have given status update pattern permissions!!")
        return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Pattern"))

############### Setup Charge Commissions ################

@patterns_configuarations.route("/add_setup_charge_commission",methods=["POST","GET"])
def add_setup_charge_commission():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        loginBrowser = request.headers.get("Sec-Ch-Ua")
        if loginBrowser:
            loginBrowseData = loginBrowser.split(";")
            browser = loginBrowseData[0]
        else:
            loginBrowseData = request.headers.get('User-Agent').split(";")
            browser = loginBrowseData[0]

        client_ip=0
        # Extracting client IP address
        if request.headers.getlist("X-Forwarded-For"): 
            client_ip = request.headers.getlist("X-Forwarded-For")[0]
        else:
            client_ip = request.remote_addr

        actionDate=datetime.datetime.now()
        
        permissionsList = check_permissions(session.get("adminId"),"chargeCommissionsPermissions")
        if "add" in permissionsList:
            adminId = session.get("adminId")
            if request.method == "POST":
                slabName = request.form.get("slabName","")
                patternId = request.form.get("patternId","")
                paymentModeId = request.form.get("paymentModeId","")
                subPaymentModeId = request.form.get("subPaymentModeId","")
                transactionAPIId = request.form.get("transactionAPIId","")
                priceType = request.form.get("priceType","")
                aggregatorType = request.form.get("aggregatorType","")
                aggregatorValue = request.form.get("aggregatorValue",0)
                gstInclude = request.form.get("gstInclude","")
                gstValue = request.form.get("gstValue",0)
                tdsInclude = request.form.get("tdsInclude","")
                tdsValue = request.form.get("tdsValue",0)
                commissionType = request.form.get("commissionType","")
                commissionValue = request.form.get("commissionValue",0)
                chargeType = request.form.get("chargeType","")
                chargeValue = request.form.get("chargeValue",0)
                # Fetching lists from the form
                startAmountListField = request.form.getlist("startAmount[]")
                endAmountListField = request.form.getlist("endAmount[]")
                aggregatorTypeListField = request.form.getlist("aggregatorType[]")
                aggregatorValueListField = request.form.getlist("aggregatorValue[]")
                chargeTypeListField = request.form.getlist("chargeType[]")
                chargeValueListField = request.form.getlist("chargeValue[]")
                subPaymentModeIdsList = request.form.getlist("subPaymentModeIdsList")
                paymentModeIdsList = request.form.getlist("paymentModeIdsList")
                # patternIdsList = request.form.getlist("patternIdsList")
                transactionAPIIdsList = request.form.getlist("transactionAPIIdsList")
                # commissionTypeListField = request.form.getlist("commissionType[]")
                # commissionValueListField = request.form.getlist("commissionValue[]")
                jsonData = request.form.to_dict(flat=True)
                requestData = [jsonData]
                updatedrequestData = [jsonData]

                print(request.form, "((((((((((SLAB REQUEST FORM))))))))))")

                def try_float(value):
                    try:
                        return float(value)
                    except ValueError:
                        return None

                # Check if all lists have the same length
                if len(startAmountListField) == len(endAmountListField) == len(aggregatorTypeListField) == len(aggregatorValueListField) == len(chargeTypeListField) == len(chargeValueListField):
                    priceRangeList = [
                        {
                            'startAmount': try_float(startAmount),
                            'endAmount': try_float(endAmount),
                            'aggregatorType': aggregatorType,
                            'aggregatorValue': try_float(aggregatorValue),
                            'chargeType': chargeType,
                            'chargeValue': try_float(chargeValue)
                        }
                        for startAmount, endAmount, aggregatorType, aggregatorValue, chargeType, chargeValue in zip(
                            startAmountListField, endAmountListField, aggregatorTypeListField, aggregatorValueListField, chargeTypeListField, chargeValueListField
                        )
                        if try_float(startAmount) is not None and try_float(endAmount) is not None and try_float(aggregatorValue) is not None and try_float(chargeValue) is not None
                    ]
                else:
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list"))


                print(priceRangeList, "((((((((priceRangeList))))))))")

                        
                if slabName and patternId and paymentModeIdsList and subPaymentModeIdsList and transactionAPIIdsList:
                    try:
                        admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                        if admin_queryset:
                            message=admin_queryset.userName+" "+slabName+" Setup charge commission created successfully!"
                            save_admin_log_table = save_admin_logs_data(adminId,None,None,"add_setup_charge_commission","create",actionDate,client_ip,browser,message,requestData,updatedrequestData) 

                        setup_charge_commissions_table = SetupChargeCommissions(
                            adminId=adminId,
                            slabName = slabName,
                            # patternId = patternId,
                            # paymentModeId = paymentModeId,
                            # subPaymentModeId = subPaymentModeId,
                            # transactionAPIId = transactionAPIId,
                            priceType = priceType,
                            aggregatorType = aggregatorType,
                            aggregatorValue = aggregatorValue,
                            gstInclude = gstInclude,
                            gstValue = gstValue,
                            tdsInclude = tdsInclude,
                            tdsValue = tdsValue,
                            commissionType = "",
                            commissionValue = 0,
                            chargeType = chargeType,
                            chargeValue = chargeValue,
                            priceRangeList = priceRangeList,
                            subPaymentModeIdsList = subPaymentModeIdsList,
                            paymentModeIdsList = paymentModeIdsList,
                            patternIdsList = [patternId],
                            transactionAPIIdsList = transactionAPIIdsList,
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            )
                        save_table = setup_charge_commissions_table.save()

                        flash("Setup charge commission saved successfully!")
                        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
                    except Exception as e:
                        flash("Unable to save setup charge commission details!!")
                        app.logger.error(traceback.format_exc())
                        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
                else:
                    flash("Required fields are missing!!")
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
        else:
            flash("Staff member does not have given create setup charge commissions permissions!!")
            return redirect(url_for("patterns_configuarations.get_patterns_configuarations_list",redirectTo="Commission"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to save setup charge commission details!!"
        return render_template("super_admin_templates/setup_charge_commissions_list.html",error=error,redirectTo="Commission")

def fetching_setup_charge_commission_details(setup_charge_commission_queryset):
    setup_charge_commission_dict = {}
    try:
        setup_charge_commission_dict={
        "id":str(setup_charge_commission_queryset.id),
        # "patternId":str(setup_charge_commission_queryset.patternId.id),
        # "patternName":setup_charge_commission_queryset.patternId.name,
        # "paymentModeId":str(setup_charge_commission_queryset.paymentModeId.id),
        # "paymentModeName":setup_charge_commission_queryset.paymentModeId.paymentMode,
        # "subPaymentModeId":str(setup_charge_commission_queryset.subPaymentModeId.id),
        # "subPaymentModeName":setup_charge_commission_queryset.subPaymentModeId.subPaymentModeType,
        # "transactionAPIId":str(setup_charge_commission_queryset.transactionAPIId.id),
        # "transactionAPIName":setup_charge_commission_queryset.transactionAPIId.apiName,
        "slabName":setup_charge_commission_queryset.slabName,
        "priceType":setup_charge_commission_queryset.priceType,
        # "startAmount":"{:.2f}".format(float(setup_charge_commission_queryset.startAmount)),
        # "endAmount":"{:.2f}".format(float(setup_charge_commission_queryset.endAmount)),
        "aggregatorType":setup_charge_commission_queryset.aggregatorType,
        # "aggregatorValue":"{:.2f}".format(float(setup_charge_commission_queryset.aggregatorValue)),
        "gstInclude":setup_charge_commission_queryset.gstInclude,
        "gstValue":setup_charge_commission_queryset.gstValue,
        "tdsInclude":setup_charge_commission_queryset.tdsInclude,
        "tdsValue":setup_charge_commission_queryset.tdsValue,
        "commissionType":setup_charge_commission_queryset.commissionType,
        "commissionValue":setup_charge_commission_queryset.commissionValue,
        "chargeType":setup_charge_commission_queryset.chargeType,
        # "chargeValue":"{:.2f}".format(float(setup_charge_commission_queryset.chargeValue)),
        "priceRangeList":setup_charge_commission_queryset.priceRangeList
        }
        if setup_charge_commission_queryset.status==1:
            setup_charge_commission_dict["actionText"] = "Active"
        else:
            setup_charge_commission_dict["actionText"] = "Deactive"

        if setup_charge_commission_queryset.aggregatorValue:
            setup_charge_commission_dict["aggregatorValue"] = "{:.2f}".format(float(setup_charge_commission_queryset.aggregatorValue))
        else:
            setup_charge_commission_dict["aggregatorValue"] = ""

        if setup_charge_commission_queryset.chargeValue:
            setup_charge_commission_dict["chargeValue"] = "{:.2f}".format(float(setup_charge_commission_queryset.chargeValue))
        else:
            setup_charge_commission_dict["chargeValue"] = ""

        if setup_charge_commission_queryset.transactionAPIIdsList:
            setup_charge_commission_dict["transactionAPIIdsList"]=[str(each_api.id) for each_api in setup_charge_commission_queryset.transactionAPIIdsList]
            setup_charge_commission_dict["apiNamesList"]=[str(each_api.apiName) for each_api in setup_charge_commission_queryset.transactionAPIIdsList]

            setup_charge_commission_dict["apiNames"] = ', '.join(setup_charge_commission_dict["apiNamesList"])
            # print(setup_charge_commission_dict["apiNames"],"(((((((((?????????????)))))))))")
        else:
            setup_charge_commission_dict["transactionAPIIdsList"]=[]
            setup_charge_commission_dict["apiNames"]=""

        if setup_charge_commission_queryset.patternIdsList:
            setup_charge_commission_dict["patternIdsList"]=[str(each_pattern.id) for each_pattern in setup_charge_commission_queryset.patternIdsList]

            setup_charge_commission_dict["patternNamesList"]=[str(each_pattern.name) for each_pattern in setup_charge_commission_queryset.patternIdsList]

            setup_charge_commission_dict["patternNames"] = ', '.join(setup_charge_commission_dict["patternNamesList"])

        else:
            setup_charge_commission_dict["patternIdsList"]=[]
            setup_charge_commission_dict["patternNames"]=""

        if setup_charge_commission_queryset.paymentModeIdsList:
            setup_charge_commission_dict["paymentModeIdsList"]=[str(each_paymentMode.id) for each_paymentMode in setup_charge_commission_queryset.paymentModeIdsList]

            setup_charge_commission_dict["paymentModeNamesList"]=[str(each_paymentMode.paymentMode) for each_paymentMode in setup_charge_commission_queryset.paymentModeIdsList]

            setup_charge_commission_dict["paymentModeNames"] = ', '.join(setup_charge_commission_dict["paymentModeNamesList"])

        else:
            setup_charge_commission_dict["paymentModeIdsList"]=[]
            setup_charge_commission_dict["paymentModeNames"]=""

        if setup_charge_commission_queryset.subPaymentModeIdsList:
            setup_charge_commission_dict["subPaymentModeIdsList"]=[str(each_subpaymentMode.id) for each_subpaymentMode in setup_charge_commission_queryset.subPaymentModeIdsList]

            setup_charge_commission_dict["subpaymentModeNamesList"]=[str(each_subpaymentMode.subPaymentModeType) for each_subpaymentMode in setup_charge_commission_queryset.subPaymentModeIdsList]

            setup_charge_commission_dict["subpaymentModeNames"] = ', '.join(setup_charge_commission_dict["subpaymentModeNamesList"])
        else:
            setup_charge_commission_dict["subPaymentModeIdsList"]=[]
            setup_charge_commission_dict["subpaymentModeNames"]=""

        if setup_charge_commission_queryset.createdOn:
            setup_charge_commission_dict["createdOn"] = setup_charge_commission_queryset.createdOn.strftime("%d-%m-%Y")
        else:
            setup_charge_commission_queryset["createdOn"] = ""
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return setup_charge_commission_dict

@patterns_configuarations.route("/update_setup_charge_commission",methods=["POST","GET"])
def update_setup_charge_commission():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")   
     
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    existing_record = ""
    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()

    permissionsList = check_permissions(session.get("adminId"),"chargeCommissionsPermissions")
    if "edit" in permissionsList:
        try:
            transactionAPIsList = []
            patternsList = []
            paymentsModeList = []
            subPaymentsModeList = []

            commissionId = request.args.get("commissionId","")
            if request.method == "GET":
                setup_charge_commission_queryset = SetupChargeCommissions.objects(id=commissionId).first()
                if not setup_charge_commission_queryset:
                    flash("Invaild commission id!!")
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list"))

                ######################## Common Lists ###########################
                transaction_API_queryset = TransactionAPI.objects(status__in=[0,1]).order_by('-id').all()
                for each_transaction_api in transaction_API_queryset:
                    service_grouping_dict = {
                    "id":str(each_transaction_api.id),
                    "apiName":each_transaction_api.apiName
                    }
                    transactionAPIsList.append(service_grouping_dict)

                patterns_queryset = Patterns.objects(status__in=[0,1]).order_by("-id").all()
                for each_pattern in patterns_queryset:
                    pattern_dict = fetching_pattern_details(each_pattern)
                    patternsList.append(pattern_dict)


                payments_mod_queryset = PaymentMode.objects(status__in=[0,1]).order_by("-id").all()
                for each_payment_mode in payments_mod_queryset:
                    payment_mode_data = fetching_payment_mode_details(each_payment_mode)
                    paymentsModeList.append(payment_mode_data)


                sub_payments_mod_queryset = SubPaymentModes.objects(status__in=[0,1],paymentModeId__in=setup_charge_commission_queryset.paymentModeIdsList).order_by("-id").all()
                for each_sub_payment_mode in sub_payments_mod_queryset:
                    sub_payment_mode_data = fetching_sub_payment_mode_details(each_sub_payment_mode)
                    subPaymentsModeList.append(sub_payment_mode_data)

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

                setup_charge_commission_dict = fetching_setup_charge_commission_details(setup_charge_commission_queryset)

                return render_template("super_admin_templates/update_setup_charge_commission.html",
                    setup_charge_commission_dict=setup_charge_commission_dict,
                    subPaymentsModeList=subPaymentsModeList,
                    transactionAPIsList=transactionAPIsList,
                    patternsList=patternsList,
                    paymentsModeList=paymentsModeList
                    )

            if request.method == "POST":
                action = request.form.get("action", "HI").strip()
                data = request.form.to_dict()
                # Step 1: Handle OTP Generation
                if action == "generate":
                    mail_type = data.get("mailType", "").strip()
                    print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                    if not mail_type:
                        return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                    return jsonify(generate_otp_helper(mail_type))

                # tep 2: Handle OTP Verification
                elif action == "verify":
                    otp_check_id = request.form.get("otpCheckId","SAI")
                    otp_code = request.form.get("otpCode","K")

                    print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                    print(otp_code,"((((((((OTP CODE????????????))))))))")

                    if not otp_check_id or not otp_code:
                        return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                    return jsonify(verify_otp_helper(otp_check_id, otp_code))

                elif action == "update":
                    otp_check_id = request.form.get("otpCheckId", "")
                    otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                    admin_id = request.form.get("adminId", "")

                    otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
                   
                    if not otpcheck_queryset:
                        return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                    # Update OTP status to 2 after verification
                    otpcheck_queryset.update(status=2)
                    return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

                slabName = request.form.get("slabName","")
                patternId = request.form.get("patternId","")
                paymentModeId = request.form.get("paymentModeId","")
                subPaymentModeId = request.form.get("subPaymentModeId","")
                transactionAPIId = request.form.get("transactionAPIId","")
                priceType = request.form.get("priceType","")
                aggregatorType = request.form.get("aggregatorType","")
                aggregatorValue = request.form.get("aggregatorValue",0)
                gstInclude = request.form.get("gstInclude","")
                gstValue = request.form.get("gstValue")
                tdsInclude = request.form.get("tdsInclude","")
                tdsValue = request.form.get("tdsValue",0)
                # commissionType = request.form.get("commissionType")
                # commissionValue = request.form.get("commissionValue",0)
                chargeType = request.form.get("chargeType")
                chargeValue = request.form.get("chargeValue",0)

                # Fetching lists from the form
                startAmountListField = request.form.getlist("startAmount[]")
                endAmountListField = request.form.getlist("endAmount[]")
                aggregatorTypeListField = request.form.getlist("aggregatorType[]")
                aggregatorValueListField = request.form.getlist("aggregatorValue[]")
                chargeTypeListField = request.form.getlist("chargeType[]")
                chargeValueListField = request.form.getlist("chargeValue[]")
                # commissionTypeListField = request.form.getlist("commissionType[]")
                # commissionValueListField = request.form.getlist("commissionValue[]")
                jsonData = request.form.to_dict(flat=True)
                remark = request.form.get("remark","")
                subPaymentModeIdsList = request.form.getlist("subPaymentModeIdsList")
                paymentModeIdsList = request.form.getlist("paymentModeIdsList")
                transactionAPIIdsList = request.form.getlist("transactionAPIIdsList")

                print(request.form, "((((((((((SLAB REQUEST FORM))))))))))")

                def try_float(value):
                    try:
                        return float(value)
                    except ValueError:
                        return None

                # Check if all lists have the same length
                if len(startAmountListField) == len(endAmountListField) == len(aggregatorTypeListField) == len(aggregatorValueListField) == len(chargeTypeListField) == len(chargeValueListField):
                    priceRangeList = [
                        {
                            'startAmount': try_float(startAmount),
                            'endAmount': try_float(endAmount),
                            'aggregatorType': aggregatorType,
                            'aggregatorValue': try_float(aggregatorValue),
                            'chargeType': chargeType,
                            'chargeValue': try_float(chargeValue)
                        }
                        for startAmount, endAmount, aggregatorType, aggregatorValue, chargeType, chargeValue in zip(
                            startAmountListField, endAmountListField, aggregatorTypeListField, aggregatorValueListField, chargeTypeListField, chargeValueListField
                        )
                        if try_float(startAmount) is not None and try_float(endAmount) is not None and try_float(aggregatorValue) is not None and try_float(chargeValue) is not None
                    ]
                else:
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list"))


                print(priceRangeList, "((((((((priceRangeList))))))))")


                if commissionId and slabName and patternId and paymentModeIdsList and subPaymentModeIdsList and transactionAPIIdsList:
                    setup_charge_commission_queryset = SetupChargeCommissions.objects(id=commissionId,status__in=[0,1]).first()
                    existing_record = setup_charge_commission_queryset.to_json()
                    message=setup_charge_commission_queryset.adminId.userName+" "+slabName+" Setup charge commission updated successfully!"
                    requestData=[existing_record]
                    updatedrequestData=[jsonData]
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_setup_charge_commission","update",actionDate,client_ip,browser,message,requestData,updatedrequestData)
                    save_remarks_data=save_admin_remarks_data(commissionId,adminId,remark,"commission")

                    if setup_charge_commission_queryset:
                        if priceType == "RANGE":
                            setup_charge_commission_queryset.update(
                                slabName = slabName,
                                # patternId = ObjectId(patternId),
                                # paymentModeId = ObjectId(paymentModeId),
                                # subPaymentModeId = ObjectId(subPaymentModeId),
                                # transactionAPIId = ObjectId(transactionAPIId),
                                priceType = priceType,
                                gstInclude = gstInclude,
                                gstValue = gstValue,
                                tdsInclude = tdsInclude,
                                tdsValue = tdsValue,
                                subPaymentModeIdsList = [ObjectId(each_sub_payment_mode) for each_sub_payment_mode in subPaymentModeIdsList],
                                paymentModeIdsList = [ObjectId(each_payment_mode) for each_payment_mode in paymentModeIdsList],
                                patternIdsList = [ObjectId(patternId)],
                                transactionAPIIdsList = [ObjectId(each_api) for each_api in transactionAPIIdsList]
                                )
                            if priceRangeList:
                                # existing_price_ranges_list = setup_charge_commission_queryset.priceRangeList or []
                                # print(existing_price_ranges_list,"Before Extend existing_price_ranges_list")
                                # existing_price_ranges_list.extend(priceRangeList)
                                # print(existing_price_ranges_list,"(((((((((((((existing_price_ranges_list)))))))))))))")
                                setup_charge_commission_queryset.update(priceRangeList=priceRangeList)
                        else:
                            setup_charge_commission_queryset.update(
                                slabName = slabName,
                                # patternId = ObjectId(patternId),
                                # paymentModeId = ObjectId(paymentModeId),
                                # subPaymentModeId = ObjectId(subPaymentModeId),
                                # transactionAPIId = ObjectId(transactionAPIId),
                                priceType = priceType,
                                aggregatorType = aggregatorType,
                                aggregatorValue = aggregatorValue,
                                gstInclude = gstInclude,
                                gstValue = gstValue,
                                tdsInclude = tdsInclude,
                                tdsValue = tdsValue,
                                commissionType = "",
                                commissionValue = 0,
                                chargeType = chargeType,
                                chargeValue = chargeValue,
                                priceRangeList = [],
                                subPaymentModeIdsList = [ObjectId(each_sub_payment_mode) for each_sub_payment_mode in subPaymentModeIdsList],
                                paymentModeIdsList = [ObjectId(each_payment_mode) for each_payment_mode in paymentModeIdsList],
                                patternIdsList = [ObjectId(patternId)],
                                transactionAPIIdsList = [ObjectId(each_api) for each_api in transactionAPIIdsList]
                                )
                        flash("Setup charge commission updated successfully!")
                        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
                    else:
                        flash("Invaild id!!")
                        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
                else:
                    flash("Required fields are missing!!")
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to update setup charge commission details!!"
            flash(error)
            return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
    else:
        flash("Staff member does not have given update setup charge commissions permissions!!")
        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))

@patterns_configuarations.route("/get_setup_charge_commissions_list",methods=["POST","GET"])
def get_setup_charge_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    commissionsList = []
    transactionAPIsList = []
    patternsList = []
    paymentsModeList = []
    subPaymentsModeList = []
    
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"),"chargeCommissionsPermissions")
    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo","Commission")
            if redirectTo:
                redirectval = redirectTo
            else:
                redirectval = "Commission"
            search_element = request.form.get("search_element","")

            ######################## Common Lists ###########################
            transaction_API_queryset = TransactionAPI.objects(status__in=[0,1]).order_by('-id').all()
            for each_transaction_api in transaction_API_queryset:
                service_grouping_dict = {
                "id":str(each_transaction_api.id),
                "apiName":each_transaction_api.apiName
                }
                transactionAPIsList.append(service_grouping_dict)

            patterns_queryset = Patterns.objects(status__in=[0,1]).order_by("-id").all()
            for each_pattern in patterns_queryset:
                pattern_dict = fetching_pattern_details(each_pattern)
                patternsList.append(pattern_dict)


            payments_mod_queryset = PaymentMode.objects(status__in=[0,1]).order_by("-id").all()
            for each_payment_mode in payments_mod_queryset:
                payment_mode_data = fetching_payment_mode_details(each_payment_mode)
                paymentsModeList.append(payment_mode_data)


            sub_payments_mod_queryset = SubPaymentModes.objects(status__in=[0,1]).order_by("-id").all()
            for each_sub_payment_mode in sub_payments_mod_queryset:
                sub_payment_mode_data = fetching_sub_payment_mode_details(each_sub_payment_mode)
                subPaymentsModeList.append(sub_payment_mode_data)

            
            setup_charge_commissions_queryset = SetupChargeCommissions.objects(status__in=[0,1]).order_by("-id")
            if search_element:
                setup_charge_commissions_queryset = setup_charge_commissions_queryset.filter(Q(slabName__icontains=search_element))

            for each_setup_charge_commission in setup_charge_commissions_queryset:
                setup_charge_commission_dict = fetching_setup_charge_commission_details(each_setup_charge_commission)
                commissionsList.append(setup_charge_commission_dict)
            
            return render_template("super_admin_templates/setup_charge_commissions_list.html",
                commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                transactionAPIsList=transactionAPIsList,
                redirectval=redirectval,
                search_element=search_element
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch setup charge commission details!!"
            return render_template("super_admin_templates/setup_charge_commissions_list.html", 
                error=error,
                commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                transactionAPIsList=transactionAPIsList,
                search_element=search_element
                )
    else:
        flash("Staff member does not have given view setup charge commissions permissions!!")
        return render_template("super_admin_templates/setup_charge_commissions_list.html")

@patterns_configuarations.route("/update_setup_charge_commission_status",methods=["POST","GET"])
def update_setup_charge_commission_status():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()

    jsonData = request.form.to_dict(flat=True)

    existing_record = ""
    updatedrequestData = [jsonData]
    remark = request.form.get("remark","")

    permissionsList = check_permissions(session.get("adminId"),"chargeCommissionsPermissions")
    if "edit" in permissionsList:
        commissionId = request.args.get("commissionId","")

        if commissionId:
            try:
                setup_charge_commission_queryset = SetupChargeCommissions.objects(id=commissionId,status__in=[0,1]).first()
                existing_record = setup_charge_commission_queryset.to_json()
                requestData = [existing_record]
                if setup_charge_commission_queryset:
                    if setup_charge_commission_queryset.status == 0:
                        setup_charge_commission_queryset.update(status=1)
                        flash("Setup charge commission activated successfully!")
                        message=setup_charge_commission_queryset.adminId.userName+" "+setup_charge_commission_queryset.slabName+" Setup charge commission activated successfully!"
                    elif setup_charge_commission_queryset.status == 1:
                        setup_charge_commission_queryset.update(status=0)
                        flash("Setup charge commission deactivated successfully!")
                        message=setup_charge_commission_queryset.adminId.userName+" "+setup_charge_commission_queryset.slabName+" Setup charge commission deactivated successfully!"
                    save_remarks_data=save_admin_remarks_data(commissionId,adminId,remark,"commission")
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_setup_charge_commission_status","updatestatus",actionDate,client_ip,browser,message,requestData,updatedrequestData)     
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
                else:
                    flash("Invaild id!!")
                    return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
            except Exception as e:
                app.logger.error(traceback.format_exc())
                return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
        else:
            flash("Required field is missing!!")
            return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))
    else:
        flash("Staff member does not have given status update setup charge commissions permissions!!")
        return redirect(url_for("patterns_configuarations.get_setup_charge_commissions_list",redirectTo="Commission"))



@patterns_configuarations.route("/sub_payment_based_payment_modes_list", methods=["POST"])
def sub_payment_based_payment_modes_list():
    data_status = {"responseStatus": 0, "result": ""}
    # Get paymentModeIdsList as a string, then split if necessary
    paymentModeIdsList = request.form.getlist("paymentModeIdsList[]")
    
    # If it's a single string with comma-separated ObjectIds, split it
    if isinstance(paymentModeIdsList, str):
        paymentModeIdsList = paymentModeIdsList.split(",")
    
    print(paymentModeIdsList, "((((((((((paymentModeIdsList))))))))))")
    
    # If the list is empty, return an error
    if not paymentModeIdsList:
        data_status["result"] = "Required fields are missing!!"
        return data_status

    try:
        payment_mod_queryset = PaymentMode.objects(id__in=paymentModeIdsList, status__in=[0, 1])
        paymentModesList = [str(each_payment_mode.id) for each_payment_mode in payment_mod_queryset]
        print(paymentModesList, "paymentModesList")

        subPaymentsModeList = []
        sub_payments_mod_queryset = SubPaymentModes.objects(
            paymentModeId__in=paymentModesList, status__in=[0, 1]
        ).order_by("-id").all()

        for each_sub_payment_mode in sub_payments_mod_queryset:
            subPaymentsModeDict = fetching_sub_payment_mode_details(each_sub_payment_mode)
            subPaymentsModeList.append(subPaymentsModeDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "PaymentMode based sub payments data fetched successfully!"
        data_status["subPaymentsModeList"] = subPaymentsModeList
        return data_status
    
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch sub payments data!!"
        return data_status

# @patterns_configuarations.route("/sub_payment_based_payment_modes_list", methods=["POST"])
# def sub_payment_based_payment_modes_list():
#     data_status = {"responseStatus": 0, "result": ""}
#     # Get paymentModeIdsList as a string, then split if necessary
#     paymentModeIdsList = request.form.getlist("paymentModeIdsList[]")
    
#     # If it's a single string with comma-separated ObjectIds, split it
#     if isinstance(paymentModeIdsList, str):
#         paymentModeIdsList = paymentModeIdsList.split(",")
    
#     print(paymentModeIdsList, "((((((((((paymentModeIdsList))))))))))")
    
#     # If the list is empty, return an error
#     if not paymentModeIdsList:
#         data_status["result"] = "Required fields are missing!!"
#         return data_status

#     try:
#         payment_mod_queryset = PaymentMode.objects(id__in=paymentModeIdsList, status__in=[0, 1])
#         paymentModesList = [str(each_payment_mode.id) for each_payment_mode in payment_mod_queryset]
#         print(paymentModesList, "paymentModesList")

#         subPaymentsModeList = []
#         sub_payments_mod_queryset = SubPaymentModes.objects(
#             paymentModeId__in=paymentModesList, status__in=[0, 1]
#         ).order_by("-id").all()

#         for each_sub_payment_mode in sub_payments_mod_queryset:
#             subPaymentsModeDict = {
#             "value":str(each_sub_payment_mode.id),
#             "label":str(each_sub_payment_mode.subPaymentModeType)
#             }
#             subPaymentsModeList.append(subPaymentsModeDict)

#         data_status["responseStatus"] = 1
#         data_status["result"] = "PaymentMode based sub payments data fetched successfully!"
#         data_status["subPaymentsModeList"] = subPaymentsModeList
#         return data_status
    
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "Unable to fetch sub payments data!!"
#         return data_status

@patterns_configuarations.route("/new_get_setup_charge_commissions_list", methods=["POST", "GET"])
def new_get_setup_charge_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    
    # Initialize lists
    commissionsList = []
    transactionAPIsList = []
    patternsList = []
    paymentsModeList = []
    subPaymentsModeList = []
    error = None
    success_message = None
    editable = False
    update = False

    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"), "chargeCommissionsPermissions")

    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo", "Commission")
            search_action = request.args.get("action")

            ######################## Common Lists ###########################
            transaction_API_queryset = TransactionAPI.objects(status__in=[0, 1]).order_by('-id').all()
            for each_transaction_api in transaction_API_queryset:
                service_grouping_dict = {
                    "id": str(each_transaction_api.id),
                    "apiName": each_transaction_api.apiName
                }
                transactionAPIsList.append(service_grouping_dict)

            patterns_queryset = Patterns.objects(status__in=[0, 1]).order_by("-id").all()
            for each_pattern in patterns_queryset:
                patternsList.append(fetching_pattern_details(each_pattern))

            payments_mod_queryset = PaymentMode.objects(status__in=[0, 1]).order_by("-id").all()
            for each_payment_mode in payments_mod_queryset:
                paymentsModeList.append(fetching_payment_mode_details(each_payment_mode))

            sub_payments_mod_queryset = SubPaymentModes.objects(status__in=[0, 1]).order_by("-id").all()
            for each_sub_payment_mode in sub_payments_mod_queryset:
                subPaymentsModeList.append(fetching_sub_payment_mode_details(each_sub_payment_mode))

            if request.method == "GET" and request.args.get("action") == "search":
                patternId = request.args.get("patternId")
                paymentModeId = request.args.get("paymentModeId")
                subPaymentModeId = request.args.get("subPaymentModeId")
                transactionAPIId = request.args.get("transactionAPIId")
                editable = True
                update = True

                # Search for matching records
                setup_charge_commission = SetupChargeCommissions.objects(
                    patternId=patternId,
                    paymentModeId=paymentModeId,
                    transactionAPIId=transactionAPIId,
                    status=1
                ).first()

                if setup_charge_commission:
                    print("charge type =",setup_charge_commission.chargeType)
                    print("++++++++++++++++++",setup_charge_commission["priceRangeList"],setup_charge_commission)
                    startAmountList, endAmountList, isUnlimitedList = [], [], []
                    aggregatorTypeListField, aggregatorValueListField = [], []
                    chargeTypeListField, chargeValueListField = [], []
                    if setup_charge_commission.priceType == 'RANGE':
                        price_ranges = setup_charge_commission.priceRangeList
                        
                        
                    else:
                        price_ranges = []

                    
                    flash("Matching record found! You can update it.", "success")
                    return render_template(
                        "super_admin_templates/new_setup_charge_commissions_list.html",
                        patternId=patternId,
                        recordId=setup_charge_commission.id,
                        paymentModeId=paymentModeId,
                        transactionAPIId=transactionAPIId,
                        subPaymentsModeList=subPaymentsModeList,
                        patternsList=patternsList,
                        paymentsModeList=paymentsModeList,
                        transactionAPIsList=transactionAPIsList,
                        editable=editable,
                        priceType=setup_charge_commission.priceType,
                        aggregatorType=setup_charge_commission.aggregatorType,
                        aggregatorValue=setup_charge_commission.aggregatorValue,
                        chargeType=setup_charge_commission.chargeType,
                        chargeValue=setup_charge_commission.chargeValue,
                        gstInclude=setup_charge_commission.gstInclude,
                        gstValue=setup_charge_commission.gstValue,
                        tdsInclude=setup_charge_commission.tdsInclude,
                        tdsValue=setup_charge_commission.tdsValue,
                        priceRangeList=price_ranges,
                        update= update
                    )
                else:
                    flash("No matching record found. Please add a new record.", "error")
                    return render_template("super_admin_templates/new_setup_charge_commissions_list.html",
                                        patternId=patternId,
                                        paymentModeId=paymentModeId,
                                        # subPaymentModeId=subPaymentModeId,
                                        transactionAPIId=transactionAPIId,
                                        subPaymentsModeList=subPaymentsModeList,
                                        patternsList=patternsList,
                                        paymentsModeList=paymentsModeList,
                                        transactionAPIsList=transactionAPIsList,
                                        editable=editable
                    )

            elif request.method == "POST" and request.form.get("action") == "submit":
                editable = True
                record_id = request.form.get("recordId")

                if record_id:  # Update existing record
                    existing_record = SetupChargeCommissions.objects.get(id=record_id)
                    existing_record.patternId = ObjectId(request.form.get("patternId"))
                    existing_record.paymentModeId = ObjectId(request.form.get("paymentModeId"))
                    existing_record.transactionAPIId = ObjectId(request.form.get("transactionAPIId"))
                    existing_record.priceType = request.form.get("priceType")
                    existing_record.aggregatorType = request.form.get("aggregatorType")
                    existing_record.chargeType = request.form.get("chargeType")

                    # Convert numeric fields to float
                    try:
                        existing_record.aggregatorValue = float(request.form.get("aggregatorValue", 0))
                        existing_record.chargeValue = float(request.form.get("chargeValue", 0))
                        existing_record.gstValue = float(request.form.get("gstValue", 0))
                        existing_record.tdsValue = float(request.form.get("tdsValue", 0))

                        if existing_record.priceType == 'RANGE':
                            startAmountListField = request.form.getlist("startAmount[]")
                            endAmountListField = request.form.getlist("endAmount[]")
                            aggregatorTypeListField = request.form.getlist("aggregatorType[]")
                            aggregatorValueListField = request.form.getlist("aggregatorValue[]")
                            chargeTypeListField = request.form.getlist("chargeType[]")
                            chargeValueListField = request.form.getlist("chargeValue[]")
                            isUnlimited= request.form.getlist("isUnlimited")
                            print("uuuu___________________________________________", request.form.to_dict(),isUnlimited)

                            def try_float(value):
                                print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Trying to convert value: '{value}'")  # Print value being converted
                                if value.strip() == "":
                                    print("Empty string encountered.")
                                    return None
                                try:
                                    return float(value)
                                except ValueError:
                                    print(f"ValueError: Cannot convert '{value}' to float.")
                                    return None
                            
                            priceRangeList = []
                            print("startAmountListField++++",startAmountListField, "endAmountListField",endAmountListField,"aggregatorTypeListField",aggregatorTypeListField,"aggregatorValueListField",aggregatorValueListField,"chargeTypeListField",chargeTypeListField,"chargeValueListField",chargeValueListField,"isunlimited:::::",isUnlimited)

                            # Validate that all lists have the same length
                            if (len(startAmountListField) == len(endAmountListField) ==
                                len(aggregatorTypeListField) == len(aggregatorValueListField) ==
                                len(chargeTypeListField) == len(chargeValueListField)):
                                
                                isUnlimitedLastRow = isUnlimited[0] == 'on' if isUnlimited else False

                                for startAmount, endAmount, aggregatorType, aggregatorValue, chargeType, chargeValue in zip(
                                        startAmountListField, endAmountListField, aggregatorTypeListField, aggregatorValueListField, 
                                        chargeTypeListField, chargeValueListField):
                                    
                                    startAmountFloat = try_float(startAmount)
                                    endAmountFloat = try_float(endAmount)
                                    aggregatorValueFloat = try_float(aggregatorValue)
                                    chargeValueFloat = try_float(chargeValue)



                                    print(f"CCCCCCCCCCCCCCCCCCCCCConverted Values - Start: {startAmountFloat}, End: {endAmountFloat}, "
                                        f"Aggregator: {aggregatorValueFloat}, Charge: {chargeValueFloat}, isunlimited: {isUnlimited}")

                                    if None not in (startAmountFloat, endAmountFloat, aggregatorValueFloat, chargeValueFloat):
                                        priceRangeList.append({
                                            'startAmount': startAmountFloat,
                                            'endAmount': endAmountFloat,
                                            'aggregatorType': aggregatorType,  # Adding this for clarity
                                            'aggregatorValue': aggregatorValueFloat,
                                            'chargeType': chargeType,           # Adding this for clarity
                                            'chargeValue': chargeValueFloat,
                                            'isUnlimited': isUnlimitedLastRow if endAmount == endAmountListField[-1] else False                                
                                            })
                                print("=====================================Final Price Range List:", priceRangeList)
                                existing_record.priceRangeList = priceRangeList
                            else:
                                flash("Mismatch in input lengths for price ranges.", "error")
                                return redirect(url_for("patterns_configuarations.new_get_setup_charge_commissions_list"))

                                # Assign the constructed price range list to the existing record
                    except ValueError:
                        flash("Invalid input for numeric fields.", "error")
                        return render_template("super_admin_templates/new_setup_charge_commissions_list.html")

                    existing_record.gstInclude = request.form.get("gstInclude")
                    existing_record.tdsInclude = request.form.get("tdsInclude")

                    

                    existing_record.save()
                    flash("Record updated successfully!", "success")
                    return render_template(
                        "super_admin_templates/new_setup_charge_commissions_list.html",
                        patternId=str(existing_record.patternId),
                        recordId=existing_record.id,
                        paymentModeId=str(existing_record.paymentModeId),
                        transactionAPIId=str(existing_record.transactionAPIId),
                        # subPaymentsModeList=subPaymentsModeList,
                        patternsList=patternsList,
                        paymentsModeList=paymentsModeList,
                        transactionAPIsList=transactionAPIsList,
                        editable=editable,
                        priceType=existing_record.priceType,
                        aggregatorType=existing_record.aggregatorType,
                        aggregatorValue=existing_record.aggregatorValue,
                        chargeType=existing_record.chargeType,
                        chargeValue=existing_record.chargeValue,
                        gstInclude=existing_record.gstInclude,
                        gstValue=existing_record.gstValue,
                        tdsInclude=existing_record.tdsInclude,
                        tdsValue=existing_record.tdsValue,
                        priceRangeList=existing_record.priceRangeList,
                        update= update
                    )


                else:  # Insert a new record
                    # slabName = request.form.get("slabName", "")
                    patternId = request.form.get("patternId", "")
                    paymentModeId = request.form.get("paymentModeId", "")
                    # subPaymentModeId = request.form.get("subPaymentModeId", "")
                    transactionAPIId = request.form.get("transactionAPIId", "")
                    priceType = request.form.get("priceType", "")
                    aggregatorType = request.form.get("aggregatorType", "")
                    aggregatorValue = request.form.get("aggregatorValue", 0)
                    gstInclude = request.form.get("gstInclude", "")
                    gstValue = request.form.get("gstValue", 0)
                    tdsInclude = request.form.get("tdsInclude", "")
                    tdsValue = request.form.get("tdsValue", 0)
                    chargeType = request.form.get("chargeType", "")
                    chargeValue = request.form.get("chargeValue", 0)

                    # Fetching lists from the form
                    isUnlimited = request.form.getlist("isUnlimited")
                    startAmountListField = request.form.getlist("startAmount[]")
                    endAmountListField = request.form.getlist("endAmount[]")
                    aggregatorTypeListField = request.form.getlist("aggregatorType[]")
                    aggregatorValueListField = request.form.getlist("aggregatorValue[]")
                    chargeTypeListField = request.form.getlist("chargeType[]")
                    chargeValueListField = request.form.getlist("chargeValue[]")
                    # subPaymentModeIdsList = request.form.getlist("subPaymentModeIdsList")
                    # paymentModeIdsList = request.form.getlist("paymentModeIdsList")
                    # transactionAPIIdsList = request.form.getlist("transactionAPIIdsList")
                    

                    jsonData = request.form.to_dict(flat=True)
                    requestData = [jsonData]
                    updatedrequestData = [jsonData]
 
                    print(request.form, "((((((((((SLAB REQUEST FORM))))))))))")
                   
                    def try_float(value):
                        print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Trying to convert value: '{value}'")  # Print value being converted
                        if value.strip() == "":
                            print("Empty string encountered.")
                            return None
                        try:
                            return float(value)
                        except ValueError:
                            print(f"ValueError: Cannot convert '{value}' to float.")
                            return None
                        
                    priceRangeList = []


                    print("startAmountListField++++",startAmountListField)


                    # Check if all lists have the same length
                    # Check if all lists have the same length
                    if (len(startAmountListField) == len(endAmountListField) ==
                        len(aggregatorTypeListField) == len(aggregatorValueListField) ==
                        len(chargeTypeListField) == len(chargeValueListField)):

                        isUnlimitedLastRow = isUnlimited[0] == 'on' if isUnlimited else False
                        
                        
                        for startAmount, endAmount, aggregatorType, aggregatorValue, chargeType, chargeValue in zip(
                                startAmountListField, endAmountListField, aggregatorTypeListField, aggregatorValueListField, 
                                chargeTypeListField, chargeValueListField):
                            
                            startAmountFloat = try_float(startAmount)
                            endAmountFloat = try_float(endAmount)
                            aggregatorValueFloat = try_float(aggregatorValue)
                            chargeValueFloat = try_float(chargeValue)

                            print(f"Converted Values - Start: {startAmountFloat}, End: {endAmountFloat}, "
                                f"Aggregator: {aggregatorValueFloat}, Charge: {chargeValueFloat}")

                            if None not in (startAmountFloat, endAmountFloat, aggregatorValueFloat, chargeValueFloat):
                                priceRangeList.append({
                                    'startAmount': startAmountFloat,
                                    'endAmount': endAmountFloat,
                                    'aggregatorType': aggregatorType,  # Adding this for clarity
                                    'aggregatorValue': aggregatorValueFloat,
                                    'chargeType': chargeType,           # Adding this for clarity
                                    'chargeValue': chargeValueFloat,
                                    'isUnlimited': isUnlimitedLastRow if endAmount == endAmountListField[-1] else False
                                })

                        # print("Final Price Range List:",[i for i in priceRangeList])



                    else:
                        flash("Mismatch in input lengths for price ranges.", "error")
                        return redirect(url_for("patterns_configuarations.new_get_setup_charge_commissions_list"))

                    if patternId:
                        try:
                            def try_float(value):
                                print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Trying to convert value: '{value}'")  # Print value being converted
                                if value.strip() == "":
                                    print("Empty string encountered.")
                                    return None
                                try:
                                    return float(value)
                                except ValueError:
                                    print(f"ValueError: Cannot convert '{value}' to float.")
                                    return None
                        
                            aggregatorValue = try_float(request.form.get("aggregatorValue"))
                            gstValue = try_float(request.form.get("gstValue"))
                            tdsValue = try_float(request.form.get("tdsValue"))
                            chargeValue = try_float(request.form.get("chargeValue"))
                            
                            new_record = SetupChargeCommissions(
                                adminId=adminId,
                                # slabName=slabName,
                                patternId=ObjectId(patternId),
                                paymentModeId=ObjectId(paymentModeId),
                                transactionAPIId=ObjectId(transactionAPIId),
                                priceType=priceType,
                                aggregatorType=aggregatorType,
                                aggregatorValue=float(aggregatorValue) if aggregatorValue is not None else None,  # Convert to float, check for None
                                gstInclude=gstInclude,  # Ensure gstInclude is correctly defined (boolean)
                                gstValue=float(gstValue) if gstValue is not None else None,  # Convert to float, check for None
                                tdsInclude=tdsInclude,  # Ensure tdsInclude is correctly defined (boolean)
                                tdsValue=float(tdsValue) if tdsValue is not None else None,  # Convert to float, check for None
                                chargeType=chargeType,  # Ensure chargeType is defined correctly
                                chargeValue=float(chargeValue) if chargeValue is not None else None,  # Convert to float, check for None
                                priceRangeList=priceRangeList,  # Ensure priceRangeList is populated as expected
                                # subPaymentModeIdsList=[ObjectId(each_sub_payment_mode) for each_sub_payment_mode in subPaymentModeIdsList],
                                # paymentModeIdsList=[ObjectId(each_payment_mode) for each_payment_mode in paymentModeIdsList],
                                # patternIdsList=[ObjectId(patternId)],
                                # transactionAPIIdsList=[ObjectId(each_api) for each_api in transactionAPIIdsList],
                                createdOn=datetime.datetime.now(),
                                status=1,
                            )
                            print("bbbbbbbbbbbbbbbbb____________________________________________________________________agggg", request.form.get("aggregatorType"),
                        f"Updated Record: Pattern ID: {patternId}, Payment Mode ID: {paymentModeId}, "
                        f"Transaction API ID: {transactionAPIId}, "
                        f"Price Type: {priceType}, Aggregator Type: {aggregatorType}, "
                        f"Aggregator Value: {aggregatorValue}, Charge Type: {chargeType}, "
                        f"Charge Value: {chargeValue}, GST Include: {gstInclude}, "
                        f"GST Value: {gstValue}, TDS Include: {tdsInclude}, "
                        f"TDS Value: {tdsValue}","Pricelist: {priceRangeList}")

                            new_record.save()
                            flash("Setup charge commission created successfully!", "success")

                            



                            return render_template(
                        "super_admin_templates/new_setup_charge_commissions_list.html",
                        patternId=str(patternId),
                        paymentModeId=str(paymentModeId),
                        transactionAPIId=str(transactionAPIId),
                        # subPaymentsModeList=subPaymentsModeList,
                        patternsList=patternsList,
                        paymentsModeList=paymentsModeList,
                        transactionAPIsList=transactionAPIsList,
                        editable=editable,
                        priceType=priceType,
                        aggregatorType=aggregatorType,
                        aggregatorValue=aggregatorValue,
                        chargeType=chargeType,
                        chargeValue=chargeValue,
                        gstInclude=gstInclude,
                        gstValue=gstValue,
                        tdsInclude=tdsInclude,
                        tdsValue=tdsValue,
                        priceRangeList=priceRangeList,
                        update= update
                    )

                        except Exception as e:
                            flash(f"Error while creating setup charge commission: {str(e)}", "error")
                            return redirect(url_for("patterns_configuarations.new_get_setup_charge_commissions_list"))

                    else:
                        flash("Required fields are missing!", "error")
                        return redirect(url_for("patterns_configuarations.new_get_setup_charge_commissions_list"))  



            return render_template("super_admin_templates/new_setup_charge_commissions_list.html",
                commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                transactionAPIsList=transactionAPIsList,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
            )

        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch setup charge commission details!!"
            flash(error, "error")
            return render_template("super_admin_templates/new_setup_charge_commissions_list.html",commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                transactionAPIsList=transactionAPIsList,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
                )

@patterns_configuarations.route("/get_merchant_setup_charge_commissions_list", methods=["POST", "GET"])
def get_merchant_setup_charge_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    
    # Initialize lists
    commissionsList = []
    patternsList = []
    paymentsModeList = []
    subPaymentsModeList = []
    error = None
    success_message = None
    editable = False
    update = False
    setup_charge_commission={}
    setup_charge_commission_dict={}
    setup_charge_commission_list=[]
    price_ranges = []

    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"), "chargeCommissionsPermissions")

    if "view" in permissionsList:
        try:
            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))

            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
               
                if not otpcheck_queryset:
                    return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
                return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

            redirectTo = request.args.get("redirectTo", "Commission")
            search_action = request.args.get("action")

            ######################## Common Lists ###########################

            patterns_queryset = Patterns.objects(status__in=[0, 1]).order_by("-id").all()
            for each_pattern in patterns_queryset:
                patternsList.append(fetching_pattern_details(each_pattern))

            payments_mod_queryset = PaymentMode.objects(status__in=[0, 1]).order_by("-id").all()
            for each_payment_mode in payments_mod_queryset:
                paymentsModeList.append(fetching_payment_mode_details(each_payment_mode))

         

            if request.method == "GET" and request.args.get("action") == "search":
                patternId = request.args.get("patternId")
                paymentModeId = request.args.get("paymentModeId")
                subPaymentModeId = request.args.get("subPaymentModeId")
                editable = True
                update = True

                # print(patternId,"(((((((((patternId)))))))))")
                # print(paymentModeId,"(((((((((paymentModeId)))))))))")
                # print(subPaymentModeId,"(((((((((subPaymentModeId)))))))))")

                # Search for matching records
                

                sub_payments_mod_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,status__in=[0, 1]).order_by("-id").all()
                for each_sub_payment_mode in sub_payments_mod_queryset:
                    setup_charge_commission_queryset = SetupChargeCommissions.objects(subPaymentModeIdsList__in=[str(each_sub_payment_mode.id)],patternIdsList__in=[patternId],
                    paymentModeIdsList__in=[paymentModeId],
                    status=1).first()

                    if setup_charge_commission_queryset:
                        price_ranges=[]
                        if setup_charge_commission_queryset.priceType == 'RANGE':
                            price_ranges = setup_charge_commission_queryset.priceRangeList
                        setup_charge_commission_dict= {
                            "id":str(each_sub_payment_mode.id),
                            "subPaymentModeType": each_sub_payment_mode.subPaymentModeType,  # Use the subPaymentModeType
                            "subPaymentModeId": str(each_sub_payment_mode.id),  # Keep the ID for reference
                            "priceType": setup_charge_commission_queryset.priceType,
                            "chargeType": setup_charge_commission_queryset.chargeType,
                            "chargeValue": setup_charge_commission_queryset.chargeValue,
                            "gstInclude": setup_charge_commission_queryset.gstInclude,
                            "gstValue": setup_charge_commission_queryset.gstValue,
                            "tdsInclude": setup_charge_commission_queryset.tdsInclude,
                            "tdsValue": setup_charge_commission_queryset.tdsValue,
                            "price_ranges": price_ranges
                        }
                    else:
                        setup_charge_commission_dict= {
                            "id":str(each_sub_payment_mode.id),
                            "subPaymentModeType": str(each_sub_payment_mode.subPaymentModeType),
                            "subPaymentModeId": str(each_sub_payment_mode.id),
                            "priceType": "",
                            "chargeType": "",
                            "chargeValue": 0,
                            "gstInclude": "",
                            "gstValue": 0,
                            "tdsInclude": "",
                            "tdsValue": 0,
                            "price_ranges": []
                        }

                    # print("_____dict value",setup_charge_commission_dict)

                    setup_charge_commission_list.append(setup_charge_commission_dict)

                return render_template(
                    "super_admin_templates/merchant_setup_charge_commissions_list.html",
                    patternId=patternId,
                    patternsList=patternsList,
                    paymentModeId=paymentModeId,
                    paymentsModeList=paymentsModeList,
                    setup_charge_commission=setup_charge_commission,
                    subPaymentsModeList=subPaymentsModeList,
                    setup_charge_commission_list=setup_charge_commission_list,
                    # priceRangeList=price_ranges,
                    editable=editable,
                    update= update
                )

            return render_template("super_admin_templates/merchant_setup_charge_commissions_list.html",
                commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                setup_charge_commission=setup_charge_commission,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
            )

        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch setup charge commission details!!"
            flash(error, "error")
            return render_template("super_admin_templates/merchant_setup_charge_commissions_list.html",commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                setup_charge_commission=setup_charge_commission,
                patternsList=patternsList,
                paymentsModeList=paymentsModeList,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
                )

@patterns_configuarations.route("/merchant_upsert_setup_charge_commission", methods=["POST"])
def merchant_upsert_setup_charge_commission():
    if not session.get("adminId"):
        return redirect("admin_login")
    try:
        print(request.form,"request.form")
        patternId = request.form.get("patternId", "") # type: ignore
        paymentModeId = request.form.get("paymentModeId", "")
        subPaymentModeId = request.form.get("subPaymentModeId", "")
        priceType = request.form.get("priceType", "")
        gstInclude = request.form.get("gstInclude", "")
        gstValue = request.form.get("gstValue", 0)
        tdsInclude = request.form.get("tdsInclude", "")
        tdsValue = request.form.get("tdsValue", 0)
        chargeType = request.form.get("chargeType", "")
        chargeValue = request.form.get("chargeValue", 0)
        price_range_list = []
        priceDict={}
        if priceType == 'RANGE':
            startAmountListField = request.form.getlist("startAmount[]")
            endAmountListField = request.form.getlist("endAmount[]")
            chargeTypeListField = request.form.getlist("chargeType[]")
            chargeValueListField = request.form.getlist("chargeValue[]")

            if len(startAmountListField) == len(endAmountListField) == len(chargeTypeListField) == len(chargeValueListField):
                j=0
                for startAmount in startAmountListField:
                    isUnlimited=False
                    if len(startAmountListField)-1==j:
                       isUnlimited=True 
                    priceDict={
                    'startAmount': float(startAmount),
                    'endAmount': float(endAmountListField[j]),
                    'chargeType': chargeTypeListField[j],
                    'chargeValue': float(chargeValueListField[j]),
                    'isUnlimited':isUnlimited
                    }
                    price_range_list.append(priceDict)

                    j=j+1

        existing_record = SetupChargeCommissions.objects(patternIdsList__in=[patternId],paymentModeIdsList__in=[paymentModeId],
            subPaymentModeIdsList__in=[subPaymentModeId],status=1).first()
        if existing_record:
            existing_record.update(priceType=priceType,chargeType=chargeType,chargeValue=float(chargeValue),priceRangeList=price_range_list,gstInclude=gstInclude,gstValue=float(gstValue),tdsInclude=tdsInclude,tdsValue=float(tdsValue))
            flash("Record updated successfully!", "success")
        else:
            # print("is new record++++++++++++++++++++")
            new_record = SetupChargeCommissions(
                adminId=session.get("adminId"),
                patternIdsList=[ObjectId(patternId)],
                paymentModeIdsList=[ObjectId(paymentModeId)],
                subPaymentModeIdsList=[ObjectId(subPaymentModeId)],
                priceType=priceType,
                gstInclude=gstInclude,
                gstValue=float(gstValue),
                tdsInclude=tdsInclude,
                tdsValue=float(tdsValue),
                chargeType=chargeType,
                chargeValue=float(chargeValue),
                priceRangeList=price_range_list,
                createdOn=datetime.datetime.now(),
                status=1,
            )
            new_record.save()
            flash("Setup charge commission created successfully!", "success")

        return redirect(url_for("patterns_configuarations.get_merchant_setup_charge_commissions_list", patternId=patternId, paymentModeId=paymentModeId,action="search"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash(f"Error in upserting record: {str(e)}", "error")
        return redirect(url_for("patterns_configuarations.get_merchant_setup_charge_commissions_list"))



@patterns_configuarations.route("/get_api_setup_charge_commissions_list", methods=["POST", "GET"])
def get_api_setup_charge_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    # Initialize lists
    commissionsList = []
    transactionAPIsList = []
    paymentsModeList = []
    subPaymentsModeList = []
    error = None
    success_message = None
    editable = False
    update = False
    setup_charge_commission={}
    setup_charge_commission_dict={}
    setup_charge_commission_list=[]
    price_ranges = []
    transactionapiName=""

    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"), "chargeCommissionsPermissions")

    if "view" in permissionsList:
        try:
            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))

            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
               
                if not otpcheck_queryset:
                    return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
                return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

            redirectTo = request.args.get("redirectTo", "Commission")
            search_action = request.args.get("action")

            ######################## Common Lists ###########################
            transaction_API_queryset = TransactionAPI.objects(status__in=[0, 1]).order_by('-id').all()
            for each_transaction_api in transaction_API_queryset:
                service_grouping_dict = {
                    "id": str(each_transaction_api.id),
                    "apiName": each_transaction_api.apiName
                }
                transactionAPIsList.append(service_grouping_dict)


            payments_mod_queryset = PaymentMode.objects(status__in=[0, 1]).order_by("-id").all()
            for each_payment_mode in payments_mod_queryset:
                paymentsModeList.append(fetching_payment_mode_details(each_payment_mode))

         

            if request.method == "GET" and request.args.get("action") == "search":
                paymentModeId = request.args.get("paymentModeId")
                subPaymentModeId = request.args.get("subPaymentModeId")
                transactionAPIId = request.args.get("transactionAPIId")
                editable = True
                update = True

                # print(paymentModeId,"(((((((((paymentModeId)))))))))")
                # print(subPaymentModeId,"(((((((((subPaymentModeId)))))))))")
                # print(transactionAPIId,"(((((((((transactionAPIId)))))))))")

                # Search for matching records
                
                transaction_queryset = TransactionAPI.objects(id=str(transactionAPIId)).first()
                if transaction_queryset:
                    transactionapiName=transaction_queryset.apiName

                sub_payments_mod_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,status__in=[0, 1]).order_by("-id").all()
                for each_sub_payment_mode in sub_payments_mod_queryset:
                    setup_charge_commission_queryset = ApiSetupChargeCommissions.objects(subPaymentModeIdsList__in=[str(each_sub_payment_mode.id)],
                    paymentModeIdsList__in=[paymentModeId],
                    transactionAPIIdsList__in=[transactionAPIId],
                    status=1).first()

                    if setup_charge_commission_queryset:
                        price_ranges=[]
                        if setup_charge_commission_queryset.priceType == 'RANGE':
                            price_ranges = setup_charge_commission_queryset.priceRangeList
                        setup_charge_commission_dict= {
                            "id":str(each_sub_payment_mode.id),
                            "subPaymentModeType": each_sub_payment_mode.subPaymentModeType,  # Use the subPaymentModeType
                            "subPaymentModeId": str(each_sub_payment_mode.id),  # Keep the ID for reference
                            "priceType": setup_charge_commission_queryset.priceType,
                            "chargeType": setup_charge_commission_queryset.chargeType,
                            "chargeValue": setup_charge_commission_queryset.chargeValue,
                            "gstInclude": setup_charge_commission_queryset.gstInclude,
                            "gstValue": setup_charge_commission_queryset.gstValue,
                            "tdsInclude": setup_charge_commission_queryset.tdsInclude,
                            "tdsValue": setup_charge_commission_queryset.tdsValue,
                            "price_ranges": price_ranges
                        }
                    else:
                        setup_charge_commission_dict= {
                            "id":str(each_sub_payment_mode.id),
                            "subPaymentModeType": str(each_sub_payment_mode.subPaymentModeType),
                            "subPaymentModeId": str(each_sub_payment_mode.id),
                            "priceType": "",
                            "chargeType": "",
                            "chargeValue": 0,
                            "gstInclude": "",
                            "gstValue": 0,
                            "tdsInclude": "",
                            "tdsValue": 0,
                            "price_ranges": []
                        }

                    # print("_____dict value",setup_charge_commission_dict)

                    setup_charge_commission_list.append(setup_charge_commission_dict)

                return render_template(
                    "super_admin_templates/api_setup_charge_commissions_list.html",
                    paymentModeId=paymentModeId,
                    paymentsModeList=paymentsModeList,
                    transactionAPIId=transactionAPIId,
                    transactionapiName=transactionapiName,
                    transactionAPIsList=transactionAPIsList,
                    setup_charge_commission=setup_charge_commission,
                    subPaymentsModeList=subPaymentsModeList,
                    setup_charge_commission_list=setup_charge_commission_list,
                    # priceRangeList=price_ranges,
                    editable=editable,
                    update= update
                )

            return render_template("super_admin_templates/api_setup_charge_commissions_list.html",
                commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                setup_charge_commission=setup_charge_commission,
                paymentsModeList=paymentsModeList,
                transactionapiName=transactionapiName,
                transactionAPIsList=transactionAPIsList,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
            )

        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch setup charge commission details!!"
            flash(error, "error")
            return render_template("super_admin_templates/api_setup_charge_commissions_list.html",commissionsList=commissionsList,
                subPaymentsModeList=subPaymentsModeList,
                setup_charge_commission=setup_charge_commission,
                paymentsModeList=paymentsModeList,
                transactionAPIsList=transactionAPIsList,
                transactionapiName=transactionapiName,
                redirectval=redirectTo,
                error=error,
                editable=editable,
                success_message=success_message
                )


@patterns_configuarations.route("/api_upsert_setup_charge_commission", methods=["POST"])
def api_upsert_setup_charge_commission():
    if not session.get("adminId"):
        return redirect("admin_login")
    try:
        print(request.form,"request.form")
        paymentModeId = request.form.get("paymentModeId", "")
        subPaymentModeId = request.form.get("subPaymentModeId", "")
        transactionAPIId = request.form.get("transactionAPIId", "")
        priceType = request.form.get("priceType", "")
        gstInclude = request.form.get("gstInclude", "")
        gstValue = request.form.get("gstValue", 0)
        tdsInclude = request.form.get("tdsInclude", "")
        tdsValue = request.form.get("tdsValue", 0)
        chargeType = request.form.get("chargeType", "")
        chargeValue = request.form.get("chargeValue", 0)
        price_range_list = []
        priceDict={}
        if priceType == 'RANGE':
            chargeType=""
            chargeValue=0
            startAmountListField = request.form.getlist("startAmount[]")
            endAmountListField = request.form.getlist("endAmount[]")
            chargeTypeListField = request.form.getlist("chargeTypeList[]")
            chargeValueListField = request.form.getlist("chargeValue[]")

            # print("(((((((((((((((range list)))))))))))))))",startAmountListField,endAmountListField,chargeTypeListField,chargeValueListField)

            if len(startAmountListField) == len(endAmountListField) == len(chargeTypeListField) == len(chargeValueListField):
                j=0
                for startAmount in startAmountListField:
                    isUnlimited=False
                    if len(startAmountListField)-1==j:
                       isUnlimited=True 
                    priceDict={
                    'startAmount': float(startAmount),
                    'endAmount': float(endAmountListField[j]),
                    'chargeType': chargeTypeListField[j],
                    'chargeValue': float(chargeValueListField[j]),
                    'isUnlimited':isUnlimited
                    }
                    price_range_list.append(priceDict)

                    j=j+1
            else:
                app.logger.error("range fields rows do not have same length")
                flash(f"Error in upserting record!")
                return redirect(url_for("patterns_configuarations.get_api_setup_charge_commissions_list"))

        existing_record = ApiSetupChargeCommissions.objects(paymentModeIdsList__in=[paymentModeId],
            subPaymentModeIdsList__in=[subPaymentModeId],transactionAPIIdsList__in=[transactionAPIId],status=1).first()
        if existing_record:
            existing_record.update(priceType=priceType,chargeType=chargeType,chargeValue=float(chargeValue),priceRangeList=price_range_list,gstInclude=gstInclude,gstValue=float(gstValue),tdsInclude=tdsInclude,tdsValue=float(tdsValue))
            flash("Record updated successfully!", "success")
        else:
            # print("is new record++++++++++++++++++++")
            new_record = ApiSetupChargeCommissions(
                adminId=session.get("adminId"),
                paymentModeIdsList=[ObjectId(paymentModeId)],
                transactionAPIIdsList=[ObjectId(transactionAPIId)],
                subPaymentModeIdsList=[ObjectId(subPaymentModeId)],
                priceType=priceType,
                gstInclude=gstInclude,
                gstValue=float(gstValue),
                tdsInclude=tdsInclude,
                tdsValue=float(tdsValue),
                chargeType=chargeType,
                chargeValue=float(chargeValue),
                priceRangeList=price_range_list,
                createdOn=datetime.datetime.now(),
                status=1,
            )
            new_record.save()
            flash("Setup charge commission created successfully!", "success")

        return redirect(url_for("patterns_configuarations.get_api_setup_charge_commissions_list", paymentModeId=paymentModeId,transactionAPIId=transactionAPIId,action="search"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash(f"Error in upserting record: {str(e)}", "error")
        return redirect(url_for("patterns_configuarations.get_api_setup_charge_commissions_list"))


@patterns_configuarations.route("/bulk_profile_update",methods=["POST","GET"])
def bulk_profile_update():
    data_status = {"responseStatus": 0, "result": ""}
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")

    existingPatternsList = []
    try:
        if request.method =="GET":

            user_queryset = Patterns.objects(status__in=[0,1]).all()
            for each_user in user_queryset:
                patternDict = {
                    "patternId":each_user.id,
                    "patternName":each_user.name
                }
                if patternDict not in existingPatternsList:
                    existingPatternsList.append(patternDict)
            return render_template(
                    "super_admin_templates/bulk_profile_update.html",
                    existingPatternsList=existingPatternsList
                )
        elif request.method=="POST":
            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))

            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
                   
                if not otpcheck_queryset:
                    return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
                return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

            updateType=""
            existingPatternIdsList = request.form.getlist("existingPatternIdsList[]")
            newPatternId = request.form.get("newPatternId")
            includeUsersList = request.form.getlist("includeUsersList[]")
            excludeUsersList = request.form.getlist("excludeUsersList[]")
            if len(includeUsersList)> 0:
                updateType="include"
            elif len(excludeUsersList)> 0:
                updateType="exclude"
            
            if existingPatternIdsList and newPatternId:
                users_queryset=Users.objects(patternId__in=existingPatternIdsList,status=1).all()
                users_count=0
                for user in users_queryset:
                    if updateType == "include":
                        if str(user.id) in includeUsersList:
                            users_count= users_count+1
                            user.patternId = ObjectId(newPatternId)
                            user.save()
                    elif updateType == "exclude":
                        if str(user.id) not in excludeUsersList:
                            users_count= users_count+1
                            user.patternId = ObjectId(newPatternId)
                            user.save()
                    else:
                        users_count= users_count+1
                        user.patternId = ObjectId(newPatternId)
                        user.save()
                if users_count > 0:
                    flash("User profile updated successfully for "+str(users_count)+" Users!!")
                else:
                    flash("No Users with selected Profile exist!!")
            else:
                flash("Required fields are missing!!")
            return redirect(url_for("patterns_configuarations.bulk_profile_update"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash(f"Error in Bulk Profile Update: {str(e)}", "error")
        return redirect(url_for("patterns_configuarations.bulk_profile_update"))
        
                
@patterns_configuarations.route("/get_profile_users_list",methods=["POST","GET"])
def get_profile_users_list():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId=session.get("adminId")

        patternIdsList = request.json.get("patternIds")
        patternUsersList = []

        users_queryset=Users.objects(patternId__in=patternIdsList,status=1).all()
        for user in users_queryset:
            userDict = {
                "id": str(user.id),
                "fullName": user.fullName,
                "merchantReferenceNumber": user.merchantUniqueNumber,
                "phoneNumber": user.phoneNumber,
            }
            patternUsersList.append(userDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "ProfileUsers List fetched successfully!"
        data_status["patternUsersList"] = patternUsersList

        return jsonify(data_status), 200
        return redirect(url_for("patterns_configuarations.bulk_profile_update"))

    except Exception as e:
        app.logger.error(f"Error fetching payout options: {str(e)}")
        data_status["result"] = "An error occurred while fetching payout options!"
        return jsonify(data_status), 500

@patterns_configuarations.route("/available_timings",methods=["POST","GET"])
def available_timings():
    try:
        data_status = {"responseStatus": 0, "result":""}
        payinTimingsList=[]
        available_timings_data={}

        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        transactionType =request.args.get("transactionType","")

        available_timings_queryset0 = AvailableTimings.objects(transactionType=transactionType,status=1).first()
        available_timings_data_list=[]
        overridesDatesList = []
        timings_str_list=[]
        overrideTimingsList=[]
        # If the record doesn't exist, create a new one
        if not available_timings_queryset0:
            available_timings_queryset1 = AvailableTimings(
                isEnabled =  False,
                sunEnabled = False,
                sunAvailableTimingsList = [],
                monEnabled = False,
                monAvailableTimingsList = [],
                tueEnabled = False,
                tueAvailableTimingsList = [],
                wedEnabled = False,
                wedAvailableTimingsList = [],
                thuEnabled = False,
                thuAvailableTimingsList = [],
                friEnabled = False,
                friAvailableTimingsList = [],
                satEnabled = False,
                satAvailableTimingsList = [],
                overridesDatesList = [],
                transactionType=transactionType,  # Ensure it's for "payout"
                createdOn=datetime.datetime.now(),
                status=1
            )
            available_timings_queryset1.save()
        available_timings_queryset = AvailableTimings.objects(transactionType=transactionType,status=1).first()
        redirectTo =request.args.get("redirectval","timingsList")
        if request.method == "GET":

            time_list = available_timings_queryset.overridesDatesList
            print("time_list",time_list)

            for each_override_list in time_list:
                timings_str_list=[]
                print("timingsList",each_override_list)
                overrideTimingsList = each_override_list.get("timingsList")
                for each_rec in overrideTimingsList:
                    timings_str_list.append(each_rec.get("fromTime") + " - " +each_rec.get("toTime"))
                timings_str_list = ', '.join(timings_str_list)
                overridesDatesList.append({
                    "overrideDate": each_override_list.get("overrideDate"),
                    "formattedTimingsList": timings_str_list,
                    "timingsList": each_override_list.get("timingsList"),

                })
            # print("overridesDatesListoverridesDatesListoverridesDatesList",overridesDatesList)

            is_enabled = available_timings_queryset.isEnabled
            sundayDict={
                "day":"Sunday",
                "is_enabled":available_timings_queryset.sunEnabled,
                "timingsList":available_timings_queryset.sunAvailableTimingsList
            }
            available_timings_data_list.append(sundayDict)

            mondayDict={
                "day":"Monday",
                "is_enabled":available_timings_queryset.monEnabled,
                "timingsList":available_timings_queryset.monAvailableTimingsList
            }
            available_timings_data_list.append(mondayDict)

            tuesdayDict={
                "day":"Tuesday",
                "is_enabled":available_timings_queryset.tueEnabled,
                "timingsList":available_timings_queryset.tueAvailableTimingsList
            }
            available_timings_data_list.append(tuesdayDict)

            wednesdayDict={
                "day":"Wednesday",
                "is_enabled":available_timings_queryset.wedEnabled,
                "timingsList":available_timings_queryset.wedAvailableTimingsList
            }
            available_timings_data_list.append(wednesdayDict)

            thursdayDict={
                "day":"Thursday",
                "is_enabled":available_timings_queryset.thuEnabled,
                "timingsList":available_timings_queryset.thuAvailableTimingsList
            }
            available_timings_data_list.append(thursdayDict)

            fridayDict={
                "day":"Friday",
                "is_enabled":available_timings_queryset.friEnabled,
                "timingsList":available_timings_queryset.friAvailableTimingsList
            }
            available_timings_data_list.append(fridayDict)

            saturdayDict={
                "day":"Saturday",
                "is_enabled":available_timings_queryset.satEnabled,
                "timingsList":available_timings_queryset.satAvailableTimingsList
            }
            available_timings_data_list.append(saturdayDict)
            
            print("dataaaaaaaa",available_timings_data_list )
            print("overridesDatesList",overridesDatesList )

            return render_template(
                        "super_admin_templates/available_timings.html",
                        payinTimingsList=payinTimingsList,
                        redirectval=redirectTo,
                        available_timings_data_list=available_timings_data_list,
                        is_enabled=is_enabled,
                        overridesDatesList=overridesDatesList,transactionType=transactionType
                    )

        elif request.method == "POST":
            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))

            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
               
                if not otpcheck_queryset:
                    return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
                return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

            print("request.form ",request.form)
            transactionType =request.args.get("transactionType","")
            redirectTo ="timingsList"
            is_enabled = request.form.get('is_enabled') == 'True'
            sun_enabled = request.form.get('Sunday_is_enabled')== 'True'
            sun_from_times = request.form.getlist('from_time_Sunday[]')
            sun_to_times = request.form.getlist('to_time_Sunday[]')

            mon_enabled = request.form.get('Monday_is_enabled') == 'True'
            mon_from_times = request.form.getlist('from_time_Monday[]')
            mon_to_times = request.form.getlist('to_time_Monday[]')

            tue_enabled = request.form.get('Tuesday_is_enabled') == 'True'
            tue_from_times = request.form.getlist('from_time_Tuesday[]')
            tue_to_times = request.form.getlist('to_time_Tuesday[]')

            wed_enabled = request.form.get('Wednesday_is_enabled') == 'True'
            wed_from_times = request.form.getlist('from_time_Wednesday[]')
            wed_to_times = request.form.getlist('to_time_Wednesday[]')

            thu_enabled = request.form.get('Thursday_is_enabled') == 'True'
            thu_from_times = request.form.getlist('from_time_Thursday[]')
            thu_to_times = request.form.getlist('to_time_Thursday[]')

            fri_enabled = request.form.get('Friday_is_enabled') == 'True'
            fri_from_times = request.form.getlist('from_time_Friday[]')
            fri_to_times = request.form.getlist('to_time_Friday[]')

            sat_enabled = request.form.get('Saturday_is_enabled') == 'True'
            sat_from_times = request.form.getlist('from_time_Saturday[]')
            sat_to_times = request.form.getlist('to_time_Saturday[]')

            

    
            print("created new",sun_enabled,is_enabled)
            
            available_timings_queryset = AvailableTimings.objects(transactionType=transactionType,status=1).first()

            if available_timings_queryset:
                print("inside updte")
                print(f"""
                Sunday Enabled: {sun_enabled}, Sunday From Times: {sun_from_times}, Sunday To Times: {sun_to_times}
                Monday Enabled: {mon_enabled}, Monday From Times: {mon_from_times}, Monday To Times: {mon_to_times}
                Tuesday Enabled: {tue_enabled}, Tuesday From Times: {tue_from_times}, Tuesday To Times: {tue_to_times}
                Wednesday Enabled: {wed_enabled}, Wednesday From Times: {wed_from_times}, Wednesday To Times: {wed_to_times}
                Thursday Enabled: {thu_enabled}, Thursday From Times: {thu_from_times}, Thursday To Times: {thu_to_times}
                Friday Enabled: {fri_enabled}, Friday From Times: {fri_from_times}, Friday To Times: {fri_to_times}
                Saturday Enabled: {sat_enabled}, Saturday From Times: {sat_from_times}, Saturday To Times: {sat_to_times}
                """,type(sun_enabled))
                available_timings_queryset.isEnabled = is_enabled
                available_timings_queryset.sunEnabled = sun_enabled
                available_timings_queryset.sunAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(sun_from_times, sun_to_times)]
                available_timings_queryset.monEnabled = mon_enabled
                available_timings_queryset.monAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(mon_from_times, mon_to_times)]
                available_timings_queryset.tueEnabled = tue_enabled
                available_timings_queryset.tueAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(tue_from_times, tue_to_times)]
                available_timings_queryset.wedEnabled = wed_enabled
                available_timings_queryset.wedAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(wed_from_times, wed_to_times)]
                available_timings_queryset.thuEnabled = thu_enabled
                available_timings_queryset.thuAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(thu_from_times, thu_to_times)]
                available_timings_queryset.friEnabled = fri_enabled
                available_timings_queryset.friAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(fri_from_times, fri_to_times)]
                available_timings_queryset.satEnabled = sat_enabled
                available_timings_queryset.satAvailableTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(sat_from_times, sat_to_times)]
                available_timings_queryset.status = 1
                available_timings_queryset.createdOn = datetime.datetime.now()
                available_timings_queryset.save()
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

    except Exception as e:
        app.logger.error(f"Error fetching options: {str(e)}")
        data_status["result"] = "An error occurred while fetching Available Options!"
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

@patterns_configuarations.route("/add_override_date", methods=["POST", "GET"])
def add_override_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        redirectTo = "overrides_dates_list"

        action = request.form.get("action", "HI").strip()
        data = request.form.to_dict()
        # Step 1: Handle OTP Generation
        if action == "generate":
            mail_type = data.get("mailType", "").strip()
            print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
            if not mail_type:
                return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


            return jsonify(generate_otp_helper(mail_type))

        # tep 2: Handle OTP Verification
        elif action == "verify":
            otp_check_id = request.form.get("otpCheckId","SAI")
            otp_code = request.form.get("otpCode","K")

            print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
            print(otp_code,"((((((((OTP CODE????????????))))))))")

            if not otp_check_id or not otp_code:
                return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

            return jsonify(verify_otp_helper(otp_check_id, otp_code))

        elif action == "update":
            otp_check_id = request.form.get("otpCheckId", "")
            otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
            admin_id = request.form.get("adminId", "")

            otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
           
            if not otpcheck_queryset:
                return jsonify({"responseStatus": 0, "result": "Invalid Request."})
            # Update OTP status to 2 after verification
            otpcheck_queryset.update(status=2)
            return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

        # Fetch form data
        print("requestsssssssss", request.form)
        transactionType =request.args.get("transactionType","")
        overrideDate = request.form.get('overrideDate')  # Get the override date
        from_times = request.form.getlist('from_time[]')  # List of from times
        to_times = request.form.getlist('to_time[]')  # List of to times

        print("overrideDate", overrideDate)
        print("from_times", from_times)
        print("to_times", to_times)

        

        # Validate input
        if not overrideDate or not from_times or not to_times or not transactionType:
            flash("Required fields are missing!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Build the timings list
        timingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(from_times, to_times)]

        # Fetch the database record
        available_timings_queryset = AvailableTimings.objects(transactionType=transactionType, status=1).first()
        if not available_timings_queryset:
            flash("No available timings found!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Check for duplicates in overridesDatesList
        overridesDatesList = available_timings_queryset.overridesDatesList
        for override in overridesDatesList:
            if override["overrideDate"] == overrideDate:  # If the date already exists
                flash(f"An override already exists for the date: {overrideDate}")
                return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Add the new override date and timings
        overridesDatesListDict = {
            "overrideDate": overrideDate,
            "timingsList": timingsList
        }
        overridesDatesList.append(overridesDatesListDict)

        # Save the updated list back to the database
        available_timings_queryset.update(overridesDatesList=overridesDatesList)

        flash("Override date added successfully!")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

    except Exception as e:
        app.logger.error(f"Error adding override date: {str(e)}")
        flash("An error occurred while adding the override date.")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))


@patterns_configuarations.route("/update_override_date", methods=["POST", "GET"])
def update_override_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        redirectTo = "overrides_dates_list"
        transactionType =request.args.get("transactionType","")


        action = request.form.get("action", "HI").strip()
        data = request.form.to_dict()
        # Step 1: Handle OTP Generation
        if action == "generate":
            mail_type = data.get("mailType", "").strip()
            print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
            if not mail_type:
                return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


            return jsonify(generate_otp_helper(mail_type))

        # tep 2: Handle OTP Verification
        elif action == "verify":
            otp_check_id = request.form.get("otpCheckId","SAI")
            otp_code = request.form.get("otpCode","K")

            print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
            print(otp_code,"((((((((OTP CODE????????????))))))))")

            if not otp_check_id or not otp_code:
                return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

            return jsonify(verify_otp_helper(otp_check_id, otp_code))

        elif action == "update":
            otp_check_id = request.form.get("otpCheckId", "")
            otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
            admin_id = request.form.get("adminId", "")

            otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
           
            if not otpcheck_queryset:
                return jsonify({"responseStatus": 0, "result": "Invalid Request."})
            # Update OTP status to 2 after verification
            otpcheck_queryset.update(status=2)
            return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

        # Fetch form data
        overrideDate = request.form.get("overrideDate")        # The date to identify the record to update
        from_times = request.form.getlist("from_time[]")       # New 'from' times
        to_times = request.form.getlist("to_time[]")           # New 'to' times

        print("overrideDate", overrideDate)
        print("from_times", from_times)
        print("to_times", to_times)
        print("redirectTo", redirectTo)

        

        # Validate input
        if not overrideDate or not from_times or not to_times:
            flash("Required fields are missing!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Build the new timings list
        updatedTimingsList = [{"fromTime": ft, "toTime": tt} for ft, tt in zip(from_times, to_times)]

        # Fetch the database record
        available_timings_queryset = AvailableTimings.objects(transactionType=transactionType, status=1).first()
        if not available_timings_queryset:
            flash("No available timings found!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Find and update the matching record in overridesDatesList
        overridesDatesList = available_timings_queryset.overridesDatesList
        for override in overridesDatesList:
            if override["overrideDate"] == overrideDate:  # Match the date
                override["timingsList"] = updatedTimingsList  # Update timings list
                break
        else:
            flash("No matching override date found!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Save the updated list back to the database
        available_timings_queryset.update(overridesDatesList=overridesDatesList)

        flash("Override date updated successfully!")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

    except Exception as e:
        app.logger.error(f"Error updating override date: {str(e)}")
        flash("An error occurred while updating the override date.")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))


@patterns_configuarations.route("/delete_override_date", methods=["GET"])
def delete_override_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        redirectTo = "overrides_dates_list"

        # Fetch the override date to delete
        transactionType =request.args.get("transactionType","")
        overrideDate = request.args.get("overrideDate")
        print("overrideDate to delete:", overrideDate)

        # Validate input
        if not overrideDate:
            flash("Override date is required!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Fetch the database record
        available_timings_queryset = AvailableTimings.objects(transactionType=transactionType, status=1).first()
        if not available_timings_queryset:
            flash("No available timings found!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Remove the matching record from overridesDatesList
        overridesDatesList = available_timings_queryset.overridesDatesList
        updatedOverridesList = [override for override in overridesDatesList if override["overrideDate"] != overrideDate]

        # If no changes were made (overrideDate not found), return a message
        if len(overridesDatesList) == len(updatedOverridesList):
            flash("No matching override date found!")
            return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

        # Save the updated list back to the database
        available_timings_queryset.update(overridesDatesList=updatedOverridesList)

        flash("Override date deleted successfully!")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))

    except Exception as e:
        app.logger.error(f"Error deleting override date: {str(e)}")
        flash("An error occurred while deleting the override date.")
        return redirect(url_for("patterns_configuarations.available_timings",redirectval=redirectTo,transactionType=transactionType))



@patterns_configuarations.route("/dynamic_profile_switch",methods=["POST","GET"])
def dynamic_profile_switch():
    redirectTo =request.args.get("redirectval","profileSwitch")
    try:
        data_status = {"responseStatus": 0, "result":""}

        existingPatternsList=[]

        user_queryset = Patterns.objects(status=1).all()
        for each_user in user_queryset:
            patternDict = {
                "patternId":str(each_user.id),
                "patternName":each_user.name
            }
            if patternDict not in existingPatternsList:
                existingPatternsList.append(patternDict)

        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        profile_queryset0 = ProfileSwitch.objects(status=1).first()
        profile_switch_data_list=[]
        overridesProfileList = []
        timings_str_list=[]


        # If the record doesn't exist, create a new one
        if not profile_queryset0:
            profile_queryset1 = ProfileSwitch(
                sunEnabled = False,
                sunDefaultEnable = False,
                sunProfileList = [],
                monEnabled = False,
                monDefaultEnable = False,
                monProfileList = [],
                tueEnabled = False,
                tueDefaultEnable = False,
                tueProfileList = [],
                wedEnabled = False,
                wedDefaultEnable = False,
                wedProfileList = [],
                thuEnabled = False,
                thuDefaultEnable = False,
                thuProfileList = [],
                friEnabled = False,
                friDefaultEnable = False,
                friProfileList = [],
                satEnabled = False,
                satDefaultEnable = False,
                satProfileList = [],
                overridesProfileList = [] ,
                status = 1,
                createdOn = datetime.datetime.now(),
            )
            profile_queryset1.save()
        profile_queryset = ProfileSwitch.objects(status=1).first()
        if request.method == "GET":

            overridesProfileListData = profile_queryset.overridesProfileList
            # print("time_list",time_list)

            for each_override_list in overridesProfileListData:
                override_name_list=[]
                # print("each_override_list",each_override_list)
                overrideList = each_override_list.get("overrideList")
                for each_rec in overrideList:
                    existingProfile =  each_rec.get("defaultProfile")
                    defaultProfile = each_rec.get("applicableProfile")
                    existingProfile_queryset = Patterns.objects(id=existingProfile,status=1).first()
                    defaultProfile_queryset = Patterns.objects(id=str(defaultProfile),status=1).first()
                    if existingProfile_queryset and defaultProfile_queryset:
                        override_name_list.append(existingProfile_queryset.name + " - " +defaultProfile_queryset.name)
                override_name_list = ', '.join(override_name_list)
                overridesProfileList.append({
                    "overrideDate": each_override_list.get("overrideDate"),
                    "formattedOverrideList": override_name_list,
                    "overrideList": each_override_list.get("overrideList"),

                })
            # print("overridesProfileList",overridesProfileList)

            # is_enabled = profile_queryset.isEnabled
            sundayDict={
                "day":"Sunday",
                "is_enabled":profile_queryset.sunEnabled,
                "defaultEnable":profile_queryset.sunDefaultEnable,
                "profileList":profile_queryset.sunProfileList
            }
            profile_switch_data_list.append(sundayDict)

            mondayDict={
                "day":"Monday",
                "is_enabled":profile_queryset.monEnabled,
                "defaultEnable":profile_queryset.monDefaultEnable,
                "profileList":profile_queryset.monProfileList
            }
            profile_switch_data_list.append(mondayDict)

            tuesdayDict={
                "day":"Tuesday",
                "is_enabled":profile_queryset.tueEnabled,
                "defaultEnable":profile_queryset.tueDefaultEnable,
                "profileList":profile_queryset.tueProfileList
            }
            profile_switch_data_list.append(tuesdayDict)

            wednesdayDict={
                "day":"Wednesday",
                "is_enabled":profile_queryset.wedEnabled,
                "defaultEnable":profile_queryset.wedDefaultEnable,
                "profileList":profile_queryset.wedProfileList
            }
            profile_switch_data_list.append(wednesdayDict)

            thursdayDict={
                "day":"Thursday",
                "is_enabled":profile_queryset.thuEnabled,
                "defaultEnable":profile_queryset.thuDefaultEnable,
                "profileList":profile_queryset.thuProfileList
            }
            profile_switch_data_list.append(thursdayDict)

            fridayDict={
                "day":"Friday",
                "is_enabled":profile_queryset.friEnabled,
                "defaultEnable":profile_queryset.friDefaultEnable,
                "profileList":profile_queryset.friProfileList
            }
            profile_switch_data_list.append(fridayDict)

            saturdayDict={
                "day":"Saturday",
                "is_enabled":profile_queryset.satEnabled,
                "defaultEnable":profile_queryset.satDefaultEnable,
                "profileList":profile_queryset.satProfileList
            }
            profile_switch_data_list.append(saturdayDict)
            
            # print("dataaaaaaaa",profile_switch_data_list )
            # print("overridesProfileList",overridesProfileList )
            print("profileSwitch",redirectTo)

            return render_template(
                        "super_admin_templates/dynamic_profile_switch.html",
                        redirectval=redirectTo,
                        profile_switch_data_list=profile_switch_data_list,
                        existingPatternsList=existingPatternsList,
                        overridesProfileList=overridesProfileList
                    )

        elif request.method == "POST":

            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))

            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
               
                if not otpcheck_queryset:
                    return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
                return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})
            print("request.form",request.form)

            sun_enabled = request.form.get("Sunday_is_enabled") == "True"
            sun_default_enable = request.form.get("Sunday_defaultEnable") == "True"
            sun_default_profiles = request.form.getlist("defaultProfile_Sunday[]")
            sun_applicable_profiles = request.form.getlist("applicableProfile_Sunday[]")

            mon_enabled = request.form.get("Monday_is_enabled") == "True"
            mon_default_enable = request.form.get("Monday_defaultEnable") == "True"
            mon_default_profiles = request.form.getlist("defaultProfile_Monday[]")
            mon_applicable_profiles = request.form.getlist("applicableProfile_Monday[]")

            tue_enabled = request.form.get("Tuesday_is_enabled") == "True"
            tue_default_enable = request.form.get("Tuesday_defaultEnable") == "True"
            tue_default_profiles = request.form.getlist("defaultProfile_Tuesday[]")
            tue_applicable_profiles = request.form.getlist("applicableProfile_Tuesday[]")

            wed_enabled = request.form.get("Wednesday_is_enabled") == "True"
            wed_default_enable = request.form.get("Wednesday_defaultEnable") == "True"
            wed_default_profiles = request.form.getlist("defaultProfile_Wednesday[]")
            wed_applicable_profiles = request.form.getlist("applicableProfile_Wednesday[]")

            thu_enabled = request.form.get("Thursday_is_enabled") == "True"
            thu_default_enable = request.form.get("Thursday_defaultEnable") == "True"
            thu_default_profiles = request.form.getlist("defaultProfile_Thursday[]")
            thu_applicable_profiles = request.form.getlist("applicableProfile_Thursday[]")

            fri_enabled = request.form.get("Friday_is_enabled") == "True"
            fri_default_enable = request.form.get("Friday_defaultEnable") == "True"
            fri_default_profiles = request.form.getlist("defaultProfile_Friday[]")
            fri_applicable_profiles = request.form.getlist("applicableProfile_Friday[]")

            sat_enabled = request.form.get("Saturday_is_enabled") == "True"
            sat_default_enable = request.form.get("Saturday_defaultEnable") == "True"
            sat_default_profiles = request.form.getlist("defaultProfile_Saturday[]")
            sat_applicable_profiles = request.form.getlist("applicableProfile_Saturday[]")

            profile_queryset = ProfileSwitch.objects(status=1).first()

            if profile_queryset:
                profile_queryset.sunEnabled = sun_enabled
                profile_queryset.sunDefaultEnable = sun_default_enable
                profile_queryset.sunProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(sun_default_profiles, sun_applicable_profiles)
                ] if sun_enabled else []

                profile_queryset.monEnabled = mon_enabled
                profile_queryset.monDefaultEnable = mon_default_enable
                profile_queryset.monProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(mon_default_profiles, mon_applicable_profiles)
                ] if mon_enabled else []

                profile_queryset.tueEnabled = tue_enabled
                profile_queryset.tueDefaultEnable = tue_default_enable
                profile_queryset.tueProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(tue_default_profiles, tue_applicable_profiles)
                ] if tue_enabled else []

                profile_queryset.wedEnabled = wed_enabled
                profile_queryset.wedDefaultEnable = wed_default_enable
                profile_queryset.wedProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(wed_default_profiles, wed_applicable_profiles)
                ] if wed_enabled else []

                profile_queryset.thuEnabled = thu_enabled
                profile_queryset.thuDefaultEnable = thu_default_enable
                profile_queryset.thuProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(thu_default_profiles, thu_applicable_profiles)
                ] if thu_enabled else []

                profile_queryset.friEnabled = fri_enabled
                profile_queryset.friDefaultEnable = fri_default_enable
                profile_queryset.friProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(fri_default_profiles, fri_applicable_profiles)
                ] if fri_enabled else []

                profile_queryset.satEnabled = sat_enabled
                profile_queryset.satDefaultEnable = sat_default_enable
                profile_queryset.satProfileList = [
                    {"defaultProfile": dp, "applicableProfile": ap}
                    for dp, ap in zip(sat_default_profiles, sat_applicable_profiles)
                ] if sat_enabled else []

                # Save the updated profile
                profile_queryset.status = 1
                profile_queryset.createdOn = datetime.datetime.now()
                profile_queryset.save()

            return redirect(url_for(
                "patterns_configuarations.dynamic_profile_switch",
                redirectval=redirectTo
            ))

    except Exception as e:
        app.logger.error(f"Error fetching options: {str(e)}")
        data_status["result"] = "An error occurred while fetching Profile Switch Options!"
        return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

@patterns_configuarations.route("/add_override_profile_date", methods=["POST", "GET"])
def add_override_profile_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        redirectTo = "overrideDates"

        action = request.form.get("action", "HI").strip()
        data = request.form.to_dict()
        # Step 1: Handle OTP Generation
        if action == "generate":
            mail_type = data.get("mailType", "").strip()
            print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
            if not mail_type:
                return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


            return jsonify(generate_otp_helper(mail_type))

        # tep 2: Handle OTP Verification
        elif action == "verify":
            otp_check_id = request.form.get("otpCheckId","SAI")
            otp_code = request.form.get("otpCode","K")

            print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
            print(otp_code,"((((((((OTP CODE????????????))))))))")

            if not otp_check_id or not otp_code:
                return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

            return jsonify(verify_otp_helper(otp_check_id, otp_code))

        elif action == "update":
            otp_check_id = request.form.get("otpCheckId", "")
            otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
            admin_id = request.form.get("adminId", "")

            otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
           
            if not otpcheck_queryset:
                return jsonify({"responseStatus": 0, "result": "Invalid Request."})
            # Update OTP status to 2 after verification
            otpcheck_queryset.update(status=2)
            return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

        # Fetch form data
        # print("requestsssssssss", request.form)
        overrideDate = request.form.get('overrideDate')  # Get the override date
        defaultProfile = request.form.getlist('defaultProfile[]')  # List of from times
        applicableProfile = request.form.getlist('applicableProfile[]')  # List of to times

        # print("overrideDate", overrideDate)
        # print("defaultProfile", defaultProfile)
        # print("applicableProfile", applicableProfile)

        # Validate input
        if not overrideDate or not defaultProfile or not applicableProfile:
            flash("Required fields are missing!")
            return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Build the timings list
        overrideList = [{"defaultProfile": ft, "applicableProfile": tt} for ft, tt in zip(defaultProfile, applicableProfile)]

        # Fetch the database record
        profile_switch_queryset = ProfileSwitch.objects( status=1).first()
        if not profile_switch_queryset:
            flash("No Profile Switches found!")
            return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Check for duplicates in overridesProfileList
        overridesProfileList = profile_switch_queryset.overridesProfileList
        for override in overridesProfileList:
            if override["overrideDate"] == overrideDate:  # If the date already exists
                flash(f"An override already exists for the date: {overrideDate}")
                return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Add the new override date and timings
        overridesProfileListDict = {
            "overrideDate": overrideDate,
            "overrideList": overrideList
        }
        overridesProfileList.append(overridesProfileListDict)

        # Save the updated list back to the database
        profile_switch_queryset.update(overridesProfileList=overridesProfileList)

        flash("Override date added successfully!")
        return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

    except Exception as e:
        app.logger.error(f"Error adding override date: {str(e)}")
        flash("An error occurred while adding the override date.")
        return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))



# @patterns_configuarations.route("/delete_override_profile_date", methods=["POST"])
# def delete_override_profile_date():
#     try:
#         data_status = {"responseStatus": 0, "result": ""}
#         redirectTo = "overrideDates"

#         # Fetch the override date to delete
#         overrideDate = request.args.get("overrideDate")

#         action = request.form.get("action", "HI").strip()
#         # Step 1: Handle OTP Generation
#         if action == "generate":
#             return jsonify(generate_otp_helper())

#         # tep 2: Handle OTP Verification
#         elif action == "verify":
#             otp_check_id = request.form.get("otpCheckId","SAI")
#             otp_code = request.form.get("otpCode","K")

#             print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
#             print(otp_code,"((((((((OTP CODE????????????))))))))")

#             if not otp_check_id or not otp_code:
#                 return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

#             return jsonify(verify_otp_helper(otp_check_id, otp_code))

#         elif action == "update":
#             otp_check_id = request.form.get("otpCheckId", "").strip()
#             otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()

#             if not otp_record:
#                 return jsonify({"responseStatus": 0, "result": "OTP not verified. Please verify OTP first!"})

#         # Validate input
#         if not overrideDate:
#             flash("Override date is required!")
#             return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

#         # Fetch the database record
#         profile_switch_queryset = ProfileSwitch.objects(status=1).first()
#         if not profile_switch_queryset:
#             flash("No Override Date found!")
#             return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

#         # Remove the matching record from overridesDatesList
#         overridesProfileList = profile_switch_queryset.overridesProfileList
#         updatedOverridesList = [override for override in overridesProfileList if override["overrideDate"] != overrideDate]

#         # If no changes were made (overrideDate not found), return a message
#         if len(overridesProfileList) == len(updatedOverridesList):
#             flash("No matching override date found!")
#             return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

#         # Save the updated list back to the database
#         profile_switch_queryset.update(overridesProfileList=updatedOverridesList)

#         flash("Override date deleted successfully!")
#         return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

#     except Exception as e:
#         app.logger.error(f"Error deleting override date: {str(e)}")
#         flash("An error occurred while deleting the override date.")
#         return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

@patterns_configuarations.route("/delete_override_profile_date", methods=["POST"])
def delete_override_profile_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}

        # Fetch parameters
        action = request.form.get("action", "").strip()
        override_date = request.form.get("overrideDate", "").strip()
        otp_check_id = request.form.get("otpCheckId", "").strip()
        otp_code = request.form.get("otpCode", "").strip()
        admin_id = request.form.get("adminId", "").strip()

        # Step 1: Handle OTP Generation
        if action == "generate":
            mail_type = request.form.get("mailType", "").strip()

            if not mail_type:
                return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400

            return jsonify(generate_otp_helper(mail_type))

        # Step 2: Verify OTP
        elif action == "verify":
            if not otp_check_id or not otp_code:
                return jsonify({"responseStatus": 0, "result": "Missing OTP data!"})

            otp_verified = verify_otp_helper(otp_check_id, otp_code)
            if otp_verified["responseStatus"] == 0:
                return jsonify({"responseStatus": 0, "result": "OTP verification failed!"})

            # If OTP verification is successful, proceed to delete
            if not override_date:
                return jsonify({"responseStatus": 0, "result": "Override date is required!"})

            # Fetch the record with the matching overrideDate
            profile_switch_queryset = ProfileSwitch.objects(status=1, overridesProfileList__overrideDate=override_date).first()

            if not profile_switch_queryset:
                return jsonify({"responseStatus": 0, "result": "No matching override date found!"})

            # Remove only the matched entry from the list
            updated_overrides_list = [
                override for override in profile_switch_queryset.overridesProfileList if override["overrideDate"] != override_date
            ]

            # If nothing was removed, return an error
            if len(profile_switch_queryset.overridesProfileList) == len(updated_overrides_list):
                return jsonify({"responseStatus": 0, "result": "No matching override date found!"})

            # Update the database with the modified list
            profile_switch_queryset.update(overridesProfileList=updated_overrides_list)

            return jsonify({"responseStatus": 1, "result": "Record deleted successfully!"})

        # Step 3: Update OTP status after verification
        elif action == "update":
            otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()

            if not otp_record:
                return jsonify({"responseStatus": 0, "result": "Invalid OTP request!"})

            # Ensure the OTP belongs to the given adminId
            otp_check_queryset = OtpChecks.objects(adminId=admin_id, id=otp_check_id, status=1).first()
            if not otp_check_queryset:
                return jsonify({"responseStatus": 0, "result": "Invalid Request."})

            # Update OTP status to 2 after verification
            otp_check_queryset.update(status=2)
            return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

        else:
            return jsonify({"responseStatus": 0, "result": "Invalid action!"})

    except Exception as e:
        app.logger.error(f"Error deleting override date: {str(e)}")
        return jsonify({"responseStatus": 0, "result": "Server error! Please try again later."})




@patterns_configuarations.route("/update_override_profile_date", methods=["POST", "GET"])
def update_override_profile_date():
    try:
        data_status = {"responseStatus": 0, "result": ""}
        redirectTo = "overrideDates"

        action = request.form.get("action", "HI").strip()
        data = request.form.to_dict()
        # Step 1: Handle OTP Generation
        if action == "generate":
            mail_type = data.get("mailType", "").strip()
            print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
            if not mail_type:
                return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


            return jsonify(generate_otp_helper(mail_type))

        # tep 2: Handle OTP Verification
        elif action == "verify":
            otp_check_id = request.form.get("otpCheckId","SAI")
            otp_code = request.form.get("otpCode","K")

            print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
            print(otp_code,"((((((((OTP CODE????????????))))))))")

            if not otp_check_id or not otp_code:
                return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

            return jsonify(verify_otp_helper(otp_check_id, otp_code))

        elif action == "update":
            otp_check_id = request.form.get("otpCheckId", "")
            otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
            admin_id = request.form.get("adminId", "")

            otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), id=str(otp_check_id), status=1).first()
           
            if not otpcheck_queryset:
                return jsonify({"responseStatus": 0, "result": "Invalid Request."})
            # Update OTP status to 2 after verification
            otpcheck_queryset.update(status=2)
            return jsonify({"responseStatus": 1, "result": "OTP status successfully updated!"})

        # Fetch form data
        print("requesttttt",request.form)
        overrideDate = request.form.get('overrideDate')  
        defaultProfile = request.form.getlist('defaultProfile[]') 
        applicableProfile = request.form.getlist('applicableProfile[]')

        print("overrideDate", overrideDate)
        print("defaultProfile", defaultProfile)
        print("defaultProfile", defaultProfile)
        print("redirectTo", redirectTo)

        if not overrideDate or not defaultProfile or not applicableProfile:
            flash("Required fields are missing!")
            return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Build the new timings list
        updatedOverrideList = [{"defaultProfile": ft, "applicableProfile": tt} for ft, tt in zip(defaultProfile, applicableProfile)]

        profile_switch_queryset = ProfileSwitch.objects( status=1).first()
        if not profile_switch_queryset:
            flash("No Profile Switches found!")
            return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Find and update the matching record in overridesDatesList
        overridesProfileList = profile_switch_queryset.overridesProfileList
        for override in overridesProfileList:
            if override["overrideDate"] == overrideDate:  # Match the date
                override["overrideList"] = updatedOverrideList  # Update timings list
                break
        else:
            flash("No matching override date found!")
            return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

        # Save the updated list back to the database
        profile_switch_queryset.update(overridesProfileList=overridesProfileList)

        flash("Override date updated successfully!")
        return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))

    except Exception as e:
        app.logger.error(f"Error updating override date: {str(e)}")
        flash("An error occurred while updating the override date.")
        return redirect(url_for("patterns_configuarations.dynamic_profile_switch",redirectval=redirectTo))