<?php
/**
 * Total Processing Gateway Logger - Trait
 * 
 * Easy-to-use trait for gateway classes to log events
 *
 * @package TotalProcessing
 * @subpackage Gateway_Logger
 */

if (!defined('ABSPATH')) {
    exit;
}

trait TotalProcessingGatewayLoggerTrait {
    
    /**
     * Cached order object to avoid multiple DB calls
     */
    private $cached_order = null;
    private $cached_order_id = null;
    
    /**
     * Log an error event
     *
     * @param string $message Error message
     * @param array $data Additional data
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @return int|false
     */
    protected function logError($message, $data = [], $order_id = null, $transaction_id = null, $checkout_id = null) {
        return $this->logEvent(TP_Gateway_Logger::LEVEL_ERROR, $message, $data, $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Log a warning event
     *
     * @param string $message Warning message
     * @param array $data Additional data
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @return int|false
     */
    protected function logWarning($message, $data = [], $order_id = null, $transaction_id = null, $checkout_id = null) {
        return $this->logEvent(TP_Gateway_Logger::LEVEL_WARNING, $message, $data, $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Log an info event
     *
     * @param string $message Info message
     * @param array $data Additional data
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @return int|false
     */
    protected function logInfo($message, $data = [], $order_id = null, $transaction_id = null, $checkout_id = null) {
        return $this->logEvent(TP_Gateway_Logger::LEVEL_INFO, $message, $data, $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Log a success event
     *
     * @param string $message Success message
     * @param array $data Additional data
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @return int|false
     */
    protected function logSuccess($message, $data = [], $order_id = null, $transaction_id = null, $checkout_id = null) {
        return $this->logEvent(TP_Gateway_Logger::LEVEL_SUCCESS, $message, $data, $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Core logging method
     *
     * @param string $level Log level
     * @param string $message Log message
     * @param array $data Additional data
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @return int|false
     */
    private function logEvent($level, $message, $data = [], $order_id = null, $transaction_id = null, $checkout_id = null) {
        // Auto-extract IDs from order if order_id provided but other IDs missing
        if ($order_id && (!$transaction_id || !$checkout_id)) {
            $order = $this->getCachedOrder($order_id);
            if ($order) {
                if (!$transaction_id) {
                    $transaction_id = $order->get_meta('_applepay_merchant_transaction_id') ?: $order->get_transaction_id();
                }
                if (!$checkout_id) {
                    $checkout_id = $order->get_meta('_applepay_checkout_id');
                }
            }
        }
        
        return TP_Gateway_Logger::log(
            $this->id,
            $level,
            $message,
            $data,
            $order_id,
            $transaction_id,
            $checkout_id
        );
    }
    
    /**
     * Get cached order object to avoid multiple DB queries
     *
     * @param int $order_id
     * @return WC_Order|false
     */
    private function getCachedOrder($order_id) {
        if ($this->cached_order_id === $order_id && $this->cached_order) {
            return $this->cached_order;
        }
        
        $this->cached_order = wc_get_order($order_id);
        $this->cached_order_id = $order_id;
        
        return $this->cached_order;
    }
    
    /**
     * Log amount mismatch
     *
     * @param float $order_total Order total
     * @param float $authorized_amount Authorized amount
     * @param int|null $order_id Order ID
     * @param string|null $checkout_id Checkout ID
     */
    protected function logAmountMismatch($order_total, $authorized_amount, $order_id = null, $checkout_id = null) {
        $difference = abs($order_total - $authorized_amount);
        
        $this->logError('Amount mismatch detected', [
            'order_total' => number_format($order_total, 2),
            'authorized_amount' => number_format($authorized_amount, 2),
            'difference' => number_format($difference, 2),
            'currency' => get_woocommerce_currency()
        ], $order_id, null, $checkout_id);
    }
    
    /**
     * Log checkout ID reuse attempt
     *
     * @param string $checkout_id Checkout ID
     * @param int|null $existing_order_id Existing order using this checkout ID
     */
    protected function logCheckoutIdReuse($checkout_id, $existing_order_id = null) {
        $this->logWarning('Checkout ID reuse attempt detected', [
            'checkout_id' => $checkout_id,
            'existing_order_id' => $existing_order_id,
            'message' => 'This checkout ID was already used for another order'
        ], null, null, $checkout_id);
    }
    
    /**
     * Log cart restoration failure
     *
     * @param float $target_amount Target amount
     * @param string|null $preservation_key Preservation key
     */
    protected function logCartRestorationFailure($target_amount, $preservation_key = null) {
        $this->logError('Cart restoration failed', [
            'target_amount' => number_format($target_amount, 2),
            'preservation_key' => $preservation_key,
            'cart_empty' => WC()->cart ? WC()->cart->is_empty() : true
        ]);
    }
    
    /**
     * Log order creation failure
     *
     * @param string $reason Failure reason
     * @param array $context Additional context
     */
    protected function logOrderCreationFailure($reason, $context = []) {
        $this->logError('Order creation failed', array_merge([
            'reason' => $reason,
            'cart_total' => WC()->cart ? WC()->cart->get_total('edit') : 0,
            'cart_items' => WC()->cart ? count(WC()->cart->get_cart()) : 0
        ], $context));
    }
    
    /**
     * Log payment authorization
     *
     * @param float $amount Amount
     * @param int $order_id Order ID
     * @param string $transaction_id Transaction ID
     * @param string $checkout_id Checkout ID
     */
    protected function logPaymentAuthorized($amount, $order_id, $transaction_id, $checkout_id) {
        $this->logSuccess('Payment authorized successfully', [
            'amount' => number_format($amount, 2),
            'currency' => get_woocommerce_currency()
        ], $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Log payment failure
     *
     * @param string $reason Failure reason
     * @param int|null $order_id Order ID
     * @param string|null $transaction_id Transaction ID
     * @param string|null $checkout_id Checkout ID
     * @param array $context Additional context
     */
    protected function logPaymentFailure($reason, $order_id = null, $transaction_id = null, $checkout_id = null, $context = []) {
        $this->logError('Payment processing failed', array_merge([
            'reason' => $reason
        ], $context), $order_id, $transaction_id, $checkout_id);
    }
    
    /**
     * Log transaction validation failure
     *
     * @param string $transaction_id Transaction ID
     * @param string $reason Failure reason
     * @param array $context Additional context
     */
    protected function logTransactionValidationFailure($transaction_id, $reason, $context = []) {
        $this->logError('Transaction validation failed', array_merge([
            'reason' => $reason
        ], $context), null, $transaction_id);
    }
    
    /**
     * Log session/lock conflict
     *
     * @param string $type Conflict type
     * @param array $context Additional context
     */
    protected function logSessionConflict($type, $context = []) {
        $this->logWarning('Session/lock conflict detected', array_merge([
            'conflict_type' => $type
        ], $context));
    }
    
    /**
     * Log duplicate prevention trigger
     *
     * @param string $reason Trigger reason
     * @param array $context Additional context
     */
    protected function logDuplicatePrevention($reason, $context = []) {
        $this->logInfo('Duplicate order prevention triggered', array_merge([
            'reason' => $reason
        ], $context));
    }

    function generate_tp_purge_button_html($key, $data){
        return TP_Logs_Settings::render_purge_button($key, $data);
    }

    function generate_sectionend_html($key, $data){
        return '';
    }
}
