<?php

namespace WcElectronInvoice;

use WcElectronInvoice\Admin\Settings\OptionPage;
use WcElectronInvoice\Providers\OrderQuery;
use function WcElectronInvoice\Functions\disableInvoiceOnOrderTotalZero;
use function WcElectronInvoice\Functions\getXmlFromOrder;

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

/**
 * PeppolApi integration - ACUBE (Peppol API)
 *
 * @see https://docs.acubeapi.com/documentation/peppol/ - Peppol Network
 * @see https://docs.acubeapi.com/documentation/peppol-be/ - Belgian e-invoicing
 *
 */
class PeppolApi extends InvoiceApi
{
    /**
     * getUserIntegrationData
     *
     * @param $userID
     *
     * @return object
     */
    public static function getPEPPOLPOPIntegrationData(): object
    {
        $integrationPluginActive = get_option('wc_el_inv-addon-peppol-via-pop', false);

        return (object)[
            'active_plugin_integration'      => (bool) $integrationPluginActive,
            'peppol_integration'             => Integrations::isPeppolIntegrationActive(),
            'live_integration'               => 'active' === get_option('wc_el_inv-active_peppol_integration'),
            'sandbox_integration'            => 'active' === get_option('wc_el_inv-active_peppol_integration_sandbox'),
            'identifier_scheme'              => get_option('wc_el_inv-peppol_identifier_scheme') ?: null,
            'identifier_value'               => get_option('wc_el_inv-peppol_endpoint_identifier_value') ?: null,
            'legal_entity_uuid'              => get_option('wc_el_inv-peppol_legal_entity_uuid') ?: null,
            'identifier_scheme_sandbox'      => get_option('wc_el_inv-peppol_identifier_scheme_sandbox') ?: null,
            'identifier_value_sandbox'       => get_option('wc_el_inv-peppol_endpoint_identifier_value_sandbox') ?: null,
            'legal_entity_uuid_sandbox'      => get_option('wc_el_inv-peppol_legal_entity_uuid_sandbox') ?: null,
        ];
    }

    /**
     * changeStatus
     *
     * @param int    $orderID
     * @param string $from
     * @param string $to
     * @param string $provider
     *
     * @return bool
     * @throws \Exception
     */
    public static function changeStatus(int $orderID, string $from, string $to, string $provider = 'woocommerce'): bool
    {
        $getPEPPOLPOPIntegrationData = self::getPEPPOLPOPIntegrationData();
        $level                       = \WcElectronInvoice\Wizard::popGetUserLevel();
        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') ||
            (! $getPEPPOLPOPIntegrationData->active_plugin_integration ||
             ! $getPEPPOLPOPIntegrationData->peppol_integration)

        ) {
            return false;
        }

        $scheduledOptions = self::scheduledOptions();

        if ('yes' !== $scheduledOptions->active) {
            return false;
        }

        // Get order
        $order = \WcElectronInvoice\Providers\OrderQuery::instance()->getProviderOrder($orderID, $provider);
        // Check WC_Order instance
        $wcOrderClass = \WcElectronInvoice\Functions\wcOrderClassName($order, '\WC_Order');

        if (! is_subclass_of($order, '\WcElectronInvoice\Providers\Order') &&
            ! $order instanceof $wcOrderClass) {
            return false;
        }

        // Return if total is 0
        if (disableInvoiceOnOrderTotalZero($order)) {
            return false;
        }

        // Check if uuid exist
        $uuid = $order->get_meta(\WcElectronInvoice\Functions\buildUuidMetaKey('peppol_pop', 'invoice'));
        if ($uuid) {
            // Log
            \WcElectronInvoice\Functions\log("changeStatus - UUID exist: {$uuid}" . "\n");

            return false;
        }

        // Check if the invoice was already sent
        $checkSent = $order->get_meta("_invoice_sent", true);
        if ('sent' === $checkSent) {
            // Log
            \WcElectronInvoice\Functions\log("changeStatus - Document is sent: {$checkSent}" . "\n");

            return false;
        }

        $valueOrderStatus = $scheduledOptions->status;
        // FROM completed or FROM equal TO or TO not completed return false
        if ($valueOrderStatus === $from || $from === $to || $valueOrderStatus !== $to) {
            $nextScheduled = wp_next_scheduled(
                'PoPToPEPPOLJobsScheduledImport',
                [$order->get_id(), $provider]
            );
            // Clear scheduled
            if ($nextScheduled) {
                wp_clear_scheduled_hook('PoPToPEPPOLJobsScheduledImport', [$order->get_id(), $provider]);
            }

            return false;
        }

        // Scheduled Import
        $time          = self::jobTiming();
        $nextScheduled = wp_next_scheduled(
            'PoPToPEPPOLJobsScheduledImport',
            [$order->get_id(), $provider]
        );

        if (! $nextScheduled) {
            self::scheduled(
                'PoPToPEPPOLJobsScheduledImport',
                [$order->get_id(), $provider],
                $time
            );
        } else {
            \WcElectronInvoice\Functions\log("Event already scheduled for order {$order->get_id()} and provider {$provider} to the " . date('Y-m-d H:i:s',
                    $nextScheduled));
        }

        return true;
    }

    /**
     * autoCompleted
     *
     * @param int    $id
     * @param string $provider
     *
     * @return bool
     */
    public static function autoCompleted(int $id, string $provider = 'woocommerce'): bool
    {
        $getPEPPOLPOPIntegrationData = self::getPEPPOLPOPIntegrationData();
        $level                       = \WcElectronInvoice\Wizard::popGetUserLevel();
        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') ||
            (! $getPEPPOLPOPIntegrationData->active_plugin_integration ||
             ! $getPEPPOLPOPIntegrationData->peppol_integration)

        ) {
            return false;
        }

        $scheduledOptions = self::scheduledOptions();

        if ('yes' !== $scheduledOptions->active) {
            return false;
        }

        $order = \WcElectronInvoice\Providers\OrderQuery::instance()->getProviderOrder($id, $provider);
        // Check if order exist.
        $checkSent = $order->get_meta("_invoice_sent", true);
        // Check if uuid exist
        $uuid = $order->get_meta(\WcElectronInvoice\Functions\buildUuidMetaKey('peppol_pop', 'invoice'));
        // Check WC_Order instance
        $wcOrderClass = \WcElectronInvoice\Functions\wcOrderClassName($order, '\WC_Order');

        if (! is_subclass_of($order, '\WcElectronInvoice\Providers\Order') &&
            ! $order instanceof $wcOrderClass) {
            return false;
        }

        // Return if total is 0
        if (disableInvoiceOnOrderTotalZero($order)) {
            return false;
        }

        // Document id exist
        if (isset($uuid) && '' !== $uuid) {
            // Log
            \WcElectronInvoice\Functions\log("autoCompleted - UUID exist: {$uuid}" . "\n");

            return false;
        }

        // Sent
        if ('sent' === $checkSent) {
            // Log
            \WcElectronInvoice\Functions\log("autoCompleted - Document is sent: {$checkSent}" . "\n");

            return false;
        }

        // Check status.
        $valueOrderStatus = $scheduledOptions->status;
        $orderStatus      = $order->get_status();
        if ($valueOrderStatus === $orderStatus) {
            // Scheduled Import
            $time          = self::jobTiming();
            $nextScheduled = wp_next_scheduled(
                'PoPToPEPPOLJobsScheduledImport',
                [$order->get_id(), $provider]
            );
            if (! $nextScheduled) {
                self::scheduled(
                    'PoPToPEPPOLJobsScheduledImport',
                    [$order->get_id(), $provider],
                    $time
                );
            } else {
                \WcElectronInvoice\Functions\log("Event already scheduled for order {$order->get_id()} and provider {$provider} to the " . date('Y-m-d H:i:s',
                        $nextScheduled));
            }

            return true;
        }

        return false;
    }

    /**
     * actions
     *
     * @param $output
     * @param $id
     * @param $item
     * @param $provider
     *
     * @return string
     */
    public static function actions($output, $id, $item = null, $provider = 'woocommerce'): string
    {
        if ($item && ! $provider) {
            $provider = isset($item['order_provider']) ? $item['order_provider'] : null;
            $provider = ! $provider && isset($item['provider']) ? $item['provider'] : $provider;
        }

        $context       = self::resolveActionDocumentContext($id, (string)$provider, is_array($item) ? $item : null);
        $orderProvider = $context['document'];
        if (! $orderProvider) {
            return $output;
        }
        $documentType  = $context['document_type'];
        $stateType     = 'credit_note' === $documentType ? 'credit-note' : 'invoice';
        $buttonDocumentType = $context['order_type'];

        $send  = __('Invoice', WC_EL_INV_TEXTDOMAIN);
        $state = __('State', WC_EL_INV_TEXTDOMAIN);
        $sent  = __('Sent', WC_EL_INV_TEXTDOMAIN);
        if ('shop_order_refund' === $orderProvider->get_type()) {
            $send = __('Credit note', WC_EL_INV_TEXTDOMAIN);
        }

        if (is_object($orderProvider) && empty($orderProvider->get_vat_number()) || 'private' === $orderProvider->get_invoice_type()) {
            $output .= sprintf("<div style='margin:10px 0 0 0;' class='pop-notice notice-info font-size-tiny'>%s</div>",
                esc_html__('UBL invoices can only be generated for business customers with a valid VAT number. Private customers are not eligible for UBL invoicing.',
                    WC_EL_INV_TEXTDOMAIN));

            return $output;
        }

        $getPEPPOLPOPIntegrationData = self::getPEPPOLPOPIntegrationData();
        if (! $getPEPPOLPOPIntegrationData->active_plugin_integration) {
            return $output;
        }
        $level = \WcElectronInvoice\Wizard::popGetUserLevel();
        $checkSent = method_exists($orderProvider, 'get_invoice_sent') ? $orderProvider->get_invoice_sent() : null;
        $timeoutPending = \WcElectronInvoice\Functions\normalizeBooleanMeta(
            $orderProvider->get_meta(\WcElectronInvoice\Functions\buildNativeTimeoutPendingMetaKey())
        );
        $timeoutChannel = (string)($orderProvider->get_meta(\WcElectronInvoice\Functions\buildNativeTimeoutPendingChannelMetaKey()) ?: '');
        $timeoutDocType = (string)($orderProvider->get_meta(\WcElectronInvoice\Functions\buildNativeTimeoutPendingDocumentTypeMetaKey()) ?: $documentType);
        $orderNumberInvoice = method_exists($orderProvider, 'get_order_number_invoice') ? (string)$orderProvider->get_order_number_invoice() : '';
        $uuidMetaKey = \WcElectronInvoice\Functions\buildUuidMetaKey('peppol_pop', $documentType);
        $uuid        = $orderProvider->get_meta($uuidMetaKey) ?: null;

        $output .= '<div class="peppol_pop_actions">';
        $output .= sprintf('<hr><h4>%s:</h4>', __('PEPPOL', WC_EL_INV_TEXTDOMAIN));
        if ($timeoutPending && 'peppol' === $timeoutChannel) {
            $output .= sprintf(
                '<div class="pop-notice notice-warning timeout-native-pending"><p>%s</p><p>%s%s</p></div>',
                esc_html__('Send not confirmed due to provider timeout. Do not resend: verify with POP support and enter document UUID.',
                    WC_EL_INV_TEXTDOMAIN),
                esc_html__('Invoice number: ', WC_EL_INV_TEXTDOMAIN),
                esc_html('' !== $orderNumberInvoice ? $orderNumberInvoice : 'N/A')
            );
            $output .= sprintf(
                '<input type="text" class="native-timeout-uuid-input" style="display:block;width:100%%;min-width:100%%;margin:0 0 8px 0;" id="native_timeout_uuid_%1$s" placeholder="%2$s" />',
                esc_attr($id),
                esc_attr__('Enter verified UUID', WC_EL_INV_TEXTDOMAIN)
            );
            $output .= sprintf(
                '<a href="javascript:;" data-provider="%1$s" data-id="%2$s" data-channel="peppol" data-document-type="%3$s" class="api-action confirm-timeout-uuid button button-primary" id="api_confirm_timeout_uuid_%2$s">%4$s</a>',
                esc_attr($provider),
                esc_attr($id),
                esc_attr($timeoutDocType),
                esc_html__('Confirm UUID', WC_EL_INV_TEXTDOMAIN)
            );
            $output .= sprintf(
                '<a href="javascript:;" data-provider="%1$s" data-id="%2$s" data-channel="peppol" data-document-type="%4$s" class="api-action cancel-timeout-pending button button-secondary" id="api_cancel_timeout_%2$s">%3$s</a>',
                esc_attr($provider),
                esc_attr($id),
                esc_html__('Cancel timeout', WC_EL_INV_TEXTDOMAIN),
                esc_attr($buttonDocumentType)
            );
            $output .= '</div>';

            return $output;
        }

        if ($uuid || 'sent' === $checkSent) {
            // Created and notify
            $output .= "<a disabled='disabled' data-provider='{$provider}' data-id='{$id}' data-document-type='{$buttonDocumentType}' data-uuid='{$uuid}' class='disabled created button button-secondary' id='api_created_{$id}'>{$sent}</a>";
            $output .= "<a href='javascript:;' data-provider='{$provider}' data-id='{$id}' data-document-type='{$buttonDocumentType}' data-uuid='{$uuid}' data-type='{$stateType}' class='api-action state button button-primary' id='api_state_{$id}'>{$state}</a>";
        } else {
            // Create
            if (! $getPEPPOLPOPIntegrationData->peppol_integration ||
                ! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic')
            ) {
                $output .= "<a disabled='disabled' data-provider='{$provider}' data-id='{$id}' data-document-type='{$buttonDocumentType}' data-uuid='{$uuid}' class='disabled create button button-primary' id='api_create_{$id}'>{$send}</a>";
            } else {
                $output .= "<a href='javascript:;' data-provider='{$provider}' data-id='{$id}' data-document-type='{$buttonDocumentType}' data-uuid='{$uuid}' class='api-action create button button-primary' id='api_create_{$id}'>{$send}</a>";
            }
        }
        $output .= '</div>';

        return $output;
    }

    /**
     * createAndSendUblInvoice
     *
     * @return mixed|void
     * @throws \Exception
     */
    public static function createAndSendUblInvoice()
    {
        $getPEPPOLPOPIntegrationData = self::getPEPPOLPOPIntegrationData();
        $level                       = \WcElectronInvoice\Wizard::popGetUserLevel();
        $provider                    = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'provider') ?? '');
        $id                          = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'id') ?? '');
        $action                      = \WcElectronInvoice\Functions\filterInput($_POST, 'action') ?? null;
        $method                      = \WcElectronInvoice\Functions\filterInput($_POST, 'method') ?? null;

        if (! \WcElectronInvoice\Functions\isBackgroundExecutionMode($method, ['cronjob', 'feCronJobUploadRequest'])) {
            if (! check_ajax_referer('wc_el_inv_ajax-ajax_nonce', 'nonce', false)) {
                wp_send_json_error(['message' => esc_html__('Unauthorized.', WC_EL_INV_TEXTDOMAIN)]);
                return;
            }
            if (! current_user_can('manage_woocommerce')) {
                wp_send_json_error(['message' => esc_html__('Forbidden.', WC_EL_INV_TEXTDOMAIN)]);
                return;
            }
        }

        if (! \WcElectronInvoice\Integrations::isInvoiceChannelActive(\WcElectronInvoice\Integrations::CHANNEL_PEPPOL)) {
            if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                $preconditionError = \WcElectronInvoice\Functions\mapNativeCreateAndSendPreconditionError('peppol',
                    'channel_mismatch');
                wp_send_json_error([
                    'message' => esc_html__('Action not allowed: another integration channel is active.',
                        WC_EL_INV_TEXTDOMAIN),
                    'code'    => $preconditionError['code'],
                ]);
            }

            return;
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') ||
            (! $getPEPPOLPOPIntegrationData->active_plugin_integration ||
             ! $getPEPPOLPOPIntegrationData->peppol_integration)
        ) {
            if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                $preconditionError = \WcElectronInvoice\Functions\mapNativeCreateAndSendPreconditionError('peppol',
                    'integration_inactive');
                wp_send_json_error([
                    'message' => esc_html__('Action not allowed.',
                        WC_EL_INV_TEXTDOMAIN),
                    'code'    => $preconditionError['code'],
                ]);
            }

            return;
        }

        // I check the action parameter if it does not match I get an error
        if ('createAndSendUblInvoice' !== $action) {
            if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                $preconditionError = \WcElectronInvoice\Functions\mapNativeCreateAndSendPreconditionError('peppol',
                    'action_invalid');
                wp_send_json_error([
                    'message' => esc_html__('Action not valid.',
                        WC_EL_INV_TEXTDOMAIN),
                    'code'    => $preconditionError['code'],
                ]);
            }

            return;
        }

        $requestedType = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST, 'document_type') ?? '');
        $context       = self::resolveActionDocumentContext((int)$id, $provider, null, $requestedType);
        $order         = $context['document'];
        if (! $order) {
            if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                wp_send_json_error([
                    'message' => esc_html__('Order not found.', WC_EL_INV_TEXTDOMAIN),
                ]);
            }

            return;
        }
        $type  = $context['document_type'];

        $metaKey = \WcElectronInvoice\Functions\buildUuidMetaKey('peppol_pop', $type);

        $uuid = $order->get_meta($metaKey);
        // Document id exist
        if (isset($uuid) && '' !== $uuid) {
            // Log
            \WcElectronInvoice\Functions\log(
                \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol', "UUID exist: {$uuid}") . "\n"
            );

            if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                $preconditionError = \WcElectronInvoice\Functions\mapNativeCreateAndSendPreconditionError('peppol',
                    'uuid_already_exists');
                wp_send_json_error([
                    'message' => \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                        sprintf(esc_html__('UUID exist: %s', WC_EL_INV_TEXTDOMAIN), $uuid)),
                    'code'    => $preconditionError['code'],
                ]);
            }

            return;
        }

        $lockKey = \WcElectronInvoice\Functions\buildDbLockKey('peppol', 'create_and_send', (int)$order->get_id(),
            (string)$provider, $metaKey);
        $lockDecision = \WcElectronInvoice\Functions\evaluateLockBusyDecision(
            \WcElectronInvoice\Functions\acquireDbLock($lockKey, 0),
            \WcElectronInvoice\Functions\isBackgroundExecutionMode($method, ['cronjob'])
        );
        if (! $lockDecision['continue']) {
            if ($lockDecision['respond_error']) {
                $lockError = \WcElectronInvoice\Functions\mapLockBusyError('peppol', 'create_and_send');
                wp_send_json_error([
                    'message' => esc_html__('Action skipped: another send/create process is already running for this order.',
                        WC_EL_INV_TEXTDOMAIN),
                    'code'    => $lockError['code'],
                ]);
            }

            return;
        }

        try {
            add_filter('wc_el_inv-params_filter_before_api_request', function ($params) {
                $integrationMeta = \WcElectronInvoice\Functions\buildNativeCreateIntegrationMeta('peppol');
                if (! empty($integrationMeta['integration'])) {
                    $params['integration'] = $integrationMeta['integration'];
                }

                return $params;
            });

            $data       = getXmlFromOrder($order);
            $decodedJson = \WcElectronInvoice\Functions\safeJsonDecode($data);
            $response   = $decodedJson['data'];
            $overquotaPayload = \WcElectronInvoice\Functions\extractPopApiOverquotaUiPayload($response);
            if (\WcElectronInvoice\Functions\isLikelyTimeoutError($data)) {
                \WcElectronInvoice\InvoiceApi::markNativeTimeoutPending($order, 'peppol', $type);
            }

            if (is_array($overquotaPayload)) {
                \WcElectronInvoice\Functions\persistPopApiOverquotaState($order, $overquotaPayload);
                \WcElectronInvoice\Functions\log(
                    \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                        'overquota block while generating XML') .
                    "\n" . print_r($overquotaPayload, true) . "\n"
                );

                if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                    wp_send_json_error($overquotaPayload, (int)($overquotaPayload['status'] ?? 500));
                }

                return;
            }

            if (! $decodedJson['ok'] || ! is_object($response)) {
                if (\WcElectronInvoice\Functions\isLikelyTimeoutError($data)) {
                    \WcElectronInvoice\InvoiceApi::markNativeTimeoutPending($order, 'peppol', $type);
                }
                \WcElectronInvoice\Functions\log(
                    \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                        'check json response: Invalid response from the XML generator:') .
                    "\n" . print_r($data, true) .
                    (! empty($decodedJson['error']) ? "\njson_error: " . $decodedJson['error'] : '') . "\n"
                );

                if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                    wp_send_json_error([
                        'message' => \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                            esc_html__('Invalid response from the XML generator.',
                                WC_EL_INV_TEXTDOMAIN)),
                        'raw'     => $data,
                        'error'   => $decodedJson['error'],
                    ]);
                }

                return;
            }

            if (
                ! property_exists($response, 'message') ||
                ! property_exists($response, 'data') ||
                ! property_exists($response, 'xml_string')
            ) {
                if (\WcElectronInvoice\Functions\isLikelyTimeoutError($response)) {
                    \WcElectronInvoice\InvoiceApi::markNativeTimeoutPending($order, 'peppol', $type);
                }
                \WcElectronInvoice\Functions\log(
                    \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                        'check json property: Invalid response from the XML generator:') .
                    "\n" . print_r($response, true) . "\n"
                );

                if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                    wp_send_json_error([
                        'message' => \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                            esc_html__('Invalid response from the XML generator.',
                                WC_EL_INV_TEXTDOMAIN)),
                        'check'   => 'json property',
                        'raw'     => $response,
                    ]);
                }

                return;
            }

            $responseData  = is_object($response->data ?? null) ? $response->data : (object)[];
            $success       = filter_var($response->success ?? false, FILTER_VALIDATE_BOOLEAN);
            $code          = $response->code ?? 0;
            $responseError = false;
            $uuid          = ! empty($responseData->uuid) ? $responseData->uuid : null;
            if (! $success && $code !== 202) {
                $message = \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                    esc_html__('Invalid response from the XML generator.',
                        WC_EL_INV_TEXTDOMAIN));
                $detail  = \WcElectronInvoice\Functions\extractNativeErrorDetail($response);
                if ('' !== $detail) {
                    $message .= ' ' . $detail;
                }

                // not uuid
                if (! $uuid) {
                    $responseError = true;
                }

                // Violations
                if (! empty($responseData->violations)) {
                    $messageViolations = '';
                    $responseError     = true;
                    $violations        = (array)$responseData->violations;
                    if (! empty($violations)) {
                        $messages = array_map(function ($violation) {
                            return sprintf(
                                "Message: %s\nPropertyPath: %s\nCode: [%s]\n",
                                $violation->message ?? '',
                                $violation->propertyPath ?? '',
                                $violation->code ?? '',
                            );
                        }, $violations);

                        $messageViolations = "\n\n" . implode("\n", $messages);
                    }

                    $message = $message . $messageViolations;
                }

                if ($responseError) {
                    if (\WcElectronInvoice\Functions\isLikelyTimeoutError($response)) {
                        \WcElectronInvoice\InvoiceApi::markNativeTimeoutPending($order, 'peppol', $type);
                    }
                    \WcElectronInvoice\Functions\log(
                        \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                            'check success: Invalid response from the XML generator') . "\n" .
                        wp_json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
                    );

                    if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                        wp_send_json_error([
                            'message' => $message,
                            'check'   => 'success',
                            'raw'     => $response,
                        ]);
                    }

                    return;
                }
            }

            if (! \WcElectronInvoice\Functions\canMarkInvoiceSentWithUuid($uuid)) {
                \WcElectronInvoice\Functions\log(
                    \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                        'check uuid: Invalid response from the XML generator') . "\n" .
                    wp_json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
                );

                if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
                    $preconditionError = \WcElectronInvoice\Functions\mapNativeCreateAndSendPreconditionError('peppol',
                        'response_uuid_missing');
                    wp_send_json_error([
                        'message' => \WcElectronInvoice\Functions\prefixNativeFlowMessage('peppol',
                            esc_html__('Invalid response from the XML generator.',
                                WC_EL_INV_TEXTDOMAIN)),
                        'check'   => 'uuid',
                        'raw'     => $response,
                        'code'    => $preconditionError['code'],
                    ]);
                }

                return;
            }

            $order->update_meta($metaKey, $uuid);

            if (\WcElectronInvoice\Functions\canMarkInvoiceSentWithUuid($uuid)) {
                self::markDocumentAsSent($order);
                \WcElectronInvoice\InvoiceApi::clearNativeTimeoutPending($order);
                \WcElectronInvoice\Functions\clearPopApiOverquotaState($order);
            }
        } finally {
            \WcElectronInvoice\Functions\releaseDbLock($lockKey);
        }

        if (\WcElectronInvoice\Functions\shouldRespondWithImmediateError($method, ['cronjob'])) {
            wp_send_json_success([
                'message'  => $response->message,
                'provider' => $provider,
                'order_id' => $id,
                'uuid'     => $uuid,
                'xml'      => $response->xml_string,
                'raw'      => $response,
            ]);

            return;
        }

        \WcElectronInvoice\Functions\log(
            $response->message . "\n" .
            print_r([
                'provider' => $provider,
                'order_id' => $id,
                'uuid'     => $uuid,
                'xml'      => $response->xml_string,
                'raw'      => $response,
            ],
                true) . "\n");

        return $response;
    }

    /**
     * stateInvoice
     *
     * @return void
     */
    public static function stateInvoice()
    {
        $getPEPPOLPOPIntegrationData = self::getPEPPOLPOPIntegrationData();
        $level                       = \WcElectronInvoice\Wizard::popGetUserLevel();
        $licenseKey                  = OptionPage::init()->getOptions('license_key') ?: null;
        $provider                    = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'provider') ?? '');
        $id                          = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'id') ?? '');
        $uuid                        = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'uuid') ?? '');
        $postedType                  = strtolower(trim((string)(sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST,
            'type') ?? ''))));
        $action                      = \WcElectronInvoice\Functions\filterInput($_POST, 'action') ?? null;
        $method                      = \WcElectronInvoice\Functions\filterInput($_POST, 'method') ?? null;

        if (! \WcElectronInvoice\Functions\isBackgroundExecutionMode($method, ['cronjob', 'feCronJobUploadRequest'])) {
            if (! check_ajax_referer('wc_el_inv_ajax-ajax_nonce', 'nonce', false)) {
                wp_send_json_error(['message' => esc_html__('Unauthorized.', WC_EL_INV_TEXTDOMAIN)]);
                return;
            }
            if (! current_user_can('manage_woocommerce')) {
                wp_send_json_error(['message' => esc_html__('Forbidden.', WC_EL_INV_TEXTDOMAIN)]);
                return;
            }
        }

        $shopCountry                 = (string)(get_option('wc_el_inv-general_store_country', '') ?: '');
        $order                       = OrderQuery::instance()->getProviderOrder((int)$id, $provider);
        $documentType                = is_object($order) && method_exists($order, 'get_type')
            ? \WcElectronInvoice\Functions\resolveDocumentTypeFromOrderType((string)$order->get_type())
            : 'invoice';
        $type                        = 'credit_note' === $documentType ? 'credit-note' : 'invoice';
        if ('invoice' === $postedType || 'credit-note' === $postedType || 'credit_note' === $postedType) {
            $type = 'credit_note' === $postedType ? 'credit-note' : $postedType;
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') ||
            (! $getPEPPOLPOPIntegrationData->active_plugin_integration ||
             ! $getPEPPOLPOPIntegrationData->peppol_integration)
        ) {
            wp_send_json_error([
                'message' => esc_html__('Action not allowed.',
                    WC_EL_INV_TEXTDOMAIN),
            ]);

            return;
        }

        // I check the action parameter if it does not match I get an error
        if ('stateInvoice' !== $action) {
            wp_send_json_error([
                'message' => esc_html__('Action not valid.',
                    WC_EL_INV_TEXTDOMAIN),
            ]);

            return;
        }

        if ('' === $uuid) {
            \WcElectronInvoice\Functions\log("PEPPOL stateInvoice - check uuid: Missing uuid parameter" . "\n");

            wp_send_json_error([
                'message' => esc_html__('PEPPOL stateInvoice - check uuid: Missing uuid parameter',
                    WC_EL_INV_TEXTDOMAIN),
                'uuid'    => $uuid,
            ]);

            return;
        }

        /**
         * State request
         */
        $zone     = strtolower(trim($shopCountry));
        $response = wp_remote_post(
            esc_url_raw(WC_EL_INV_API_URL . 'peppol/document-get'),
            [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'X-API-Key'    => $licenseKey,
                ],
                'body'    => json_encode([
                    'license_key' => "{$licenseKey}",
                    'type'        => "{$type}",
                    'integration' => [
                        'uuid' => "{$uuid}",
                        'zone' => "{$zone}",
                    ],
                ]),
                'timeout' => 5,
            ]
        );

        $body       = '';
        $success    = false;
        $message    = 'error';
        $decodedRaw = null;

        if (is_wp_error($response)) {
            $message = $response->get_error_message();
            $code    = $response->get_error_code();
            error_log('method PEPPOL stateInvoice error: ' . $message);
        } else {
            $code    = wp_remote_retrieve_response_code($response);
            $body    = wp_remote_retrieve_body($response);
            $decodedAssoc  = \WcElectronInvoice\Functions\safeJsonDecode($body, true);
            $decodedObject = \WcElectronInvoice\Functions\safeJsonDecode($body, false);
            $data          = $decodedAssoc['data'];
            if ($decodedObject['ok'] && is_object($decodedObject['data'])) {
                $decodedRaw = $decodedObject['data'];
            }
            if (is_array($data) && isset($data['data']['peppolMessage'])) {
                $success = (bool)($data['data']['peppolMessage']['success'] ?? false);
                if (! $success && isset($data['data']['peppolMessage']['errorMessage'])) {
                    $message = $data['data']['peppolMessage']['errorMessage'];
                }
            } elseif (is_array($data) && isset($data['message']) && is_string($data['message']) && '' !== trim($data['message'])) {
                $message = $data['message'];
            }
        }

        if (! $success) {
            wp_send_json_error([
                'message'  => $message,
                'provider' => $provider,
                'order_id' => $id,
                'success'  => false,
                'raw'      => $decodedRaw,
            ]);
        }

        wp_send_json_success([
            'message'  => __('Invoice delivered successfully', WC_EL_INV_TEXTDOMAIN),
            'provider' => $provider,
            'success'  => true,
            'order_id' => $id,
            'raw'      => $decodedRaw,
        ]);
    }
}
