<?php

namespace Calio\Admin\DashboardWidgets;

use Automattic\WooCommerce\Utilities\OrderUtil;
use Calio\Support\Settings;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Summarizes the last seven days of WooCommerce revenue by operational risk.
 */
final class OrderProcessingMonitor
{
    private const CACHE_KEY = 'calio_order_processing_monitor_v1';
    private const CACHE_TTL = 5 * MINUTE_IN_SECONDS;
    private const DASHBOARD_SLUG = 'order-processing-monitor';

    public function __construct()
    {
        add_action('wp_dashboard_setup', [$this, 'register']);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
        add_filter('woocommerce_order_list_table_prepare_items_query_args', [$this, 'filter_hpos_orders']);
        add_action('pre_get_posts', [$this, 'filter_legacy_orders']);
    }

    public function register(): void
    {
        if (
            !Settings::is_dashboard_widget_enabled(self::DASHBOARD_SLUG)
            || !$this->can_view()
        ) {
            return;
        }

        wp_add_dashboard_widget(
            'calio_order_processing_monitor',
            esc_html__('Order Processing Monitor', 'calio-addon'),
            [$this, 'render'],
            null,
            null,
            'normal',
            'high'
        );
    }

    public function enqueue_assets(string $hook_suffix): void
    {
        if (
            $hook_suffix !== 'index.php'
            || !Settings::is_dashboard_widget_enabled(self::DASHBOARD_SLUG)
            || !$this->can_view()
        ) {
            return;
        }

        wp_enqueue_style(
            'calio-dashboard-widget',
            CALIO_URL . 'assets/admin/dashboard-widget.css',
            ['dashicons'],
            CALIO_VERSION
        );
    }

    public function render(): void
    {
        if (!$this->can_view()) {
            return;
        }

        if (!function_exists('wc_get_orders')) {
            echo '<div class="calio-order-monitor__notice">';
            echo '<p>' . esc_html__('WooCommerce must be installed and active to monitor order revenue.', 'calio-addon') . '</p>';
            echo '</div>';
            return;
        }

        $data = $this->revenue_data();
        $cards = [
            'completed' => [
                'label' => __('Completed', 'calio-addon'),
                'note' => __('Completed + Processing', 'calio-addon'),
                'icon' => 'dashicons-yes-alt',
            ],
            'pending' => [
                'label' => __('Pending Action', 'calio-addon'),
                'note' => __('Pending + On-Hold', 'calio-addon'),
                'icon' => 'dashicons-clock',
            ],
            'risk' => [
                'label' => __('Revenue at Risk', 'calio-addon'),
                'note' => __('Failed + Cancelled', 'calio-addon'),
                'icon' => 'dashicons-warning',
            ],
        ];

        echo '<div class="calio-order-monitor">';
        echo '<div class="calio-order-monitor__intro">';
        echo '<div>';
        echo '<strong>' . esc_html__('Last 7 days', 'calio-addon') . '</strong>';
        echo '<span>' . esc_html__('Revenue distribution by order outcome', 'calio-addon') . '</span>';
        echo '</div>';
        echo '<span class="calio-order-monitor__cached">';
        echo esc_html(
            sprintf(
                /* translators: %s: time when the cached report was generated. */
                __('Updated %s', 'calio-addon'),
                $data['generated_at']
            )
        );
        echo '</span>';
        echo '</div>';

        echo '<div class="calio-order-monitor__grid">';
        foreach ($cards as $key => $card) {
            $amount = (float) $data[$key];
            $percentage = $data['total'] > 0
                ? min(100, round(($amount / $data['total']) * 100, 1))
                : 0;
            $classes = 'calio-order-monitor__card is-' . $key;
            if ($key === 'risk' && $amount > 0) {
                $classes .= ' has-risk';
            }

            echo '<article class="' . esc_attr($classes) . '">';
            echo '<div class="calio-order-monitor__card-head">';
            echo '<span class="dashicons ' . esc_attr($card['icon']) . '" aria-hidden="true"></span>';
            echo '<div>';
            echo '<strong>' . esc_html($card['label']) . '</strong>';
            echo '<small>' . esc_html($card['note']) . '</small>';
            echo '</div>';
            echo '</div>';
            echo '<div class="calio-order-monitor__amount">';
            echo esc_html(wp_strip_all_tags(wc_price($amount)));
            echo '</div>';
            echo '<progress class="calio-order-monitor__progress" max="100" value="' . esc_attr((string) $percentage) . '" aria-label="' . esc_attr(
                sprintf(
                    /* translators: %s: revenue percentage. */
                    __('%s percent of analyzed revenue', 'calio-addon'),
                    (string) $percentage
                )
            ) . '"></progress>';
            echo '<div class="calio-order-monitor__percentage">';
            echo esc_html(number_format_i18n($percentage, 1) . '%');
            echo '</div>';
            echo '</article>';
        }
        echo '</div>';

        if ($data['risk'] > 0) {
            echo '<div class="calio-order-monitor__alert">';
            echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
            echo '<p>';
            echo '<strong>' . esc_html__('Revenue needs attention.', 'calio-addon') . '</strong> ';
            echo esc_html(
                sprintf(
                    /* translators: %s: formatted revenue amount. */
                    __('%s is currently tied to failed or cancelled orders.', 'calio-addon'),
                    wp_strip_all_tags(wc_price((float) $data['risk']))
                )
            );
            echo '</p>';
            echo '</div>';
        }

        echo '<div class="calio-order-monitor__footer">';
        echo '<span>' . esc_html__('Results are cached for 5 minutes.', 'calio-addon') . '</span>';
        echo '<a class="button button-primary" href="' . esc_url($this->at_risk_orders_url()) . '">';
        echo esc_html__('View At-Risk Orders', 'calio-addon');
        echo '</a>';
        echo '</div>';
        echo '</div>';
    }

    /**
     * Applies the combined status filter to the HPOS order table.
     *
     * @param array<string, mixed> $query_args
     * @return array<string, mixed>
     */
    public function filter_hpos_orders(array $query_args): array
    {
        if (!$this->is_at_risk_request() || !$this->can_view()) {
            return $query_args;
        }

        $query_args['status'] = $this->action_statuses(true);
        return $query_args;
    }

    /**
     * Applies the combined status filter to the legacy shop_order table.
     */
    public function filter_legacy_orders(\WP_Query $query): void
    {
        if (
            !is_admin()
            || !$query->is_main_query()
            || !$this->is_at_risk_request()
            || !$this->can_view()
        ) {
            return;
        }

        if ((string) $query->get('post_type') !== 'shop_order') {
            return;
        }

        $query->set('post_status', $this->action_statuses(true));
    }

    /**
     * @return array{completed: float, pending: float, risk: float, total: float, generated_at: string}
     */
    private function revenue_data(): array
    {
        $cached = get_transient(self::CACHE_KEY);
        if (is_array($cached) && isset($cached['completed'], $cached['pending'], $cached['risk'], $cached['total'], $cached['generated_at'])) {
            return $cached;
        }

        $totals = [
            'completed' => 0.0,
            'pending' => 0.0,
            'risk' => 0.0,
            'total' => 0.0,
            'generated_at' => wp_date(get_option('time_format')),
        ];
        $orders = wc_get_orders(
            [
                'limit' => -1,
                'status' => array_merge(
                    ['completed', 'processing'],
                    $this->action_statuses(false)
                ),
                'date_created' => '>' . (time() - WEEK_IN_SECONDS),
                'orderby' => 'date',
                'order' => 'DESC',
                'return' => 'objects',
            ]
        );

        foreach ($orders as $order) {
            if (!$order instanceof \WC_Order) {
                continue;
            }

            $status = $order->get_status();
            $amount = (float) $order->get_total();

            if (in_array($status, ['completed', 'processing'], true)) {
                $totals['completed'] += $amount;
            } elseif (in_array($status, ['pending', 'on-hold'], true)) {
                $totals['pending'] += $amount;
            } elseif (in_array($status, ['failed', 'cancelled'], true)) {
                $totals['risk'] += $amount;
            }
        }

        $totals['total'] = $totals['completed'] + $totals['pending'] + $totals['risk'];
        set_transient(self::CACHE_KEY, $totals, self::CACHE_TTL);

        return $totals;
    }

    /**
     * @return string[]
     */
    private function action_statuses(bool $with_prefix): array
    {
        $statuses = ['failed', 'cancelled', 'pending', 'on-hold'];

        if (!$with_prefix) {
            return $statuses;
        }

        return array_map(
            static fn(string $status): string => 'wc-' . $status,
            $statuses
        );
    }

    private function at_risk_orders_url(): string
    {
        $base_url = admin_url('edit.php?post_type=shop_order');

        if (
            class_exists(OrderUtil::class)
            && OrderUtil::custom_orders_table_usage_is_enabled()
        ) {
            $base_url = admin_url('admin.php?page=wc-orders');
        }

        return add_query_arg('calio_order_risk', '1', $base_url);
    }

    private function is_at_risk_request(): bool
    {
        // Read-only admin list filter; no state is changed by this request value.
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        return isset($_GET['calio_order_risk'])
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            && sanitize_key((string) wp_unslash($_GET['calio_order_risk'])) === '1';
    }

    private function can_view(): bool
    {
        return current_user_can('manage_woocommerce');
    }
}
