from appservices.common.util import *
from appservices.common.form_schemas import *

bank_codes = Blueprint("bank_codes",__name__)



@bank_codes.route("/bank_codes_list", methods=["POST", "GET"])
@adminid_access_token_required
def bank_codes_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    
    bankCodesList = []
    apiList = []
    banksList = []
    bankMasterList = []
    transactionApisList = []
    bankCodesPagination = ""
    snoCount=0
    bankCodesPage=""
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"), "bankcodesPermissions")
    form=BankCodesSearchForm(request.args)
    if "view" in permissionsList:
        try:
         
            transactionApiId = request.args.get("transactionApiId", "")
            bankSearchId = request.args.get("bankSearchId", "")
            filters = Q(status__in=[0, 1])
            pg_queryset = (
                TransactionAPI.objects(filters)
                .only("id","apiName")
                .order_by("-id")
            )
            transactionApisList=list(pg_queryset)
           
            banks_queryset = (
                MasterIFSCBank.objects(filters)
                .only("id","bankName")
                .order_by("-id")
            )
            bankMasterList=list(banks_queryset)
            bankCodesPage = request.args.get(get_page_parameter('bankCodesPage'), type=int, default=1)

            per_page = 20
            start = (bankCodesPage - 1) * per_page
            total_count = 0

            filters = Q(status__in=[0, 1])
            if form.validate():
                if transactionApiId:
                    filters &=Q(transactionApiIdsList__in=[ObjectId(transactionApiId)])
                if bankSearchId:
                    filters &=Q(bankId=bankSearchId)
                total_count=BankCodes.objects(filters).count()

                # total_pages = math.ceil(total_count / per_page) if total_count else 1
                # if total_count == 0 or bankCodesPage > total_pages or bankCodesPage < 1:
                #     bankCodesPage = 1
                #     start = 0
                # else:
                #     start = (bankCodesPage - 1) * per_page

                bank_codes_queryset=(
                BankCodes.objects(filters)
                .only("id","bankId","transactionApiIdsList","bankCode","createdOn","status")
                .order_by("-id")
                .skip(start)
                .limit(per_page)
                )
                bankCodesList=list(bank_codes_queryset)
            else:
                bankCodesList=[]
                print("form errors",form.errors)
                total_count = 0
                bankCodesPage = 1
                start = 0
                # flash("Search validation failed","danger")
            snoCount = start
                   

         

            
            bankCodesPagination = Pagination(bankCodesPage=bankCodesPage, total=total_count, page_parameter="bankCodesPage", per_page=per_page, alignment="right", record_name="bankCode", href=f"?transactionApiId={transactionApiId}&bankSearchId={bankSearchId}&bankCodesPage={{0}}")

            ############################################################
            # Category Dropdown List
            ############################################################
            # api_queryset = TransactionAPI.objects(status__in=[0, 1]).order_by('sorting')
            # for each_api in api_queryset:

            #     api_dict = fetching_transaction_api_details(each_api)
            #     apiList.append(api_dict)

            # banks_queryset = MasterIFSCBank.objects(status__in=[0, 1]).order_by('sorting')
            # for each_bank in banks_queryset:

            #     bank_dict = fetching_master_ifsc_bank_details(each_bank)
            #     banksList.append(bank_dict)

            
            # print("transactionApiId",transactionApiId)
            return render_template("super_admin_templates/bank_codes_list.html",
                bankCodesPagination=bankCodesPagination,
                banksList=banksList,
                bankCodesList=bankCodesList,
                # apiList=apiList,
                bankSearchId=bankSearchId,
                transactionApisList=transactionApisList,
                bankMasterList=bankMasterList,
                transactionApiId=transactionApiId,
                # redirectval=redirectval,
                snoCount=snoCount,
                bankCodesPage=bankCodesPage,
                form=form,
            )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            flash("Unable to fetch Bank Codes.", "danger")
            return render_template("super_admin_templates/bank_codes_list.html",
                bankCodesPagination=bankCodesPagination,
                banksList=banksList,
                bankMasterList=bankMasterList,
                # apiList=apiList,
                transactionApiId=transactionApiId,
                bankSearchId=bankSearchId,
                # redirectval=redirectval,
                bankCodesPage=bankCodesPage,
                snoCount=snoCount,
                form=form,
            )
    else:
        flash("The staff member does not have permission to view Bank Codes!", "danger")
        return redirect(url_for("admin.dashboard"))


@bank_codes.route("/add_bank_code", methods=["POST", "GET"])
@adminid_access_token_required
@csrf_protect
def add_bank_code():
    data_status={"responseStatus":0,"result":""}
    try:
        if not session.get("adminId"):
            flash("session expired.Please login again.")
            data_status["responseStatus"]=4
            return data_status
        
        adminId = session.get("adminId")
        csrf_token = request.form.get("csrf_token")
        print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
        latitude = request.form.get("latitude", "")
        longitude = request.form.get("longitude", "")
        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,"bankcodesPermissions")
        if "add" in permissionsList:
            if request.method == "POST":
                bankId = request.form.get("bankId", "")
                bankCode = request.form.get("bankCode", "")
                transactionApiIdsList = request.form.getlist("transactionApiIdsList")
                # print(transactionApiIdsList,"((((((((((((((((transactionApiIdsList))))))))))))))))")
                # The date format for the input type "date" is "YYYY-MM-DD"
                # print("**********************",bankId,transactionApiIdsList)
                # print("((((((((((((((((((BankCode))))))))))))))))))",bankCode)
                jsonData = request.form.to_dict(flat=True)
                requestData = [jsonData]
                updatedrequestData = [jsonData]
                form = BankCodeForm()
                if form.validate_on_submit():
                    
                    # if bankCode and not is_valid_alphanumeric_without_specialCharacters(bankCode):
                    #     flash("Bank Code must contain only alphanumeric characters!")
                    #     return redirect(url_for("bank_codes.bank_codes_list"))

                    if bankId and transactionApiIdsList:
                        try:
                            admin_queryset = SuperAdmin.objects(id=adminId, status=1).first()
                            if admin_queryset:
                                message=admin_queryset.userName+" bank code created successfully!"
                                save_admin_log_table = save_admin_logs_data(adminId,None,None,"add_bank_code","create",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude) 

                            bank_codes_table = BankCodes(
                                adminId=adminId,
                                bankId=bankId,
                                transactionApiIdsList=transactionApiIdsList,
                                bankCode=bankCode,
                                createdOn=datetime.datetime.now(),
                                status=1,       
                            )
                            save_table = bank_codes_table.save()  
                            # bankCodeId = str(bank_codes_table.id)

                            flash("Bank Code has been saved successfully.", "success")
                            data_status['responseStatus']=1
                            return data_status
                        except Exception as e:
                            flash("Unable to save the Bank Code.", "danger")
                            app.logger.error(traceback.format_exc())
                            data_status['responseStatus']=4
                            return data_status
                    else:
                        data_status['responseStatus']=2
                        data_status['result']="Required fields are missing!!"
                        return data_status
                else:
                    data_status['result']=form.errors
                    return data_status
            else:
                flash("Invalid request.Please try again.","danger")
                data_status['responseStatus']=4
                return data_status 
        else:
            flash("The staff member does not have permission to create a Bank Code.", "danger")
            data_status['responseStatus']=4
            return data_status
    
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to add the Bank Code.", "danger")
        data_status['responseStatus']=4
        return data_status


@bank_codes.route("/update_bank_code_status",methods=["POST","GET"])
@adminid_access_token_required
def update_bank_code_status():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")

    bankCodesPage=request.args.get("bankCodesPage")
    bankSearchId=request.args.get("bankSearchId")
    transactionApiId=request.args.get("transactionApiId")
    redirectTo=url_for("bank_codes.bank_codes_list",bankCodesPage=bankCodesPage,bankSearchId=bankSearchId,transactionApiId=transactionApiId)
    latitude = request.args.get("latitude", "")
    longitude = request.args.get("longitude", "")
    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]
   
    permissionsList = check_permissions(session.get("adminId"),"bankcodesPermissions")
    if "edit" in permissionsList:
        bankCodeId = request.args.get("bankCodeId","")
        if bankCodeId:
            try:
                message=""
                bank_codes_queryset = BankCodes.objects(id=bankCodeId,status__nin=[2]).first()
                if bank_codes_queryset:
                    existing_record = bank_codes_queryset.to_json()
                    requestData = [existing_record]
                    admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                    if bank_codes_queryset.status == 0:
                        bank_codes_queryset.update(status=1)
                        flash("Bank Code has been activated successfully.", "success")
                        message=admin_queryset.userName+" bank code activated successfully!"
                    elif bank_codes_queryset.status == 1:
                        bank_codes_queryset.update(status=0)
                        flash("Bank Code has been deactivated successfully.", "success")
                        message=admin_queryset.userName+" bank code deactivated successfully!"
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_bank_code_status","updatestatus",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                    return redirect(redirectTo)
                else:
                    flash("Invalid ID provided.", "danger")
                    return redirect(url_for(redirectTo))
            except Exception as e:
                flash("Unable to update the status", "danger")
                app.logger.error(traceback.format_exc())
                return redirect(redirectTo)
        else:
            return redirect(redirectTo)
    else:
        flash("The staff member does not have permission to update Bank Code status.", "danger")
        return redirect(redirectTo)



# Update scheme
@bank_codes.route("/update_bank_code",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def update_bank_code():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        flash("session Expired.")
        data_status["responseStatus"]=4
        return data_status
    adminId=session.get("adminId")  
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    latitude = request.form.get("latitude", "")
    longitude = request.form.get("longitude", "")
    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()

    # date_format = "%Y-%m-%d"
    permissionsList = check_permissions(session.get("adminId"),"bankcodesPermissions")
    if "edit" in permissionsList:
        try:
            bankCodeId = request.args.get("bankCodeId","")
           
            if bankCodeId and request.method == "POST":
                bankId = request.form.get("bankId","")
                transactionApiIdsList = [ObjectId(api_id) for api_id in request.form.getlist("transactionApiIdsList")]
                bankCode = request.form.get("bankCode","")
                
                jsonData = request.form.to_dict(flat=True)

                form = BankCodeForm(request.form, current_id=bankCodeId)

                if form.validate_on_submit():
                    # if bankCode and not is_valid_alphanumeric_without_specialCharacters(bankCode):
                    #     flash("Bank Code must contain only alphanumeric characters!")
                    #     return redirect(url_for("bank_codes.bank_codes_list"))

                    bank_codes_queryset = BankCodes.objects(id=bankCodeId).first()
                    admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                    
                    existing_record = bank_codes_queryset.to_json()
                    message=admin_queryset.userName+" bank code updated successfully!"
                    requestData=[bank_codes_queryset]
                    updatedrequestData=[jsonData]
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_bank_code","update",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                    if bank_codes_queryset:
                        bank_codes_queryset.update(
                            transactionApiIdsList=transactionApiIdsList,
                            bankId=ObjectId(bankId),
                            bankCode=bankCode,
                            )
                        flash("The Bank Code has been updated successfully.", "success")
                        data_status["responseStatus"]=1
                        return data_status
                    else:
                        flash("Invalid ID provided.", "danger")
                        data_status["responseStatus"]=4
                        return data_status
                else:
                    data_status["result"]=form.errors
                    return data_status
            else:
                flash("Invalid request. Please try again.", "danger")
                data_status["responseStatus"]=4
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to update the Bank Code."
            flash(error, "danger")
            data_status["responseStatus"]=4
            return data_status
    else:
        flash("The staff member does not have permission to update Bank Codes.", "danger")
        data_status["responseStatus"]=4
        return data_status


# Delete scheme
@bank_codes.route("/delete_bank_code",methods=["GET"])
@adminid_access_token_required
def delete_bank_code():
    try:
        existing_record=""
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId=session.get("adminId")

        bankCodesPage=request.args.get("bankCodesPage")
        bankSearchId=request.args.get("bankSearchId")
        transactionApiId=request.args.get("transactionApiId")
        redirectTo=url_for("bank_codes.bank_codes_list",bankCodesPage=bankCodesPage,bankSearchId=bankSearchId,transactionApiId=transactionApiId,)
        latitude = request.args.get("latitude", "")
        longitude = request.args.get("longitude", "")
        loginBrowser = request.headers.get("Sec-Ch-Ua")
        userAgent=""
        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)

        requestData = [existing_record]
        updatedrequestData = [jsonData]
        permissionsList = check_permissions(session.get("adminId"),"bankcodesPermissions")
        if "delete" in permissionsList:
            if request.method == "GET":
                bankCodeId = request.args.get("bankCodeId","")
                bank_codes_queryset = BankCodes.objects(id=bankCodeId,status__in=[0,1]).first()
                if bank_codes_queryset:
                    admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                    existing_record = bank_codes_queryset.to_json()
                    bank_codes_queryset.update(status=2)
                    flash("The Bank Code has been deleted successfully.", "success")

                    message=admin_queryset.userName+" bank code deleted successfully!"
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"delete_bank_code","delete",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                    return redirect(redirectTo)
                else:
                    flash("Invalid ID provided.", "danger")
                    return redirect(redirectTo)
        else:
            flash("The staff member does not have permission to delete Bank Codes.", "danger")
            return redirect(redirectTo)
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to delete the Bank Code. Please try again.", "danger")
        return redirect(redirectTo)