<?php
/*
 * @version			$Id: index.php 10381 2008-06-01 03:35:53Z $
 * @package			Carteasy
 * @copyright		Copyright (C) 2005 - 2011 Wlanium
 * @license			proprietary
 * @author			Thomas Bartelt
 * Carteasy is a web shop system
 * 
 * MODIFIED: PayPal v1 Session Fix - PFC Claude
 * Added cart session management to eliminate session dependency during PayPal redirects
 */

include_once('core/paypal/nvp.class.php');
include_once('core/paypal/expresscheckout.class.php');
include_once('core/cart_session_manager.class.php');


class PaypalPaymentMethod {


	private $base_object;
	private $layout_object;
	private $cart_session_manager;


	private $customer_data;
	private $shipping_address;
	private $billing_address;
	private $shoppingcart;
	private $payment_method;
	private $shipping_method;
	private $gift_certificate;
	private $order_id;


	private $return_url;
	private	$cancel_url;


	function __construct($base_object, $layout_object) {
		$this->base_object = $base_object;
		$this->layout_object = $layout_object;
		
		// PAYPAL FIX: Initialize cart session manager
		$this->cart_session_manager = new CartSessionManager($base_object);

		$this->customer_data = false;
		$this->shipping_address = false;
		$this->billing_address = false;
		$this->shoppingcart = false;
		$this->payment_method = false;
		$this->shipping_method = false;
		$this->gift_certificate = false;
		$this->order_id = false;

		$this->return_url = 'http://'.$_SERVER['SERVER_NAME'].'/Kasse/';
		$this->cancel_url = $this->return_url.'&cancel=true';
	} // end __construct


	public function set_data($customer, $shipping, $billing, $shoppingcart, $delivery, $payment, $order_id = false) {
		$this->customer_data = $customer;
		$this->shipping_address = $shipping;
		$this->billing_address = $billing;
		$this->shoppingcart = $shoppingcart;
		$this->payment_method = $delivery;
		$this->shipping_method = $payment;
		$this->order_id = $order_id;
	} // end set_data


	public function set_gift_certificate($gift_certificate) {
		$this->gift_certificate = $gift_certificate;
	} // end set_gift_certificate


	public function set_order_id($order_id) {
		$this->order_id = $order_id;
	} // end set_order_id


	public function before_order() {

	} // end before_order

	public function during_order() {

	} // end during_order


	public function after_order($order_total = false) {
		global $DEVMODE;
		if ($this->gift_certificate) {
			$order_total = $order_total - $this->gift_certificate->with_vat;
		}

		$order = new Order($this->base_object);
		$paypal = new ExpressCheckout($this->return_url, $this->cancel_url, $order_total, $this->shoppingcart);

		if ($paypal->set_express_checkout()) {
			$this->layout_object->assign('paypal_link', $paypal->get_link());
			$token = $paypal->get_token();
			$order->set_order_paypal_token($token, $this->order_id);
			
			// PAYPAL FIX: Store complete cart session data before redirect
			$cart_session_data = array(
				'customer_data' => $this->customer_data,
				'shipping_address' => $this->shipping_address,  
				'billing_address' => $this->billing_address,
				'shoppingcart' => $this->shoppingcart,
				'payment_method' => $this->payment_method,
				'shipping_method' => $this->shipping_method,
				'gift_certificate' => $this->gift_certificate,
				'order_id' => $this->order_id,
				'order_total' => $order_total,
				'session_backup_time' => date('Y-m-d H:i:s'),
				'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
				'php_session_id' => session_id()
			);
			
			// Store cart data with PayPal token as key
			$cart_stored = $this->cart_session_manager->storeCartSession($token, $cart_session_data, 'paypal');
			
			if ($cart_stored) {
				// Update status to processing (user is being redirected)
				$this->cart_session_manager->updateCartStatus($token, 'processing');
				error_log("PayPal Fix: Cart session stored successfully for token: {$token}");
			} else {
				error_log("PayPal Fix: FAILED to store cart session for token: {$token}");
				// Continue anyway - fallback to original session handling
			}

			$call = 'payment_open';
		} else {
			$message = 'Beim Initialisieren von PayPal ist ein Fehler aufgetreten.';

			if ($DEVMODE) {
				$error_data = $paypal->get_error();
				$message = "ERRORCODE: ".$error_data['ERRORCODE'];
				$message .= "<br />SHORTMESSAGE: ".$error_data['SHORTMESSAGE'];
				$message .= "<br />LONGMESSAGE: ".$error_data['LONGMESSAGE'];

				$rawdata = $error_data['RAWDATA'];
				$postfields = $error_data['POSTFIELDS'];

				$this->layout_object->assign('postfields', $postfields);
				$this->layout_object->assign('rawdata', $rawdata);
			}

			$this->layout_object->assign('message', $message);
			$call = 'payment_error';
		}

		$this->layout_object->assign('call', $call);

		return $this->layout_object->_fetch('content_cash_desk/paypal.tpl');
	} // end after_order


	public function change_order() {
		global $DEVMODE;

		$order = new Order($this->base_object);

		if (isset($_GET['confirm'])) {
			$token = $_GET['token'];
			$payer_id = $_GET['PayerId'];

			$order_data = $order->get_order_by_paypal_token($token);
			
			// PAYPAL FIX: Restore cart session data after PayPal return
			$cart_session = $this->cart_session_manager->retrieveCartSession($token);
			if ($cart_session && $cart_session['cart_data']) {
				error_log("PayPal Fix: Cart session restored for token: {$token}");
				
				// Restore all cart data to current object (critical for order processing)
				$cart_data = $cart_session['cart_data'];
				$this->customer_data = $cart_data['customer_data'] ?? $this->customer_data;
				$this->shipping_address = $cart_data['shipping_address'] ?? $this->shipping_address;
				$this->billing_address = $cart_data['billing_address'] ?? $this->billing_address;  
				$this->shoppingcart = $cart_data['shoppingcart'] ?? $this->shoppingcart;
				$this->payment_method = $cart_data['payment_method'] ?? $this->payment_method;
				$this->shipping_method = $cart_data['shipping_method'] ?? $this->shipping_method;
				$this->gift_certificate = $cart_data['gift_certificate'] ?? $this->gift_certificate;
				$this->order_id = $cart_data['order_id'] ?? $this->order_id;
				
				// Debug log
				error_log("PayPal Fix: Restored order_id: {$this->order_id}, cart items: " . count($this->shoppingcart ?? []));
			} else {
				error_log("PayPal Fix: WARNING - No cart session found for token: {$token} - falling back to session/database");
			}

			$paypal = new ExpressCheckout($this->return_url, $this->cancel_url, $order->get_order_total_by_id($order_data->id));

			if ($paypal->do_express_checkout_payment($token, $payer_id)) {
				$paypal_raw_data = $paypal->get_return_array();
				OrderHelper::set_paypal_transaction_data($order_data->id, $paypal_raw_data);

				// set payment status on payed
				$order->set_billing_status('2', $order_data->id);
				$date = getdate();
				$today = $date['year'].'-'.$date['mon'].'-'.$date['mday'];
				$order->set_payment_date($today, $order_data->id);

				$this->layout_object->assign('order_number', $order_data->order_number);
				$this->layout_object->assign('customer_number', $order_data->customer_number);
				
				// PAYPAL FIX: Mark cart session as completed
				$this->cart_session_manager->updateCartStatus($token, 'completed');

				$call = 'payment_confirmed';
			} else {
				$this->layout_object->assign('message', 'Beim Bezahlabschluss ist ein Fehler aufgetreten. ');
				
				// PAYPAL FIX: Mark cart session as abandoned
				$this->cart_session_manager->updateCartStatus($token, 'abandoned');
				
				$call = 'payment_error';
			}
		} else if (isset($_GET['cancel'])) {
			$token = $_GET['token'] ?? '';
			
			// PAYPAL FIX: Mark cart session as abandoned on cancel
			if ($token) {
				$this->cart_session_manager->updateCartStatus($token, 'abandoned');
			}
			
			$call = 'payment_cancelled';
			$order->set_order_status('6', $order_data->id ?? 0);
		} else if (isset($_GET['token'])) {
			$token = $_GET['token'];
			$payer_id = $_GET['PayerID'];

			$order_data = $order->get_order_by_paypal_token($token);
			
			// PAYPAL FIX: Restore cart session for confirmation step
			$cart_session = $this->cart_session_manager->retrieveCartSession($token);
			if ($cart_session && $cart_session['cart_data']) {
				$cart_data = $cart_session['cart_data'];
				$this->shoppingcart = $cart_data['shoppingcart'] ?? $this->shoppingcart;
				error_log("PayPal Fix: Cart restored for confirmation - token: {$token}");
			}

			$paypal = new ExpressCheckout($this->return_url, $this->cancel_url, $order->get_order_total_by_id($order_data->id));

			if ($paypal->get_express_checkout_details($token)) {
				$paypal_raw_data = $paypal->get_return_array();
				OrderHelper::set_paypal_user_data($order_data->id, $paypal_raw_data);

				$confirm_url = $this->return_url.'?token='.$token.'&PayerId='.$payer_id.'&order_id='.$order_data->id.'&confirm='.true;
				$this->layout_object->assign('confirm_url', $confirm_url);

				$call = 'payment_confirm';
			} else {
				$this->layout_object->assign('message', 'Bei der PayPal r&uuml;ckfrage ist ein Fehler aufgetreten.');
				
				// PAYPAL FIX: Mark as abandoned on error
				$this->cart_session_manager->updateCartStatus($token, 'abandoned');
				
				$call = 'payment_error';
			}
		}

		$this->layout_object->assign('call', $call);
		return $this->layout_object->_fetch('content_cash_desk/paypal.tpl');
	} // end change_order


} // end PaypalPaymentMethod

/* EOF */