<?php


function generateCCAvenuePaymentLink($student, $pg_setup, $amount, $white_label_url,$userid, $key, $conn_rjllearning) {
  
     global $conn_rjllearning_specific;
  
    $pg_credentials = json_decode(aes128Decrypt($pg_setup['credentials'], $key), true);


    if (
        !$pg_credentials['merchant_data'] || 
        !$pg_credentials['access_code'] || 
        !$pg_credentials['working_key']
    ) {
        errorreturn("Incomplete CCAvenue credentials.");
    }
    
    // Generate the order_id using workspaceId first, followed by student details and finally time at the end
    global $workspace_id; // Replace this with your dynamic workspaceId
    $order_id = $workspace_id . '_' . $student['institution_id'] . '_' . $student['branch_id'] . '_' . $student['admission_number'] . '_' . time();



    $redirect_url = $pg_setup['return_url'];
    $cancel_url = $pg_setup['return_url'];
    $working_key = $pg_credentials['working_key'];
    $access_code = $pg_credentials['access_code'];
    $merchant_id = $pg_credentials['merchant_data'];
    
    $section_name=getSection($conn_rjllearning_specific, $student['institution_id'], $student['section_id']);
    $class_info=getClass($conn_rjllearning_specific, $student['institution_id'], $student['class_id']);
    $branch_name=getBranchInfo($conn_rjllearning_specific, $student['institution_id'], $student['branch_id'], $additional_data =  null);
    // Step 2: Prepare merchant data
    $merchant_data = [
    "merchant_id" => $pg_credentials['merchant_id'],
    "order_id" => $order_id,
    "currency" => "INR",
    "amount" => $amount,
    "redirect_url" => $redirect_url,
    "cancel_url" => $cancel_url,
    "language" => "EN",
     
    // Billing info
    "billing_name" => $student['name'],
    "billing_tel" => $student['mobile'],
    "billing_email" => $student['email'] ?? 'sample@email.com',
    "billing_address" => $student['address'] ?? '',
    "billing_city" => $student['city'] ?? '',
    "billing_zip" => $student['pincode'] ?? '',
    "billing_country" => "India",

    // Optional merchant fields
    "merchant_param1" => $student['admission_number'] ?? '',
    "merchant_param2" => $branch_name['name'] ?? '',
    "merchant_param3" => $class_info['class_name'] ?? '',
    "merchant_param4" => $section_name['section_name'] ?? '',
    "merchant_param5" => $student['user_id'] ?? '',
];


    // Convert to query string
    $merchant_query = http_build_query($merchant_data);

    // Step 3: Encrypt the data using Crypto.php
    $encRequest = ccavenueencrypt($merchant_query, $working_key);
    insertInitiatedTransaction($conn_rjllearning, $workspace_id, $student['institution_id'], $student['branch_id'], $pg_setup['id'], $order_id, $amount);
    
    $payment_data = [
        "encRequest" => $encRequest,
        "access_code" => $access_code,
        "pg_url" => "https://secure.ccavenue.com/transaction/transaction.do?command=initiateTransaction"
    ];
    // Then return payment data
    successreturn([
        "order_id" =>$order_id,
        "white_label_url" => $white_label_url,
        "json_encoded_data" => $payment_data,
        "gateway" => "ccavenue"
    ]);

}


function ccavenueencrypt($plainText, $key) {
    $key = pack('H*', md5($key));
    $initVector = pack('C*', 0x00, 0x01, 0x02, 0x03,
                              0x04, 0x05, 0x06, 0x07,
                              0x08, 0x09, 0x0A, 0x0B,
                              0x0C, 0x0D, 0x0E, 0x0F);
    $encryptedText = openssl_encrypt($plainText, "AES-128-CBC", $key, OPENSSL_RAW_DATA, $initVector);
    return bin2hex($encryptedText);
}



function ccavenuedecrypt($encryptedText,$key)
	{
		$key = hextobin(md5($key));
		$initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
		$encryptedText = hextobin($encryptedText);
		$decryptedText = openssl_decrypt($encryptedText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $initVector);
		return $decryptedText;
	}
	

	 function pkcs5_pad ($plainText, $blockSize)
	{
	    $pad = $blockSize - (strlen($plainText) % $blockSize);
	    return $plainText . str_repeat(chr($pad), $pad);
	}	
	
function hextobin($hexString) 
    { 
    	$length = strlen($hexString); 
    	$binString="";   
    	$count=0; 
    	while($count<$length) 
    	{       
    	    $subString =substr($hexString,$count,2);           
    	    $packedString = pack("H*",$subString); 
    	    if ($count==0)
	    {
			$binString=$packedString;
	    } 
    	    
	    else 
	    {
			$binString.=$packedString;
	    } 
    	    
	    $count+=2; 
    	} 
          return $binString; 
    } 
    
    
    
    
    
function checkCCAvenueStatus($order_id)
{
    $order_status_check = 1;
    global $conn_rjllearning;
    global $paymentGatewayCredentialKey;
    $parts = explode('_', $order_id);
    if (count($parts) < 5) {
        errorreturn("Invalid order_id format");
    }

    list($workspace_id, $institution_id, $branch_id, $student_id, $unique_id) = $parts;
    // Fetch PG vendor setup
    $stmt = $conn_rjllearning->prepare("SELECT id, pg_vendor, credentials 
                                        FROM payment_gateway_setup 
                                        WHERE workspace_id = ? AND institution_id = ? AND branch_id = ? and status = '1' 
                                        LIMIT 1");
    $stmt->execute([$workspace_id, $institution_id, $branch_id]);
    $pg_vendor = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$pg_vendor) {
        errorreturn("PG Vendor not found for this branch");
    }
    
    // require_once $base_path_to_learning_resources . "includes/pg_credentials_encryption_key.php";

    // Decrypt credentials
    $pg_credentials = json_decode(aes128Decrypt($pg_vendor['credentials'], $paymentGatewayCredentialKey), true);

    if (
        empty($pg_credentials['merchant_data']) || 
        empty($pg_credentials['access_code']) || 
        empty($pg_credentials['working_key'])
    ) {
        errorreturn("Incomplete CCAvenue credentials.");
    }
    
    
    // Step 1: Encrypt the request data
    $merchant_json_data = json_encode(["order_no" => $order_id]);
    $encrypted_data = ccavenueencrypt($merchant_json_data, $pg_credentials['working_key']);

    // Step 2: Build POST data
    $final_data = 'enc_request=' . $encrypted_data
        . '&access_code=' . $pg_credentials['access_code']
        . '&request_type=JSON&response_type=JSON'
        . '&command=orderStatusTracker&version=1.2';

    // Step 3: Send to CCAvenue API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.ccavenue.com/apis/servlet/DoWebTrans");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $final_data);
    $result = curl_exec($ch);
    curl_close($ch);
     
    // Step 4: Decrypt response
    $status = '';
    $information = explode('&', $result);
    foreach ($information as $info) {
        $info_value = explode('=', $info);
        if (trim($info_value[0]) === 'enc_response') {
            $status = ccavenuedecrypt(trim($info_value[1]), $pg_credentials['working_key']);
            
            break;
        }
    }
    
    $obj = json_decode($status);
  

    
    
    // Step 5: Check if necessary properties exist in the response before using them
   if ($obj && isset($obj->order_status) && isset($obj->status)) {

    // Determine final order status
    // $final_status = ($obj->order_status === "Successful" && $obj->status == 0) ? "Successful" : "Aborted";
    // Not recommended unless explicitly required
     $final_status = (in_array($obj->order_status, ['Successful', 'Shipped']) && $obj->status == 0) ? "Successful" : "Aborted";


    // Explicitly track if the order was aborted
    $order_status_check = ($obj->status == 0 && $obj->order_status === "Aborted") ? 0 : 1;



    // Extract and validate order ID parts
    $parts = explode('_', $order_id);
    if (count($parts) < 5) {
        errorreturn("Invalid order_id format");
    }

    list($order_workspace_id, $order_institution_id, $branch_id, $admission_number, $time) = $parts;

    if ($order_workspace_id != $workspace_id || $order_institution_id != $institution_id) {
        errorreturn("order_id mismatch with workspace_id or institution_id");
    }
    
    $amount = $obj->order_amt ?? '';

    // verify if it is already verified in initiated transaction
    if(!checkFinwareStatusInitiatedTransaction($conn_rjllearning, $workspace_id, $institution_id, $order_id)) {
        if($final_status === 'Successful'){

            $transaction_data = [
                'order_id' => $order_id,
                'amount' => $obj->order_amt ?? '',
                'payment_gateway' => 'ccavenue',
            ];
        
            // Convert array to JSON for logging
            $json_data = json_encode($transaction_data, JSON_PRETTY_PRINT);
        
            // Define file path (make sure this path is writable)
            $file_path = __DIR__ . '/successful_transactions.json';
        
            // Append the content to the file with a separator
            file_put_contents($file_path, $json_data . PHP_EOL, FILE_APPEND);
     
    
           $create_finware_transaction_response = createPaymentGatewayTransactionFinware($conn_rjllearning,$workspace_id, $institution_id, $student_id, $transaction_data, $branch_id, 'common_status_check.php'); // admission number is sent in student id her
        } else {
            $sql = "UPDATE initiated_transactions set finware_verification = ? where workspace_id = ? and institution_id = ? and order_id = ?";
            $update = $conn_rjllearning->prepare($sql);
            // update initiated_transactions with negative response
            $update->execute(array(-1, $workspace_id, $institution_id, $order_id));
        }
    }
    

    // verify if it is already verified in initiated transaction
    if(!checkTransactionStatusLearningTable($conn_rjllearning, $workspace_id, $institution_id, $order_id)) {
        // Insert into transactions
        $insert = $conn_rjllearning->prepare("INSERT INTO transactions 
            (workspace_id, institution_id, branch_id,amount, gateway_id, reference_no, remarks, status, created_at, updated_at) 
            VALUES (?, ?, ?, ?, ?, ?, ?,?, NOW(), NOW())");

        $insert->execute([
            $workspace_id,
            $institution_id,
            $branch_id,
            $amount,
            $pg_vendor['id'],
            $order_id,
            'Order Id : ' .$order_id,
            $final_status === 'Successful' ? 1 : 0
        ]);

        if ($insert->rowCount() === 0) {
            return errorreturn("Failed to insert transaction for order_id: $order_id");
        }
        $sql = "UPDATE initiated_transactions set status = ? where workspace_id = ? and institution_id = ? and order_id = ?";
        $update = $conn_rjllearning->prepare($sql);
        // update initiated_transactions with positive response
        $update->execute(array(1, $workspace_id, $institution_id, $order_id));
    }

    // Prepare final return data
    return [
        'name' => $obj->order_bill_name ?? '',
        'email' => $obj->order_bill_email ?? '',
        'country' => $obj->order_bill_country ?? '',
        'phone' => $obj->order_bill_tel ?? '',
        'branch' => $obj->param_value2 ?? '',
        'class' => $obj->param_value3 ?? '',
        'section' => $obj->param_value4 ?? '',
        'admission_number' => $student_id ?? '',
        'status' => ($order_status_check == 0) ? 1 : 0,  // 1 if Aborted, else 0 (based on your logic)
        'txn_id' => $obj->reference_no ?? '',
        'order_status' => $final_status,
        'amount' => $obj->order_amt ?? '',
        'payment_date' => date('Y-m-d H:i:s'),
        'vendor_ref' => $obj->bank_ref_no ?? '',
        'order_no' => $order_id,
        'order_bank_response' => $obj->order_bank_response ?? '',
    ];
} else {
    errorreturn("Invalid or incomplete response from CCAvenue");
}


}



function extractedStatusDataCCAvenue($status_response, $conn_rjllearning, $workspace_id, $institution_id, $branch_id, $gateway_id) {
    $order_id           = $status_response['order_no'];
    $order_status       = $status_response['status'];
    $amount             = $status_response['amount'];
    $payment_date       = $status_response['payment_date'];
    $vendor_ref         = $status_response['vendor_ref'];
    $failure_msg        = $status_response['order_bank_response'];
    $txn_id             = $status_response['txn_id'];
    $name               = $status_response['name'];
    $email              = $status_response['email'];
    $country            = $status_response['country'];
    $phone              = $status_response['phone'];
    $branch             = $status_response['branch'];
    $class              = $status_response['class'];
    $section            = $status_response['section'];
    $admission_number   = $status_response['admission_number'];

    // Determine transaction status code
    $remarks = "Payment response for order_id: $order_id. Status: $order_status. Failure: $failure_msg";
    $status = ($order_status === 'Success') ? 1 : (($order_status === 'Failure' || $order_status === 'Aborted') ? -1 : 0);

    // Check for existing transaction
    $stmt = $conn_rjllearning->prepare("SELECT * FROM transactions WHERE reference_no = ?");
    $stmt->execute([$order_id]);
    $existing = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$existing) {
        $insert = $conn_rjllearning->prepare("INSERT INTO transactions 
            (workspace_id, institution_id, branch_id, gateway_id, reference_no, remarks, status, created_at, updated_at) 
            VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())");

        $insert->execute([
            $workspace_id,
            $institution_id,
            $branch_id,
            $gateway_id,
            $order_id,
            $remarks,
            $status
        ]);
    } elseif ($existing['status'] != $status) {
        $update = $conn_rjllearning->prepare("UPDATE transactions 
            SET status = ?, remarks = ?, updated_at = NOW() 
            WHERE reference_no = ?");
        $update->execute([$status, $remarks, $order_id]);
    }

    // Return formatted response
    successreturn([
        'message'           => 'Transaction status updated',
        'branch'            => $branch,
        'name'              => $name,
        'email'             => $email,
        'country'           => $country,
        'phone'             => $phone,
        'class'             => $class,
        'section'           => $section,
        'amount'            => $amount,
        'admission_number'  => $admission_number,
        'status'            => $order_status,
        'remarks'           => $remarks,
        'order_id'          => $order_id,
        'failure_msg'       => $failure_msg,
        'txn_id'            => $txn_id
    ]);
}




function handleCcavenueDecryptedResponse($data,$pg_vendor, $workspace_id, $institution_id, $branch_id, $conn_rjllearning) {
    global $paymentGatewayCredentialKey;
    global $gateway;
    try {
        
        $pg_credentials = json_decode(aes128Decrypt($pg_vendor['credentials'], $paymentGatewayCredentialKey), true);
    
        if (
            empty($pg_credentials['merchant_data']) || 
            empty($pg_credentials['access_code']) || 
            empty($pg_credentials['working_key'])
        ) {
            errorreturn("Incomplete CCAvenue credentials.");
        }
        
        if (!isset($data['encResp'])) {
            errorreturn("Ivalid response from CCAvenue");
        }

        $encResp = $data['encResp'];
        $decrypted_response = ccavenuedecrypt($encResp, $pg_credentials['working_key']);
        parse_str($decrypted_response, $response);

        if (!isset($response['order_id'], $response['order_status'], $response['tracking_id'])) {
             errorreturn("Incomplete response from CCAvenue");
        }

        $order_id = $response['order_id'] ?? null;
        $order_status = $response['order_status'] ?? 'Unknown';
        $tracking_id = $response['tracking_id'] ?? null;
        $failure_msg = $response['failure_message'] ?? 'No failure message';
        $amount = $response['amount'] ?? 0;

        $remarks = "Payment response for order_id: $order_id. Status: $order_status. Failure: $failure_msg";
        $status = ($order_status === 'Success') ? 1 : (($order_status === 'Failure' || $order_status === 'Aborted') ? -1 : 0);
        
        if($status == 1) {
            $transaction_data = [
                'order_id' => $order_id,
                'amount' => $amount,
                'payment_gateway' => "ccavenue",
            ];
            
            $parts = explode('_', $order_id);
            $student_id = $parts[3];
    
            $create_finware_transaction_response = createPaymentGatewayTransactionFinware($conn_rjllearning,$workspace_id, $institution_id, $student_id, $transaction_data, $branch_id, 'common_response.php'); // admission number is sent in student id her

        } else {
            $sql = "UPDATE initiated_transactions set finware_verification = ? where workspace_id = ? and institution_id = ? and order_id = ?";
            $update = $conn_rjllearning->prepare($sql);
            // update initiated_transactions with negative response
            $update->execute(array(-1, $workspace_id, $institution_id, $order_id));
        }

        $insert = $conn_rjllearning->prepare("INSERT INTO transactions 
            (workspace_id, institution_id, branch_id, gateway_id, reference_no, remarks, status, created_at, updated_at) 
            VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())");

        $insert->execute([
            $workspace_id,
            $institution_id,
            $branch_id,
            $pg_vendor['id'],
            $order_id,
            $remarks,
            $status
        ]);

        if ($insert->rowCount() === 0) {
            return errorreturn("Failed to insert transaction for order_id: $order_id");
        }
        
        $sql = "UPDATE initiated_transactions set status = ? where workspace_id = ? and institution_id = ? and order_id = ?";
        $update = $conn_rjllearning->prepare($sql);
        // update initiated_transactions with positive response
        $update->execute(array(1, $workspace_id, $institution_id, $order_id));
      
           
        return [
            'status' => 1,
            'message' => 'Transaction processed successfully',
            'order_id' => $order_id,
            'remarks' => $remarks,
            'gateway_status' => $status
        ];

    } catch (Exception $e) {
        return errorreturn("Exception during processing: " . $e->getMessage());
    }
}

