<?php

namespace WeeConnectPay\Integrations;

use Exception;
use WC_Order;
use WeeConnectPay\Api\Requests\PrintCloverOrderRequest;
use WeeConnectPay\Dependencies\GuzzleHttp\Exception\RequestException;
use WeeConnectPay\Dependencies\GuzzleHttp\Exception\ConnectException;
use WeeConnectPay\Dependencies\GuzzleHttp\Exception\ClientException;
use WeeConnectPay\Dependencies\GuzzleHttp\Exception\ServerException;
use WeeConnectPay\Integrations\LogService;

/**
 * Service class for handling Clover order printing functionality
 * 
 * This class provides a "best effort" printing service that attempts to send
 * print requests to the merchant's default Clover printer. All failures are
 * logged but never interrupt order processing.
 */
class CloverOrderPrintingService {

    /**
     * @var IntegrationSettings
     */
    private IntegrationSettings $integrationSettings;

    /**
     * Constructor
     */
    public function __construct() {
        $this->integrationSettings = new IntegrationSettings();
    }

    /**
     * Attempt to print a Clover order
     * 
     * This is a "best effort" operation that will never throw exceptions
     * or interrupt order processing. All outcomes are logged appropriately.
     * 
     * @param WC_Order $order The WooCommerce order to print
     * @return void
     */
    public function attemptOrderPrint(WC_Order $order): void {
        try {
            // Check if printing is enabled
            if (!$this->integrationSettings->getCloverOrderPrintingOrDefault()) {
                LogService::debug(sprintf(
                    'Clover order printing is disabled, skipping print for WooCommerce order (#%d)',
                    $order->get_id()
                ));
                return;
            }

            // Check if this is a recurring/subscription order and if that's allowed
            if ($this->isRecurringSubscriptionOrder($order) && !$this->integrationSettings->getCloverOrderPrintingRecurringOrDefault()) {
                LogService::debug(sprintf(
                    'Clover order printing for recurring/subscription orders is disabled, skipping print for WooCommerce order (#%d)',
                    $order->get_id()
                ));
                return;
            }

            // Get the Clover order UUID from order metadata
            $cloverOrderUuid = $order->get_meta('weeconnectpay_clover_order_uuid');
            
            if (empty($cloverOrderUuid)) {
                LogService::warning(sprintf(
                    'Cannot print Clover order - missing clover_order_uuid for WooCommerce order (#%d)',
                    $order->get_id()
                ));
                return;
            }

            LogService::info(sprintf(
                'Attempting to print Clover order (UUID: %s) for WooCommerce order (#%d)',
                $cloverOrderUuid,
                $order->get_id()
            ));

            // Make the print request
            $this->sendPrintRequest($cloverOrderUuid, $order);

        } catch (Exception $e) {
            // Catch any unexpected exceptions to ensure they never interrupt order processing
            LogService::error(sprintf(
                'Unexpected exception during Clover order printing for WooCommerce order (#%d): %s',
                $order->get_id(),
                $e->getMessage()
            ));
        }
    }

    /**
     * Send the actual print request to the API
     * 
     * @param string $cloverOrderUuid
     * @param WC_Order $order
     * @return void
     */
    private function sendPrintRequest(string $cloverOrderUuid, WC_Order $order): void {
        try {
            $printRequest = new PrintCloverOrderRequest();
            $response = $printRequest->POST($cloverOrderUuid);
            
            $statusCode = $response->getStatusCode();
            
            switch ($statusCode) {
                case 200:
                    LogService::info(sprintf(
                        'Successfully sent Clover order print request (UUID: %s) for WooCommerce order (#%d)',
                        $cloverOrderUuid,
                        $order->get_id()
                    ));
                    
                    // Add order note when print request is successfully sent
                    $order->add_order_note(
                        '<b>' . __('Order sent to printing queue of your default Clover printing device.', 'weeconnectpay') . '</b>'
                    );
                    break;
                    
                case 403:
                    LogService::error(sprintf(
                        'Clover order print failed - authorization error (UUID: %s) for WooCommerce order (#%d). Check merchant permissions and token validity.',
                        $cloverOrderUuid,
                        $order->get_id()
                    ));
                    break;
                    
                case 404:
                    LogService::error(sprintf(
                        'Clover order print failed - order not found (UUID: %s) for WooCommerce order (#%d). The order may not exist in Clover.',
                        $cloverOrderUuid,
                        $order->get_id()
                    ));
                    break;
                    
                case 500:
                    LogService::error(sprintf(
                        'Clover order print failed - server error (UUID: %s) for WooCommerce order (#%d). This may be a temporary Clover API issue.',
                        $cloverOrderUuid,
                        $order->get_id()
                    ));
                    break;
                    
                default:
                    LogService::error(sprintf(
                        'Clover order print failed with unexpected status code %d (UUID: %s) for WooCommerce order (#%d)',
                        $statusCode,
                        $cloverOrderUuid,
                        $order->get_id()
                    ));
                    break;
            }

        } catch (ConnectException $e) {
            LogService::error(sprintf(
                'Clover order print failed - network connection error (UUID: %s) for WooCommerce order (#%d): %s',
                $cloverOrderUuid,
                $order->get_id(),
                $e->getMessage()
            ));
        } catch (ClientException $e) {
            $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 'unknown';
            LogService::error(sprintf(
                'Clover order print failed - client error %s (UUID: %s) for WooCommerce order (#%d): %s',
                $statusCode,
                $cloverOrderUuid,
                $order->get_id(),
                $e->getMessage()
            ));
        } catch (ServerException $e) {
            $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 'unknown';
            LogService::error(sprintf(
                'Clover order print failed - server error %s (UUID: %s) for WooCommerce order (#%d): %s',
                $statusCode,
                $cloverOrderUuid,
                $order->get_id(),
                $e->getMessage()
            ));
        } catch (RequestException $e) {
            LogService::error(sprintf(
                'Clover order print failed - request error (UUID: %s) for WooCommerce order (#%d): %s',
                $cloverOrderUuid,
                $order->get_id(),
                $e->getMessage()
            ));
        } catch (Exception $e) {
            LogService::error(sprintf(
                'Clover order print failed - unexpected error (UUID: %s) for WooCommerce order (#%d): %s',
                $cloverOrderUuid,
                $order->get_id(),
                $e->getMessage()
            ));
        }
    }

    /**
     * Check if the order is a recurring/subscription order
     * 
     * This is a placeholder method that will be filled out later as specified
     * in the requirements. For now, it returns false.
     * 
     * @param WC_Order $order
     * @return bool
     */
    private function isRecurringSubscriptionOrder(WC_Order $order): bool {
        // TODO: Implement actual recurring/subscription order detection logic
        // This placeholder will be filled out later according to the requirements
        
        // For now, we can check some basic indicators:
        if ($order->get_created_via() === 'subscription') {
            return true;
        }
        
        // Check if WooCommerce Subscriptions is active and this order contains a subscription
        if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order)) {
            return true;
        }
        
        return false;
    }
} 