from appservices.common.util import *
from appservices.common.form_schemas import *
import math

service_charges = Blueprint("service_charges",__name__)


from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, SelectField, SelectMultipleField, BooleanField
from wtforms.validators import DataRequired, Length, Regexp, NumberRange, Optional, ValidationError


def fetching_service_charges_details(service_charge_queryset):
    service_charge_dict = {}
    try:
        service_charge_dict={
        "id":str(service_charge_queryset.id),
        "chargeType":service_charge_queryset.chargeType,
        "amountType":service_charge_queryset.amountType,
        "chargeName":service_charge_queryset.chargeName,
        "amount":service_charge_queryset.amount,
        "gstInclude":service_charge_queryset.gstInclude,
        "gstValue":service_charge_queryset.gstValue,
        "tdsInclude":service_charge_queryset.tdsInclude,
        "tdsValue":service_charge_queryset.tdsValue,
        }
        if service_charge_queryset.status==1:
            service_charge_dict["actionText"] = "Active"
        else:
            service_charge_dict["actionText"] = "Deactive"

        if service_charge_queryset.createdOn:
            service_charge_dict["createdOn"] = service_charge_queryset.createdOn.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
        else:
            service_charge_queryset["createdOn"] = ""
            
         
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return service_charge_dict


@service_charges.route("/get_service_charge_list",methods=["POST","GET"])
@adminid_access_token_required
def get_service_charge_list():
    if not session.get("adminId"):
        flash("Session expired. Please log in again.", "danger")
        return redirect("admin_login")
    serviceChargeList = []
    pagination = None
    adminId = session.get("adminId")
    search_element=""
    snoCount=0
    servicePage=None
    permissionsList = check_permissions(session.get("adminId"),"serviceChargePermissions")
    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo","serviceCharges")
            if redirectTo:
                redirectval = redirectTo
            else:
                redirectval = "serviceCharges"
            form = serviceFormSearch(request.args)
            search_element = request.args.get("search_element", "").strip()
            servicePage = request.args.get(get_page_parameter("servicePage"), type=int, default=1)
           
            per_page = 20
            start = (servicePage - 1) * per_page
            total_count=0
            filters = Q(status__in=[0, 1])
            
            
            if form.validate():
                if search_element:
                    filters &= Q(chargeName__icontains=search_element)
                total_count = ServiceCharges.objects(filters).count()
                temp = math.ceil(total_count/per_page)
                if servicePage>temp:
                    servicePage=1
                    start = 0

                service_charges_queryset = (
                    ServiceCharges.objects(filters)
                    .only("id", "chargeName", "chargeType", "amountType","amount","gstInclude","gstValue","tdsInclude","tdsValue","status")
                    .order_by("-id")
                    .skip(start)
                    .limit(per_page)
                )
                serviceChargeList=list(service_charges_queryset)
            else:
                serviceChargeList=[]
                
           
            snoCount = start
            

            # service_charges_queryset = ServiceCharges.objects(status__in=[0,1]).order_by("-id")
            # if search_element:
            #     service_charges_queryset = service_charges_queryset.filter(Q(chargeType__icontains=search_element) | Q(chargeName__icontains=search_element))


            # # Get the current page from the query parameters
            # page = request.args.get(get_page_parameter(), type=int, default=1)

            # per_page = 20  # Number of items per page

            # # Query the database for the current page's data
            # total_count = service_charges_queryset.count()

            # start = (page - 1) * per_page

            # end = min(start + per_page, total_count)

            # total_service_charges = service_charges_queryset[start:end]
            
            # snoCount = start
            # for each_service_charge in total_service_charges:
            #     snoCount +=1
            #     service_charge_dict = fetching_service_charges_details(each_service_charge)
            #     service_charge_dict["snoCount"]=snoCount
            #     serviceChargeList.append(service_charge_dict)

            # Pagination object for rendering pagination controls in the template
            pagination = Pagination(servicePage=servicePage, total=total_count, per_page=per_page,page_parameter ="servicePage", alignment="right", record_name="serviceCharges",href=f"?search_element={search_element}&servicePage={{0}}")

            return render_template("super_admin_templates/service_charges_list.html",
                pagination=pagination,
                serviceChargeList=serviceChargeList,
                redirectval=redirectval,
                search_element=search_element,
                snoCount=snoCount,
                servicePage = servicePage,
                form=form,
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch service charge details"
            return render_template("super_admin_templates/service_charges_list.html", 
                error=error,
                pagination=pagination,
                serviceChargeList=serviceChargeList,
                search_element=search_element,
                snoCount=snoCount,
                servicePage = servicePage,
                form=form,
                )
    else:
        flash("The staff member does not have permission to view Service charge details.", "danger")
        return redirect(url_for("admin.dashboard"))
        # return render_template("super_admin_templates/bank_masters_list.html"




@service_charges.route("/add_service_charges",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def add_service_charges():
    data_status={"responseStatus":0,"result":""}
    try:
        if not session.get("adminId"):
            flash("Session expired Please login again.","danger")
            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,"serviceChargePermissions")
        if "add" in permissionsList:
            if request.method == "POST":
                otp_check_id = request.form.get("otpLogid", "")
                defaultVerificationId = request.form.get("defaultVerificationId", "")

                print("otp_check_id",otp_check_id)
                if not otp_check_id:
                    flash("Invalid Request.","danger")
                    data_status["responseStatus"]=4
                    return data_status
                
                otpcheck_queryset = OtpChecks.objects(adminId=adminId,defaultVerificationField=defaultVerificationId, id=str(otp_check_id), status=1).first()
                
                if not otpcheck_queryset:
                    flash("Invalid Request.","danger")
                    data_status["responseStatus"]=4
                    return data_status
                # Update OTP status to 2 after verification
                otpcheck_queryset.update(status=2)
 
                chargeType = request.form.get("chargeType","")
                amountType = request.form.get("amountType","")
                chargeName = request.form.get("chargeName","")
                amount = request.form.get("amount","")
                gstInclude = request.form.get("gstInclude","")
                gstValue = request.form.get("gstValue",0)
                tdsInclude = request.form.get("tdsInclude","")
                tdsValue = request.form.get("tdsValue",0)

                # if chargeName and not is_valid_alphanumeric(chargeName):
                #     flash("Charge Name must contain only alphanumeric characters, spaces, and specific special characters:@#$()+_-/")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if amount and not is_valid_numeric(amount):
                #     flash("Amount must contain only numeric characters!")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if gstValue and not is_valid_txn_limit(gstValue):
                #     flash("Please enter a valid Gst Value")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if tdsValue and not is_valid_txn_limit(tdsValue):
                #     flash("Please enter a valid Tds Value")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                jsonData = request.form.to_dict(flat=True)
                requestData = [jsonData]
                updatedrequestData = [jsonData]
                form = ServiceChargesForm()
                if form.validate_on_submit():
                    if chargeType and amountType and amount: 
                        try:
                            admin_queryset = SuperAdmin.objects(id=str(adminId),status=1).first()
                            if admin_queryset:
                                message=admin_queryset.userName+" "+chargeType+" service charges created successfully!"
                                save_admin_log_table = save_admin_logs_data(adminId,None,None,"add_service_charges","create",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude) 
                                

                            service_charge_table = ServiceCharges(
                                adminId=adminId,
                                chargeType=chargeType,
                                amountType = amountType,
                                chargeName = chargeName,
                                amount = amount,
                                gstInclude = gstInclude,
                                gstValue = gstValue,
                                tdsInclude = tdsInclude,
                                tdsValue = tdsValue,
                                createdOn = datetime.datetime.now(),
                                status = 1,
                                )
                            save_table = service_charge_table.save()
                            serviceChargeId = str(save_table.id)

                            flash("Service Charges Saved Successfully","success")
                            data_status['responseStatus']=1
                            return data_status
                        except Exception as e:
                            flash("Unable to save service charge details","danger")
                            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.","danger")
                data_status['responseStatus']=4
                return data_status       
        else:
            flash("The staff member does not have permission to create a Service Charges.", "danger")
            data_status['responseStatus']=4
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to save service charge details!!"
        flash("Unable to save service charges.", "danger")
        data_status['responseStatus']=4
        return data_status




#Update master IFSC bank
@service_charges.route("/update_service_charges", methods=["POST", "GET"])
@adminid_access_token_required
@csrf_protect
def update_service_charges():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        flash("Session expired. Please log in again.", "danger")
        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()
    
    # serviceChargeId = request.args.get("serviceChargeId","")
    
    try:
        permissionsList = check_permissions(session.get("adminId"),"serviceChargePermissions")
        if "edit" in permissionsList:               
            serviceChargeId = request.args.get("serviceChargeId","")
            if request.method == "POST":
                form = ServiceChargesForm(request.form, current_id=serviceChargeId)
                
                if form.validate_on_submit():
                    
                    otp_check_id = request.form.get("otpLogid", "")
                    defaultVerificationId = request.form.get("defaultVerificationId", "")
                    print("otp_check_id",otp_check_id)
                    if not otp_check_id:
                        flash("Invalid Request","danger")
                        data_status['responseStatus']=4
                        return data_status
                    print("#######################################",adminId,otp_check_id)
                    otpcheck_queryset = OtpChecks.objects(adminId=adminId,defaultVerificationField=defaultVerificationId, id=str(otp_check_id), status=1).first()
                    
                    if not otpcheck_queryset:
                        flash("Invalid Request","danger")
                        data_status['responseStatus']=4
                        print("(((((((((((((((((((((((((((otpcheck_queryset)))))))))))))))))))))))))))",otpcheck_queryset)
                        return data_status
                    def safe_float(value):
                        try:
                            return float(value) if value.strip() else 0.0
                        except (ValueError, TypeError):
                            return 0.0
                    # Update OTP status to 2 after verification
                    otpcheck_queryset.update(status=2)
                    chargeType = request.form.get("chargeType","")
                    amountType = request.form.get("amountType","")
                    chargeName = request.form.get("chargeName","")
                    amount = request.form.get("amount",0)
                    gstInclude = request.form.get("gstInclude","")
                    gstValue = safe_float(request.form.get("gstValue", "0"))
                    tdsInclude = request.form.get("tdsInclude","")
                    tdsValue = safe_float(request.form.get("tdsValue", "0"))
                    remark = request.form.get("remark","")
                    jsonData = request.form.to_dict(flat=True)
                    
                    
                # if chargeName and not is_valid_alphanumeric(chargeName):
                #     flash("Charge Name must contain only alphanumeric characters, spaces, and specific special characters:@#$()+_-/")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if amount and not is_valid_numeric(amount):
                #     flash("Amount must contain only numeric characters!")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if gstValue and not is_valid_txn_limit(gstValue):
                #     flash("Please enter a valid Gst Value")
                #     return redirect(url_for("service_charges.get_service_charge_list"))

                # if tdsValue and not is_valid_txn_limit(tdsValue):
                #     flash("Please enter a valid Tds Value")
                #     return redirect(url_for("service_charges.get_service_charge_list"))
                    
                    
                    if chargeType and amountType and amount:
                        service_charges_queryset = ServiceCharges.objects(id=serviceChargeId, status__in=[0, 1]).first()
                        admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                        existing_record = service_charges_queryset.to_json()
                        message=admin_queryset.userName+" "+chargeType+" service charges updated successfully!"
                        requestData=[service_charges_queryset]
                        updatedrequestData=[jsonData]
                        save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_service_charges","update",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                        save_remarks_data=save_admin_remarks_data(serviceChargeId,adminId,remark,"serviceCharges") 
                        print("((((((((((((((((((((amount))))))))))))))))))))",amount)
                        if service_charges_queryset:
                            
                            print("@@@@@@@@@@@@@@",chargeType,amountType,chargeName,amount,gstInclude,gstValue,tdsInclude,tdsValue)
                            
                            service_charges_queryset.update(
                                chargeType = chargeType,
                                amountType = amountType,
                                chargeName = chargeName,
                                amount = amount,
                                gstInclude = gstInclude,
                                gstValue = gstValue,
                                tdsInclude = tdsInclude,
                                tdsValue = tdsValue,
                                )
                            
                            flash("Service Charges Updated Successfully","success")
                            data_status["responseStatus"]=1
                            return data_status
                        else:
                            flash("Invalid ID!","danger")
                            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", "danger")
                data_status["responseStatus"]=4
                return data_status
        else:
            flash("The staff member does not have permission to update Service charges.", "danger")
            data_status["responseStatus"]=4
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to update service charges details","danger")
        data_status["responseStatus"]=4
        return data_status


@service_charges.route("/update_service_charge_status",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def update_service_charge_status():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    servicePage = request.args.get("servicePage")
    search_element = request.args.get("search_element", "").strip()

    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()

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

    existing_record = ""
    updatedrequestData = [jsonData]

    form=RemarkForm()
    if form.validate_on_submit():

        permissionsList = check_permissions(session.get("adminId"),"serviceChargePermissions")
        if "edit" in permissionsList:
            serviceChargeId = request.args.get("serviceChargeId","")
            remark = request.form.get("remark","")

            if remark and not is_valid_alphanumeric(remark):
                flash("Remark must contain only alphanumeric characters, spaces, and specific special characters:@#$()+_-/","danger")
                return redirect(url_for("service_charges.get_service_charge_list"))

            if serviceChargeId and remark:
                try:
                    message=""
                    service_charges_queryset = ServiceCharges.objects(id=serviceChargeId).first()
                    existing_record = service_charges_queryset.to_json()
                    requestData = [existing_record]
                    if service_charges_queryset:
                        if service_charges_queryset.status == 0:
                            service_charges_queryset.update(status=1)
                            flash("Service Charges Activated Successfully","success")
                            message=service_charges_queryset.adminId.userName+" "+service_charges_queryset.chargeType+" Service Charges activated successfully!"
                        elif service_charges_queryset.status == 1:
                            service_charges_queryset.update(status=0)
                            flash("Service Charges Deactivated Successfully","success")
                            message=service_charges_queryset.adminId.userName+" "+service_charges_queryset.chargeType+" Service Charges deactivated successfully!"
                        save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_service_charge_status","updatestatus",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                        save_remarks_data=save_admin_remarks_data(serviceChargeId,adminId,remark,"serviceCharges")
                        data_status['responseStatus']=1
                        return data_status
                    else:
                        flash("Invaild id","danger")
                        data_status['responseStatus']=4
                        return data_status
                except Exception as e:
                    flash("Unable to update the status", "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:
            flash("The staff member does not have permission to update Service Charges status.", "danger")
            data_status['responseStatus']=4
            return data_status
    else:
        data_status['result']=form.errors
        return data_status
    
    