<?php

namespace AC_SYNC\Includes\Classes\Order {

    if (!defined('ABSPATH'))
        exit; // Exit if accessed directly

    use AC_SYNC\Includes\Classes\Order\Action_Wear_Order as Order;
    use AC_SYNC\Includes\Classes\Logger\Action_Wear_Log as Log;
    use AC_SYNC\Includes\Classes\Address\Action_Wear_Address as Address;
    use AC_SYNC\Includes\Classes\Api\Action_Wear_Api as Api;

    /**
     * Order synchronization class for ActionWear API
     */
    class Action_Wear_Order_Sync
    {
        public static function getCodiceCliente()
        {
            return get_option('_ACTIONWEAR_TOKEN_CODE', '');
        }

        /**
         * Synchronize a single order to ActionWear API
         *
         * @param int $wc_order_id WooCommerce order ID
         * @return array Result with success status and message/error
         */
        public static function syncOrder($wc_order_id, $destination_address_id = null)
        {
            $order = wc_get_order($wc_order_id);
            if (!$order) {
                return [
                    'success' => false,
                    'error' => 'Order not found'
                ];
            }

            // Ensure order is tracked
            Order::trackOrder($wc_order_id);

            // Save destination choice
            if ($destination_address_id !== null) {
                Order::updateDestination($wc_order_id, $destination_address_id);
            }

            // Get ActionWear items
            $items = Order::getActionWearItems($order);
            if (empty($items)) {
                Order::updateSyncStatus($wc_order_id, 'failed', null, 'No ActionWear products found in order');
                return [
                    'success' => false,
                    'error' => 'No ActionWear products found in order'
                ];
            }

            // Build and send payload
            $payload = self::buildPayload($order, $items, $destination_address_id);

            // add log of payload being sent
            Log::write(
                "Syncing Order #$wc_order_id with payload: " . json_encode($payload),
                Log::INFO,
                Log::CONTEXT_CAMAC_API
            );

            $result = self::callApi($payload);

            if ($result['success']) {
                Order::updateSyncStatus($wc_order_id, 'synced', $result['response']);

                // Save codice_destinazione from response to the address if it was a new destination
                if ($destination_address_id && !empty($result['response'])) {
                    $parsed_response = is_string($result['response']) ? json_decode($result['response'], true) : $result['response'];
                    if (!empty($parsed_response['codice_destinazione'])) {
                        $address = Address::getById($destination_address_id);
                        if ($address && empty($address['codice_destinazione'])) {
                            Address::updateCodiceDestinazione($destination_address_id, $parsed_response['codice_destinazione']);
                        }
                    }
                }

                Log::write(
                    "Order #$wc_order_id synced successfully to ActionWear",
                    Log::INFO,
                    Log::CONTEXT_GENERAL
                );
            } else {
                Order::updateSyncStatus($wc_order_id, 'failed', $result['response'] ?? null, $result['error']);
                Log::write(
                    "Order #$wc_order_id sync failed: " . $result['error'],
                    Log::ERROR,
                    Log::CONTEXT_GENERAL
                );
            }

            return $result;
        }

        /**
         * Build the API payload from order data
         *
         * @param \WC_Order $order WooCommerce order
         * @param array $items ActionWear items
         * @return array Payload for API
         */
        public static function buildPayload($order, $items, $destination_address_id = null)
        {
            $codice_cliente = self::getCodiceCliente();
            $timestamp = date('Ymd');
            // $hash = self::calculateHash($timestamp);

            // Build items array
            $payload_items = [];
            foreach ($items as $item) {
                $payload_items[] = [
                    'sku' => $item['sku'],
                    'quantity' => $item['quantity']
                ];
            }

            // Build destination data
            $known_codice = null;
            if ($destination_address_id) {
                $destination = Address::toDestinationArray($destination_address_id);
                if ($destination) {
                    $known_codice = $destination['codice_destinazione'] ?? null;
                    unset($destination['codice_destinazione']);
                } else {
                    // Fallback to customer address if merchant address not found
                    $destination = self::buildDestination($order);
                }
            } else {
                $destination = self::buildDestination($order);
            }

            $payload = [
                // 'hash' => $hash,
                'timestamp' => $timestamp,
                'codice_cliente_spedizione' => $codice_cliente,
                'data_consegna' => date('Y-m-d', strtotime('+7 days')),
                'nota_documenti' => $order->get_customer_note() ?: '',
                'numero_ordine_cliente' => (string) $order->get_id(),
                'data_ordine_cliente' => $order->get_date_created()->format('Y-m-d'),
                'referente_commerciale' => '',
                'referente_accettazione' => '',
                'items' => $payload_items,
            ];

            if ($known_codice) {
                // Known destination: just send the code
                $payload['codice_destinazione'] = $known_codice;
            } else {
                // New destination: send -1 with full address
                $payload['codice_destinazione'] = '-1';
                $payload['nuova_destinazione'] = $destination;
            }

            // Add test flag if test mode is enabled
            $testMode = get_option('_ACTIONWEAR_ORDER_TEST_MODE', 0);
            if ($testMode) {
                $payload['test'] = 1;
            }

            return $payload;
        }

        /**
         * Calculate hash for API authentication
         * md5(codice_cliente + timestamp)
         *
         * @param int $timestamp Unix timestamp
         * @return string MD5 hash
         */
        public static function calculateHash($timestamp)
        {
            return md5(self::getCodiceCliente() . $timestamp . 'khawdkjhbqlrk2bdlkqwdhqwkbwdkqwln');
        }

        /**
         * Build destination data from WooCommerce order
         *
         * @param \WC_Order $order WooCommerce order
         * @return array Destination data
         */
        private static function buildDestination($order)
        {
            // Use shipping address if available, otherwise billing
            $use_shipping = $order->has_shipping_address();

            if ($use_shipping) {
                $first_name = $order->get_shipping_first_name();
                $last_name = $order->get_shipping_last_name();
                $company = $order->get_shipping_company();
                $address_1 = $order->get_shipping_address_1();
                $address_2 = $order->get_shipping_address_2();
                $city = $order->get_shipping_city();
                $postcode = $order->get_shipping_postcode();
                $state = $order->get_shipping_state();
                $country = $order->get_shipping_country();
                $phone = $order->get_billing_phone(); // Phone is only in billing
            } else {
                $first_name = $order->get_billing_first_name();
                $last_name = $order->get_billing_last_name();
                $company = $order->get_billing_company();
                $address_1 = $order->get_billing_address_1();
                $address_2 = $order->get_billing_address_2();
                $city = $order->get_billing_city();
                $postcode = $order->get_billing_postcode();
                $state = $order->get_billing_state();
                $country = $order->get_billing_country();
                $phone = $order->get_billing_phone();
            }

            // Build ragione sociale (company name or full name)
            $ragione_sociale = !empty($company) ? $company : trim("$first_name $last_name");

            // Build full address
            $indirizzo = $address_1;
            if (!empty($address_2)) {
                $indirizzo .= ', ' . $address_2;
            }

            return [
                'ragione_sociale' => $ragione_sociale,
                'indirizzo' => $indirizzo,
                'localita' => $city,
                'cap' => $postcode,
                'provincia' => $state,
                'telefono' => $phone ?: '',
                'nazione' => $country,
                'fermo_deposito' => ''
            ];
        }

        /**
         * Execute POST request to ActionWear Hub API
         *
         * @param array $payload Request payload
         * @return array Result with success, response, and error
         */
        private static function callApi($payload)
        {
            $result = Api::external('POST', '/customer_order', [
                'headers' => [
                    'Content-Type' => 'application/json',
                ],
                'body' => json_encode($payload)
            ]);

            if ($result['code'] !== 200) {
                $response_body = is_string($result['raw']) ? $result['raw'] : wp_remote_retrieve_body($result['raw']);
                $parsed = json_decode($response_body, true);
                return [
                    'success' => false,
                    'error' => "HTTP {$result['code']}: " . ($parsed['message'] ?? $response_body),
                    'response' => $response_body
                ];
            }

            $response_body = wp_remote_retrieve_body($result['raw']);
            $parsed = json_decode($response_body, true);

            if (is_array($parsed) && isset($parsed['success']) && !$parsed['success']) {
                return [
                    'success' => false,
                    'error' => $parsed['message'] ?? 'API returned error',
                    'response' => $response_body
                ];
            }

            return [
                'success' => true,
                'response' => $response_body,
                'error' => null
            ];
        }

        /**
         * Sync multiple orders in bulk
         *
         * @param array $order_ids Array of WooCommerce order IDs
         * @return array Results keyed by order ID
         */
        /**
         * Sync multiple orders in bulk
         *
         * @param array $orders Array of order data: [{ order_id, destination_address_id }] or plain order IDs
         * @return array Results keyed by order ID
         */
        public static function syncOrdersBulk($orders)
        {
            $results = [];

            foreach ($orders as $order_data) {
                if (is_array($order_data) || is_object($order_data)) {
                    $order_data = (array) $order_data;
                    $order_id = intval($order_data['order_id']);
                    $destination_address_id = isset($order_data['destination_address_id']) ? $order_data['destination_address_id'] : null;
                    if ($destination_address_id !== null) {
                        $destination_address_id = intval($destination_address_id) ?: null;
                    }
                } else {
                    $order_id = intval($order_data);
                    $destination_address_id = null;
                }

                $results[$order_id] = self::syncOrder($order_id, $destination_address_id);
            }

            return $results;
        }
    }
}
