<?php

namespace Sibs\Stargate\Api;

use Sibs\Stargate\Constants\OrderStatus;
use Sibs\Stargate\Constants\PaymentStatus;
use Sibs\Stargate\Constants\PaymentTypes;
use Sibs\Stargate\Constants\WoocommerceOrderStatus;
use Sibs\Stargate\Exceptions\SibsException;
use Sibs\Stargate\Loggers\SibsLogger;
use Sibs\Stargate\Models\SibsGeneralModels;
use Sibs\Stargate\Utils\SibsVersion;

defined('ABSPATH') || exit;

class AsyncRefund extends ApiAbstract
{
    /**
     * SIBS: Process.
     */
    public static function process(\WC_Order $wc_order)
    {
        SibsLogger::debug("[process_async_refund] order_id: {$wc_order->get_id()}");

        $is_sibs_payment = SibsVersion::sibs_is_order_from_sibs($wc_order);

        if (!$is_sibs_payment) {
            throw new SibsException(
                __('Order is not a SIBS payment', 'sibs-woo-stg')
            );
        }

        $payment_status = $wc_order->get_status();
        $status_to_refund = [
            OrderStatus::PROCESSING,
            OrderStatus::COMPLETED,
            OrderStatus::PARTIALLY_CAPTURED,
            OrderStatus::PARTIALLY_REFUNDED,
        ];

        if (!in_array($payment_status, $status_to_refund)) {
            throw new SibsException(
                sprintf(
                    // translators: Payment Status
                    __('Order is cannot be refunded in status %s', 'sibs-woo-stg'),
                    esc_attr($payment_status)
                )
            );
        }

        $sibs_payment = SibsGeneralModels::get_transaction($wc_order);
        $payment_type = PaymentTypes::RFND;
        $error_message = __('Refund request has an ERROR', 'sibs-woo-stg');
        $amount = $wc_order->get_total();

        $log_sibs_payment = $sibs_payment;
        $log_sibs_payment['formConfig']
        = $log_sibs_payment['formConfig'] = json_decode($log_sibs_payment['formConfig'], true);
        $log_sibs_payment['spg_style'] = json_decode($log_sibs_payment['spg_style'], true);

        SibsLogger::debug('[process_async_refund] sibs_payment', [
            'data' => $log_sibs_payment,
        ]);

        $backoffice_config = self::get_backoffice_config(
            $sibs_payment,
            $payment_type,
            $amount,
            $error_message
        );

        $backoffice_result = self::sibs_do_back_office_payment($wc_order, $backoffice_config);
        SibsGeneralModels::update_transaction($wc_order, [
            'refunded_id' => $backoffice_result['response']['transactionID'],
            'refund_status' => $backoffice_result['response']['paymentStatus'],
        ]);

        if (!$backoffice_result['is_valid']) {
            throw new SibsException($error_message);
        }

        switch ($backoffice_result['response']['paymentStatus']) {
            case PaymentStatus::SUCCESS:
                $refund_status = $backoffice_config['order_status'];
                SibsLogger::debug('[async_refund] SUCCESS');

                break;

            case PaymentStatus::PENDING:
                $refund_status = WoocommerceOrderStatus::PENDING_REFUND;
                SibsLogger::debug('[async_refund] PENDING');

                break;

            default:
                throw new SibsException(
                    __('Refund request denied by SIBS', 'sibs-woo-stg')
                );
        }

        $amountMSG = "{$amount} {$wc_order->get_currency()}";

        $note_message = sprintf(
            // translators: Amount Message
            __('Order is Pending for Refund with %s', 'sibs-woo-stg'),
            $amountMSG
        );

        try {
            $wc_order->update_status($refund_status);
        } catch (\Throwable $t) {
            SibsLogger::error($t->getMessage());
        }

        SibsGeneralModels::update_transaction($wc_order, [
            'payment_status' => $refund_status,
            'refunded_amount' => $backoffice_result['response']['amount']['value'] + $sibs_payment['refunded_amount'],
            'refund_information' => $note_message.(!empty($sibs_payment['refund_information']) ? ', '.$sibs_payment['refund_information'] : ''),
        ]);

        if (PaymentStatus::PENDING === $backoffice_result['response']['paymentStatus']) {
            return sprintf(
                __('BLIK Refund is asyncronous, you have to make a refund inquiry to get the real refund status', 'sibs-woo-stg'),
                $wc_order->get_id()
            );
        }

        // Refund Success
        return sprintf(
            // translators: Order Id, Amount Message
            __('Refund success for order #%1$s with %2$s', 'sibs-woo-stg'),
            $wc_order->get_id(),
            $amountMSG
        );
    }

    /**
     * SIBS Refund Async Order Add Button.
     *
     * @param mixed $order
     */
    public static function add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '5', esc_attr(__('SIBS Async Refund', 'sibs-woo-stg')));
    }
}
