<?php

namespace WKO\Controllers;

use WKO\Controllers\Actions\CancellOrder;
use WKO\Helpers\Utils;

/**
 * Name: Gateways
 * Create customs status
 * @package Controllers
 * @since 1.0.0
 */
class Status
{
    public function __construct()
    {
        $this->register_koin_custom_statuses();

        add_filter('wc_order_statuses', [$this, 'add_koin_custom_statuses'], 10, 1);
        add_action('woocommerce_order_status_changed', [$this, 'on_koin_status_changed'], 10, 3);
        add_action('woocommerce_order_status_awaiting-analysis_to_failed', [$this, 'maybeRestoreStock'], 10);
    }

    /**
     * Controller Koin statuses
     * @since 1.0.0
     * @return array
     */
    private function get_koin_status()
    {
        return [
            'wc-awaiting-payment'  => __('Awaiting payment', 'wc-koin-official'),
            'wc-awaiting-analysis' => __('Under analysist', 'wc-koin-official')
        ];
    }

    /**
     * Register Koin custom statuses
     * @since 1.0.0
     * @return void
     */
    public function register_koin_custom_statuses()
    {
        $statuses = $this->get_koin_status();

        foreach ($statuses as $key => $status) {
            register_post_status($key, [
                'label'                     => $status,
                'public'                    => true,
                'exclude_from_search'       => false,
                'show_in_admin_all_list'    => true,
                'show_in_admin_status_list' => true,
            ]);
        }
    }

    /**
     * Add Koin custom statuses
     * @since 1.0.0
     * @param array $order_statuses
     * @return array
     */
    public function add_koin_custom_statuses($order_statuses)
    {
        $statuses = $this->get_koin_status();

        foreach ($statuses as $key => $status) {
            if (!isset($order_statuses[$key])) {
                $order_statuses[$key] = $status;
            }
        }

        return $order_statuses;
    }

    /**
     * Call koin cancellation method
     * @since 1.0.0
     * @param int $id
     * @param string $from
     * @param string $to
     * @return void
     */
    public function on_koin_status_changed($id, $from, $to)
    {
        $order = wc_get_order($id);

        $payment_method  = $order->get_payment_method();
        $payment_methods = Utils::koin_payment_methods();

        if (array_intersect($payment_methods, [$payment_method]) && $to === 'cancelled') {
            $koin = new Koin();
            $koin_response = $koin->get_order($id);

            $should_cancel = false;
            $koin_status = null;

            if (! isset($koin_response['error']) && isset($koin_response['body'])) {
                $body = json_decode($koin_response['body']);

                if (isset($body->status->type)) {
                    $koin_status = $body->status->type;

                    $cancellable_statuses = ['Opened', 'Authorized'];

                    if (in_array($koin_status, $cancellable_statuses)) {
                        $should_cancel = true;
                    }
                }
            }

            if ($should_cancel) {
                new CancellOrder($id);
            }
        }
    }

    /**
     * Restores stock levels for an order if the payment method is a Koin payment method.
     *
     * This method is triggered when an order status changes from awaiting-analysis to failed. It checks if the order
     * uses a Koin payment method and, if so, attempts to restore the stock levels
     * for the order items.
     *
     * @param int    $order_id    The ID of the order being processed.
     * @return void
     */
    public function maybeRestoreStock($order_id)
    {
        $order = wc_get_order($order_id);


        $payment_method = $order->get_payment_method();
        $payment_methods = Utils::koin_payment_methods();

        if (!in_array($payment_method, $payment_methods)) {
            return;
        }

        wc_maybe_increase_stock_levels($order_id);
    }
}
