from appservices.common.util import *

def decode_recursive(data):
    if isinstance(data, dict):  # If it's a dictionary, decode its keys and values recursively
        return {
            decode_recursive(key): decode_recursive(value)
            for key, value in data.items()
        }
    elif isinstance(data, list):  # If it's a list, decode each item recursively
        return [decode_recursive(item) for item in data]
    elif isinstance(data, bytes):  # If it's bytes, decode it
        return data.decode()
    else:  # If it's anything else, return as-is
        return data
def PayuSha512Hash(requstDataDict,salt):
    try:
        hashdata = requstDataDict.get("key")+"|"+requstDataDict.get("command")+"|"+requstDataDict.get("var1")+"|"+salt
        hashed = hashlib.sha512(hashdata.encode('utf-8')).hexdigest()
        print(hashed,"(((((((((PAY U Hased)))))))))")
        return hashed
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return False

def PayuSha512HashParams(requestDataDict, salt):
    try:
        # Concatenate the required fields in the correct order for PayU hashing
        hash_sequence = (
            f"{requestDataDict['key']}|{requestDataDict['txnid']}|{requestDataDict['amount']}|"
            f"{requestDataDict['productinfo']}|{requestDataDict['firstname']}|{requestDataDict['email']}|"
            f"{requestDataDict.get('udf1', '')}|{requestDataDict.get('udf2', '')}|{requestDataDict.get('udf3', '')}|"
            f"{requestDataDict.get('udf4', '')}|{requestDataDict.get('udf5', '')}||||||{salt}"
        )

        # Generate SHA-512 hash
        hashed = hashlib.sha512(hash_sequence.encode('utf-8')).hexdigest()
        print(hashed, "(((PAY U Hashed)))")
        return hashed
    except Exception as e:
        print("Error generating hash:", traceback.format_exc())
        return False


def check_payu_bin(get_api_key,get_salt,get_base_url,var1):
    payucardbincheckResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        responseBody = {
        "key": get_api_key,
        "command": "check_isDomestic",
        "var1": var1
        }
        print(responseBody)
        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {"accept": "application/json",'Content-Type': 'application/x-www-form-urlencoded'}

        responseBody.update({
            "hash":hashvalue
            })
        print(responseBody,"responseBody")
        try:
            response = requests.post(get_base_url, data=responseBody, headers=headers)
            jsonResponseData = response.json()
            print(jsonResponseData,"jsonResponseData")
            if response.status_code == 200:
                payucardbincheckResponseDict["responseStatus"] = 1
                payucardbincheckResponseDict["data"] = jsonResponseData
            return payucardbincheckResponseDict
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payucardbincheckResponseDict["result"]="Our banking partner server is down please try after sometime!!"

    except Exception as e:
        app.logger.error(traceback.format_exc())
    return payucardbincheckResponseDict

def check_payu_binInfo(get_api_key,get_salt,get_base_url,cardNumber):
    payucardbincheckResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        responseBody = {
        "key": get_api_key,
        "command": "getBINInfo",
        "var1": "1",
        "var2":cardNumber
        }
        print(responseBody)
        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {"accept": "application/json",'Content-Type': 'application/x-www-form-urlencoded'}

        responseBody.update({
            "hash":hashvalue
            })
        try:
            finalDict={}
            response = requests.post(get_base_url, data=responseBody, headers=headers)
            jsonResponseData = response.json()
            print(jsonResponseData,"check_payu_bin")
            if response.status_code == 200:
                if jsonResponseData.get('status',0)==1:
                    payucardbincheckResponseDict["responseStatus"] = 1
                    dataresponse=jsonResponseData.get('data')
                    finalDict={
                    'isDomestic':dataresponse.get('bins_data').get('is_domestic'),
                    'additonalCardType':dataresponse.get('bins_data').get('additonalCardType'),
                    'issuingBank':dataresponse.get('bins_data').get('issuing_bank'),
                    'cardCategory':dataresponse.get('bins_data').get('category'),
                    'cardType':dataresponse.get('bins_data').get('card_type')
                    }
                    payucardbincheckResponseDict["data"] = finalDict
                else:
                    payucardbincheckResponseDict["result"] = jsonResponseData.get('msg')
            return payucardbincheckResponseDict
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payucardbincheckResponseDict["result"]="Our banking partner server is down please try after sometime!!"

    except Exception as e:
        app.logger.error(traceback.format_exc())
    print(payucardbincheckResponseDict,"payucardbincheckResponseDict")
    return payucardbincheckResponseDict

def payu_refund(get_api_key,get_salt,get_base_url,original_txnId,transaction_id,amount,callback_url):
    payinPaymentstatusResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        print(get_api_key,"get_api_key")
        print(get_salt,"get_salt")
        responseBody = {
            "key": get_api_key,
            "command": "cancel_refund_transaction",
            "var1": original_txnId,
            "var2": transaction_id,
            "var3": amount,
            "var5": callback_url,
        }
        print(responseBody,"responseBody")

        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {
    "accept": "application/json",
    "content-type": "application/x-www-form-urlencoded"
    }
        responseBody.update({
            "hash":hashvalue
            })
        try:
            print("request body",responseBody)
            response = requests.post(get_base_url, data=responseBody, headers=headers)
            print(response.text,"********PAY U PAY response***********")
            # jsonResponseData = json.loads(response.text)
            # print(jsonResponseData,"********PAY U PAY IN ORDER STATUS DATA***********")
            # transactionData=[jsonResponseData]
            
            deserialized_data = phpserialize.loads(response.text.encode('utf-8'))
            print("((((((((deserialized_data))s))))))", deserialized_data)

            decoded_data = {
                key.decode() if isinstance(key, bytes) else key:
                value.decode() if isinstance(value, bytes) else value
                for key, value in deserialized_data.items()
                }

            print("((((((decoded_data))))))",decoded_data)
            responseStatus=0
            status="Failed"
            message=""
            transaction_update_id=""
            bankRefNo=""
            mihpayid=""

            msg=decoded_data.get("msg")
            if decoded_data.get("status") == 1:
                responseStatus = 1
                status="Success"
                bankRefNo = decoded_data.get("bank_ref_num")
                message=decoded_data.get("msg")
                mihpayid=decoded_data.get("mihpayid","")
                # transaction_update_id =  decoded_data.get("txn_update_id")
            elif decoded_data.get("status") == 0:
                message=decoded_data.get("msg")

            payucardbincheckResponseDict = {
                "responseStatus": responseStatus,
                "status": status,
                "mihpayid":mihpayid,    
                "bankRefNo": bankRefNo,
                "transaction_update_id": transaction_update_id,
                "responseData": decoded_data

            }
            return payucardbincheckResponseDict
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payinPaymentstatusResponseDict["result"]="Our banking partner server is down please try after sometime!!"
            return payinPaymentstatusResponseDict



        
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return payinPaymentstatusResponseDict



def payu_refund_status(get_api_key,get_salt,get_base_url,request_id):
    payinPaymentstatusResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        print(get_api_key,"get_api_key")
        print(get_salt,"get_salt")
        responseBody = {
            "key": get_api_key,
            "command": "check_action_status",
            "var1": request_id,
            "var2": "",
        }
        print(responseBody,"responseBody")

        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {
    "accept": "application/json",
    "content-type": "application/x-www-form-urlencoded"
    }
        responseBody.update({
            "hash":hashvalue
            })
        try:
            print("request body",responseBody)
            response = requests.post(get_base_url, data=responseBody, headers=headers)
            print(response.text,"********PAY U PAY response***********")
            # jsonResponseData = json.loads(response.text)
            # print(jsonResponseData,"********PAY U PAY IN ORDER STATUS DATA***********")
            # transactionData=[jsonResponseData]
            
            deserialized_data = phpserialize.loads(response.text.encode('utf-8'))
            print("((((((((deserialized_data))s))))))", deserialized_data)

            decoded_data = decode_recursive(deserialized_data)

            print("((((((decoded_data))))))",decoded_data)
            responseStatus=0
            status="Failed"
            message=""
            transaction_details=""

            msg=decoded_data.get("msg")
            if decoded_data.get("status") == 1:
                responseStatus = 1
                status="Success"
                message=decoded_data.get("msg")
                transaction_details=decoded_data.get("transaction_details","")
                
            elif decoded_data.get("status") == 0:
                message=decoded_data.get("msg")
                transaction_details=decoded_data.get("transaction_details","")
            payucardbincheckResponseDict = {
                "responseStatus": responseStatus,
                "status": status,
                "transaction_details": transaction_details,
                "responseData": decoded_data

            }
            return payucardbincheckResponseDict
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payinPaymentstatusResponseDict["result"]="Our banking partner server is down please try after sometime!!"
            return payinPaymentstatusResponseDict
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return payinPaymentstatusResponseDict

def check_payu_payin_paymentstatus(get_api_key,get_salt,get_base_url,pgOrderId):
    payinPaymentstatusResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        print(get_api_key,"get_api_key")
        responseBody = {
        "key": get_api_key,
        "command": "verify_payment",
        "var1": pgOrderId
        }
        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        responseBody.update({
            "hash":hashvalue
            })
        payload="key="+str(get_api_key)+"&command=verify_payment&var1="+str(pgOrderId)+"&hash="+str(hashvalue)
        try:
            response = requests.post(get_base_url, data=payload, headers=headers)
            jsonResponseData = json.loads(response.text)
            print(jsonResponseData,"********PAY U PAY IN ORDER STATUS DATA***********")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payinPaymentstatusResponseDict["result"]="Our banking partner server is down please try after sometime!!"

        transactionData=[jsonResponseData]
        bankRefNo = ""

        if jsonResponseData.get('status')==0:
            payinPaymentstatusResponseDict = {
            "status":"failed",
            "message":"failed"
            }
        else:
            paymentStatus=3
            status="pending"
            if "mihpayid" in jsonResponseData.get('transaction_details'):
                payinPaymentstatusResponseDict = {
                "status":"failed",
                "message":"failed"
                }
            else:
                transaction_details=jsonResponseData.get('transaction_details').get(str(pgOrderId))
                print("transaction_details",transaction_details)
                if jsonResponseData.get('status')==1 and transaction_details.get("status")=="success":
                    paymentStatus=1
                    status = "success"
                    bankRefNo=transaction_details.get("bank_ref_num")
                elif jsonResponseData.get('status')==1 and transaction_details.get("status")=="failed":
                    status = "failed"
                    paymentStatus=0
                else:
                    status="pending"

                cardmasked = ""
                customerVpa = ""
                cardType = ""
                bankName=""
                bankRefId=str(transaction_details.get("bank_ref_no"))
                mihpayid=str(transaction_details.get("mihpayid"))
                if transaction_details.get("mode")=="UPI":
                    customerVpa = transaction_details.get("field1")
                elif transaction_details.get("mode")=="CC":
                    paymentMode="CREDIT CARD"
                    cardType=transaction_details.get("card_type")
                    customerVpa=transaction_details.get("bankcode")
                    cardmasked=transaction_details.get("card_no")
                elif transaction_details.get("mode")=="DC":
                    paymentMode="DEBIT CARD"
                    cardType=transaction_details.get("bankcode")
                    cardmasked=transaction_details.get("card_no")
                elif transaction_details.get("mode")=="NB":
                    paymentMode="NET BANKING"
                    customerVpa=transaction_details.get("bankcode")
                elif transaction_details.get("mode")=="CASH":
                    paymentMode="WALLET"
                    customerVpa=transaction_details.get("bankcode")


                payinPaymentstatusResponseDict = {
                "responseStatus":1,
                "paymentStatus":paymentStatus,
                "status":status,
                "currency":"INR",
                "message":transaction_details.get("status"),
                "bankRefNo":bankRefId,
                "cardType":cardType,
                "customerVpa":customerVpa,
                "cardmasked":cardmasked,
                'payment_mode':paymentMode,
                'pgOrderId':mihpayid,
                'response_code':jsonResponseData.get("status"),
                'orderAmount':transaction_details.get("amt"),
                "transactionData":transactionData
                }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return payinPaymentstatusResponseDict


def payu_transaction_refund(get_api_key,get_salt,get_refund_base_url,amount,payuId,refUniqueId,refundwebhookurl):
    payinPaymentstatusResponseDict = {"responseStatus":0,"result":""}
    responseBody = {}
    try:
        print(get_api_key,"get_api_key")
        responseBody = {
        "key": get_api_key,
        "command": "cancel_refund_transaction",
        "var1": str(payuId),
        "var2": str(refUniqueId),
        "var3": amount,
        "var5": str(refundwebhookurl)
        }
        hashvalue = PayuSha512Hash(responseBody,get_salt)
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        responseBody.update({
            "hash":hashvalue
            })
        payload="key="+str(get_api_key)+"&command=cancel_refund_transaction&var1="+str(payuId)+"&var2="+str(refUniqueId)+"&var3="+str(amount)+"&var5="+str(refundwebhookurl)+"&hash="+str(hashvalue)
        try:
            response = requests.post(get_refund_base_url, data=payload, headers=headers)
            jsonResponseData = json.loads(response.text)
            print(jsonResponseData,"********PAY U PAY IN ORDER STATUS DATA***********")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            payinPaymentstatusResponseDict["result"]="Our banking partner server is down please try after sometime!!"

        transactionData=[jsonResponseData]
        bankRefNo = ""

        if jsonResponseData.get('status')==0:
            payinPaymentstatusResponseDict = {
            "status":"failed",
            "message":"failed"
            }
        else:
            paymentStatus=3
            status="pending"
            if "mihpayid" in jsonResponseData.get('transaction_details'):
                payinPaymentstatusResponseDict = {
                "status":"failed",
                "message":"failed"
                }
            else:
                transaction_details=jsonResponseData.get('transaction_details').get(str(pgOrderId))
                print("transaction_details",transaction_details)
                if jsonResponseData.get('status')==1 and transaction_details.get("status")=="success":
                    paymentStatus=1
                    status = "success"
                    bankRefNo=transaction_details.get("bank_ref_num")
                elif jsonResponseData.get('status')==1 and transaction_details.get("status")=="failed":
                    status = "failed"
                    paymentStatus=0
                else:
                    status="pending"

                cardmasked = ""
                customerVpa = ""
                cardType = ""
                bankName=""
                bankRefId=str(transaction_details.get("bank_ref_no"))
                mihpayid=str(transaction_details.get("mihpayid"))
                if transaction_details.get("mode")=="UPI":
                    customerVpa = transaction_details.get("field1")
                elif transaction_details.get("mode")=="CC":
                    paymentMode="CREDIT CARD"
                    cardType=transaction_details.get("card_type")
                    customerVpa=transaction_details.get("bankcode")
                    cardmasked=transaction_details.get("card_no")
                elif transaction_details.get("mode")=="DC":
                    paymentMode="DEBIT CARD"
                    cardType=transaction_details.get("bankcode")
                    cardmasked=transaction_details.get("card_no")
                elif transaction_details.get("mode")=="NB":
                    paymentMode="NET BANKING"
                    customerVpa=transaction_details.get("bankcode")
                elif transaction_details.get("mode")=="CASH":
                    paymentMode="WALLET"
                    customerVpa=transaction_details.get("bankcode")


                payinPaymentstatusResponseDict = {
                "responseStatus":1,
                "paymentStatus":paymentStatus,
                "status":status,
                "currency":"INR",
                "message":transaction_details.get("status"),
                "bankRefNo":bankRefId,
                "cardType":cardType,
                "customerVpa":customerVpa,
                "cardmasked":cardmasked,
                'payment_mode':paymentMode,
                'pgOrderId':mihpayid,
                'response_code':jsonResponseData.get("status"),
                'orderAmount':transaction_details.get("amt"),
                "transactionData":transactionData
                }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return payinPaymentstatusResponseDict