<?php

namespace Sibs\Stargate\Core;

use Sibs\Stargate\Config\SibsConfig;
use Sibs\Stargate\Constants\Environments;
use Sibs\Stargate\Constants\PaymentTypes;
use Sibs\Stargate\Constants\Plugin;
use Sibs\Stargate\Exceptions\StgException;
use Sibs\Stargate\Loggers\SibsLogger;
use Sibs\Stargate\Models\SibsGeneralModels;

defined('ABSPATH') || exit;

class SibsPaymentCore
{
    protected static array $ack_patterns = [
        '/^(000)/',
    ];

    /**
     * SIBS GET Payment Widget Content.
     *
     * @param string $url
     *
     * @return array
     */
    public static function sibs_get_payment_widget_content($url)
    {
        SibsLogger::debug('Entrou em sibs_get_payment_widget_content');
        $args = [
            'sslverify' => self::sibs_get_ssl_verify(),
            'conn_timeout' => 90,
            'timeout' => 90,
            'sibs_request' => true,
        ];

        SibsLogger::debug("[sibs_get_payment_widget_content] url: {$url}");
        SibsLogger::debug('[sibs_get_payment_widget_content] args: '.SibsLogger::prettify($args));

        $response = wp_remote_get($url, $args);

        return self::sibs_get_wp_response($response);
    }

    /**
     * SIBS Get Checkout Result.
     *
     * @param array $post_data
     *
     * @return array
     */
    public static function sibs_get_checkout_result($post_data)
    {
        SibsLogger::debug('Entrou em sibs_get_checkout_result');
        $checkout_url = self::sibs_get_checkout_url();

        return self::sibs_get_response_data($checkout_url, $post_data);
    }

    /**
     * SIBS Get Payment Widget URL.
     *
     * @param string $transaction_id
     *
     * @return string
     */
    public static function sibs_get_payment_widget_url($transaction_id)
    {
        SibsLogger::debug('Entrou em sibs_get_payment_widget_url');
        $environment_file = SibsFunctions::get_environment();
        $widget_endpoints = $environment_file['widget_endpoints'];
        $environment = SibsConfig::getEnvironment();

        return $widget_endpoints[$environment].$transaction_id;
    }

    /**
     * SIBS Get Payment Status.
     *
     * @param string $transaction_id
     *
     * @return array|\WP_Error
     */
    public static function sibs_get_payment_status($transaction_id)
    {
        SibsLogger::debug('Entrou em sibs_get_payment_status');

        $payment_status_url = self::sibs_get_payment_status_url($transaction_id);

        return self::sibs_get_payment_response($payment_status_url);
    }

    /**
     * SIBS Back Office Operation.
     *
     * @param string $reference_id
     * @param array  $parameters
     *
     * @return string
     */
    public static function sibs_back_office_operation(\WC_Order $wc_order, $reference_id, $parameters)
    {
        SibsLogger::debug('Entrou em sibs_back_office_operation');

        $back_office_url = self::sibs_get_spg_back_office_url($reference_id, $parameters);
        $post_data = self::sibs_set_spg_back_office_parameters($wc_order, $reference_id, $parameters);

        return self::sibs_get_response_data($back_office_url, $post_data);
    }

    /**
     * SIBS Update Status.
     *
     * @param string $reference_id
     *
     * @return array|\WP_Error
     */
    public static function sibs_update_status($reference_id)
    {
        SibsLogger::debug('Entrou em sibs_update_status');

        $status_url = self::sibs_get_back_office_url($reference_id);

        return self::sibs_get_payment_response($status_url);
    }

    /**
     * SIBS Get Transaction Result.
     *
     * @param bool $return_code
     *
     * @return string
     */
    public static function sibs_get_transaction_result($return_code = false)
    {
        SibsLogger::debug('Entrou em sibs_get_transaction_result');
        SibsLogger::debug("return_code: {$return_code}");

        if (false === $return_code) {
            SibsLogger::debug('transaction_result: '.Plugin::NOK);

            return Plugin::NOK;
        }

        foreach (self::$ack_patterns as $pattern) {
            if (preg_match($pattern, $return_code)) {
                SibsLogger::debug('transaction_result: '.Plugin::ACK);

                return Plugin::ACK;
            }
        }

        SibsLogger::debug('transaction_result: '.Plugin::NOK);

        return Plugin::NOK;
    }

    /**
     * SIBS Get Return Code.
     *
     * @return string
     */
    public static function sibs_get_return_code(array $payment_result)
    {
        $payment_result = $payment_result['response'] ?? $payment_result;
        $payment_result = $payment_result['returnStatus'] ?? $payment_result;
        $payment_result = $payment_result['respObject'] ?? $payment_result;

        return $payment_result['statusCode']
            ?? $payment_result['code']
            ?? StgException::ERROR_CODE;
    }

    /**
     * SIBS Get Return Message.
     *
     * @return string
     */
    public static function sibs_get_return_msg(array $payment_result)
    {
        $payment_result = $payment_result['response'] ?? $payment_result;
        $payment_result = $payment_result['returnStatus'] ?? $payment_result;
        $payment_result = $payment_result['respObject'] ?? $payment_result;

        return $payment_result['statusMsg']
            ?? StgException::ERROR_UNKNOWN;
    }

    /**
     * SIBS Get Checkout URL.
     *
     * @return string
     */
    private static function sibs_get_checkout_url()
    {
        SibsLogger::debug('Entrou em sibs_get_checkout_url');
        $environment_file = SibsFunctions::get_environment();
        $checkout_endpoints = $environment_file['checkout_endpoints'];
        $environment = SibsConfig::getEnvironment();

        return $checkout_endpoints[$environment];
    }

    /**
     * SIBS Get Payment Status URL.
     *
     * @param string $transaction_id
     *
     * @return string
     */
    private static function sibs_get_payment_status_url($transaction_id)
    {
        SibsLogger::debug('Entrou em sibs_get_payment_status_url');
        $environment_file = SibsFunctions::get_environment();
        $checkout_endpoints = $environment_file['checkout_endpoints'];
        $environment = SibsConfig::getEnvironment();

        return $checkout_endpoints[$environment]."/{$transaction_id}/status";
    }

    /**
     * SIBS Get BackOffice URL.
     *
     * @param string $reference_id
     *
     * @return string
     */
    private static function sibs_get_back_office_url($reference_id)
    {
        SibsLogger::debug('Entrou em sibs_get_back_office_url');
        $environment_file = SibsFunctions::get_environment();
        $back_office_endpoints = $environment_file['back_office_endpoints'];
        $environment = SibsConfig::getEnvironment();

        return $back_office_endpoints[$environment].$reference_id;
    }

    /**
     * SIBS Get SPG BackOffice URL.
     *
     * @return string
     */
    private static function sibs_get_spg_back_office_url(string $reference_id, array $parameters)
    {
        SibsLogger::debug('Entrou em sibs_get_spg_back_office_url');
        $environment_file = SibsFunctions::get_environment();
        $back_office_endpoints = $environment_file['back_office_endpoints'];
        $environment = SibsConfig::getEnvironment();
        $end_url = self::get_endpoint($parameters['payment_type']);

        return $back_office_endpoints[$environment].$reference_id.$end_url;
    }

    /**
     * Get Endpoint.
     *
     * @param string $payment_type
     *
     * @return string
     */
    private static function get_endpoint($payment_type)
    {
        SibsLogger::debug('Entrou em get_endpoint');

        switch ($payment_type) {
            case PaymentTypes::CAPT:
                return '/capture';

                break;

            case PaymentTypes::RFND:
                return '/refund';

                break;

            case PaymentTypes::CAUT:
                return '/cancellation';

                break;

            default:
                return '/none';
        }
    }

    /**
     * SIBS Get SSL Verify.
     *
     * @return bool
     */
    private static function sibs_get_ssl_verify()
    {
        SibsLogger::debug('Entrou em sibs_get_ssl_verify');
        $environment = SibsConfig::getEnvironment();

        if (
            in_array($environment, [
                Environments::DEV,
                Environments::TST,
                Environments::QLY,
                Environments::CER,
            ])
        ) {
            return false;
        }

        return false; // Always false due to cURL issues in some environments
    }

    /**
     * SIBS Get WP Response.
     *
     * @param mixed $response
     *
     * @return array
     */
    private static function sibs_get_wp_response($response)
    {
        SibsLogger::debug('Entrou em sibs_get_wp_response');
        if (is_wp_error($response)) {
            $result['response'] = __('Unfortunately, your transaction has failed. Please try again', 'sibs-woo-stg');
            $result['is_valid'] = false;
            $error_code = $response->get_error_code();
            $error_message = $response->get_error_message();
            SibsLogger::error('Error Code: '.SibsLogger::prettify($error_code));
            SibsLogger::error('Error Message: '.SibsLogger::prettify($error_message));

            if (false !== strpos($error_message, 'cURL error 60')) {
                $result['response'] = 'ERROR_MERCHANT_SSL_CERTIFICATE';
            }

            return $result;
        }

        $response = wp_remote_retrieve_body($response);
        $json_response = json_decode($response, true);

        $result['response'] = $json_response ?? $response;
        $result['is_valid'] = true;

        SibsLogger::debug('result: '.SibsLogger::prettify($result));

        return $result;
    }

    /**
     * SIBS Get Headers.
     *
     * @return array
     */
    private static function sibs_get_headers()
    {
        SibsLogger::debug('Entrou em sibs_get_headers');

        $token = SibsConfig::getToken();
        $clientId = SibsConfig::getClientId();

        $headers = [
            'content-type' => 'application/json',
            'charset' => 'UTF-8',
        ];

        if (!empty($token)) {
            $headers = array_merge($headers, [
                'Authorization' => "Bearer {$token}",
            ]);
        }

        if (!empty($clientId)) {
            $headers = array_merge($headers, [
                'X-IBM-Client-Id' => $clientId,
            ]);
        }

        return $headers;
    }

    /**
     * SIBS Get Response Data.
     *
     * @param string $url
     * @param array  $data
     *
     * @return array
     */
    private static function sibs_get_response_data($url, $data)
    {
        SibsLogger::debug('Entrou em sibs_get_response_data');
        $data_json = json_encode($data);
        $headers = self::sibs_get_headers();

        $args = [
            'headers' => $headers,
            'body' => $data_json,
            'sslverify' => self::sibs_get_ssl_verify(),
            'conn_timeout' => 90,
            'timeout' => 90,
            'sibs_request' => true,
        ];

        SibsLogger::debug("[sibs_get_response_data] url: {$url}");
        SibsLogger::debug('[sibs_get_response_data] args: '.SibsLogger::prettify($args));

        $response = wp_remote_post($url, $args);

        return self::sibs_get_wp_response($response);
    }

    /**
     * SIBS Get Payment Response.
     *
     * @param string $url
     *
     * @return array|\WP_Error
     */
    private static function sibs_get_payment_response($url)
    {
        SibsLogger::debug('Entrou em sibs_get_payment_response');
        $headers = self::sibs_get_headers();

        $args = [
            'headers' => $headers,
            'sslverify' => self::sibs_get_ssl_verify(),
        ];

        SibsLogger::debug("url: {$url}");
        SibsLogger::debug('args: '.SibsLogger::prettify($args));

        $response = wp_remote_get($url, $args);

        if (is_wp_error($response)) {
            SibsLogger::debug('response: error');

            return false;
        }

        $response = json_decode(wp_remote_retrieve_body($response), true);

        SibsLogger::debug('response: '.SibsLogger::prettify($response));

        return $response;
    }

    /**
     * SIBS set SPG Back Office Parameters.
     *
     * @param string $reference_id
     * @param array  $parameters
     *
     * @return array
     */
    private static function sibs_set_spg_back_office_parameters(\WC_Order $wc_order, $reference_id, $parameters)
    {
        SibsLogger::debug('Entrou em sibs_set_spg_back_office_parameters');
        SibsLogger::debug("order_id: {$wc_order->get_id()}");
        SibsLogger::debug('BO order: '.SibsLogger::prettify($parameters));

        $transaction = SibsGeneralModels::get_transaction($wc_order);

        return [
            'merchant' => [
                'terminalId' => SibsConfig::getTerminalId(),
                'channel' => SibsConfig::getChannel(),
                'merchantTransactionId' => $transaction['order_no'],
            ],
            'transaction' => [
                'amount' => [
                    'value' => floatval(SibsFunctions::sibs_set_number_format($parameters['amount'])),
                    'currency' => $parameters['currency'],
                ],
                'description' => SibsConfig::getEcommerceName(),
                'transactionTimestamp' => wp_date('Y-m-d\TH:i:s.vP'),
                'originalTransaction' => [
                    'id' => $reference_id,
                    'datetime' => $transaction['date'],
                ],
            ],
        ];
    }
}
