<?php

namespace Calio\Admin\DashboardWidgets;

use Calio\Support\Settings;

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

/**
 * Adds a focused WooCommerce product editor with safe inline price updates.
 */
final class InlineProductsManager
{
    private const DASHBOARD_SLUG = 'inline-products';
    private const MENU_SLUG = 'calio-inline-products';
    private const NONCE_ACTION = 'calio_inline_products';
    private const SCRIPT_HANDLE = 'calio-inline-products';
    private const STYLE_HANDLE = 'calio-inline-products';
    private const PER_PAGE = 25;

    public function __construct()
    {
        add_action('admin_menu', [$this, 'register_menu'], 59);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
        add_action('wp_ajax_calio_inline_products_list', [$this, 'ajax_list_products']);
        add_action('wp_ajax_calio_inline_products_save_price', [$this, 'ajax_save_price']);
    }

    public function register_menu(): void
    {
        if (!Settings::is_dashboard_widget_enabled(self::DASHBOARD_SLUG)) {
            return;
        }

        add_menu_page(
            esc_html__('Inline Products', 'calio-addon'),
            esc_html__('Inline Products', 'calio-addon'),
            'manage_woocommerce',
            self::MENU_SLUG,
            [$this, 'render_page'],
            'dashicons-store',
            59
        );
    }

    public function enqueue_assets(string $hook_suffix): void
    {
        if (
            $hook_suffix !== 'toplevel_page_' . self::MENU_SLUG
            || !$this->can_manage()
        ) {
            return;
        }

        wp_enqueue_style(
            self::STYLE_HANDLE,
            CALIO_URL . 'assets/admin/inline-products.css',
            ['dashicons'],
            CALIO_VERSION
        );
        wp_enqueue_script(
            self::SCRIPT_HANDLE,
            CALIO_URL . 'assets/admin/inline-products.js',
            [],
            CALIO_VERSION,
            true
        );
        wp_localize_script(
            self::SCRIPT_HANDLE,
            'calioInlineProducts',
            [
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce(self::NONCE_ACTION),
                'actions' => [
                    'list' => 'calio_inline_products_list',
                    'save' => 'calio_inline_products_save_price',
                ],
                'currency' => get_woocommerce_currency_symbol(),
                'labels' => [
                    'loading' => __('Loading products...', 'calio-addon'),
                    'loadFailed' => __('Products could not be loaded. Please try again.', 'calio-addon'),
                    'saving' => __('Saving...', 'calio-addon'),
                    'saved' => __('Price saved.', 'calio-addon'),
                    'saveFailed' => __('The price could not be saved.', 'calio-addon'),
                    'empty' => __('No products match this search.', 'calio-addon'),
                    'page' => __('Page', 'calio-addon'),
                    'of' => __('of', 'calio-addon'),
                    'variableNotice' => __('Edit prices on individual variations.', 'calio-addon'),
                    'noDescription' => __('This product does not have a description.', 'calio-addon'),
                    'description' => __('Description', 'calio-addon'),
                    'edit' => __('Edit', 'calio-addon'),
                    'save' => __('Save', 'calio-addon'),
                    'products' => __('products', 'calio-addon'),
                ],
            ]
        );
    }

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

        if (!function_exists('wc_get_products')) {
            echo '<div class="wrap"><div class="notice notice-error"><p>';
            echo esc_html__('WooCommerce must be installed and active to use Inline Products.', 'calio-addon');
            echo '</p></div></div>';
            return;
        }

        ?>
        <div class="wrap calio-inline-products" data-calio-inline-products>
            <header class="calio-inline-products__header">
                <div>
                    <span class="calio-inline-products__eyebrow"><?php echo esc_html__('WooCommerce Product Management', 'calio-addon'); ?></span>
                    <h1><?php echo esc_html__('Inline Products', 'calio-addon'); ?></h1>
                    <p><?php echo esc_html__('Search, sort, and update product prices without opening each product editor.', 'calio-addon'); ?></p>
                </div>
                <div class="calio-inline-products__header-icon" aria-hidden="true">
                    <span class="dashicons dashicons-store"></span>
                </div>
            </header>

            <section class="calio-inline-products__surface">
                <div class="calio-inline-products__toolbar">
                    <label class="calio-inline-products__search">
                        <span class="screen-reader-text"><?php echo esc_html__('Search products by name or SKU', 'calio-addon'); ?></span>
                        <span class="dashicons dashicons-search" aria-hidden="true"></span>
                        <input type="search" placeholder="<?php echo esc_attr__('Search product or SKU...', 'calio-addon'); ?>" data-inline-search />
                    </label>
                    <label class="calio-inline-products__sort">
                        <span><?php echo esc_html__('Sort by', 'calio-addon'); ?></span>
                        <select data-inline-sort>
                            <option value="title:ASC"><?php echo esc_html__('Product name A-Z', 'calio-addon'); ?></option>
                            <option value="title:DESC"><?php echo esc_html__('Product name Z-A', 'calio-addon'); ?></option>
                            <option value="date:DESC"><?php echo esc_html__('Newest first', 'calio-addon'); ?></option>
                            <option value="date:ASC"><?php echo esc_html__('Oldest first', 'calio-addon'); ?></option>
                            <option value="ID:DESC"><?php echo esc_html__('Highest product ID', 'calio-addon'); ?></option>
                        </select>
                    </label>
                    <button type="button" class="button" data-inline-refresh>
                        <span class="dashicons dashicons-update" aria-hidden="true"></span>
                        <?php echo esc_html__('Refresh', 'calio-addon'); ?>
                    </button>
                </div>

                <div class="calio-inline-products__notice" data-inline-notice aria-live="polite"></div>

                <div class="calio-inline-products__table-wrap">
                    <table class="widefat fixed striped calio-inline-products__table">
                        <thead>
                            <tr>
                                <th scope="col"><?php echo esc_html__('Product', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('SKU', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('Regular price', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('Sale price', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('Stock', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('Status', 'calio-addon'); ?></th>
                                <th scope="col"><?php echo esc_html__('Actions', 'calio-addon'); ?></th>
                            </tr>
                        </thead>
                        <tbody data-inline-body></tbody>
                    </table>
                    <div class="calio-inline-products__loading" data-inline-loading>
                        <span class="spinner is-active"></span>
                        <span><?php echo esc_html__('Loading products...', 'calio-addon'); ?></span>
                    </div>
                </div>

                <footer class="calio-inline-products__pagination">
                    <span data-inline-results></span>
                    <div>
                        <button type="button" class="button" data-inline-prev disabled>
                            <span class="dashicons dashicons-arrow-left-alt2" aria-hidden="true"></span>
                            <?php echo esc_html__('Previous', 'calio-addon'); ?>
                        </button>
                        <span data-inline-page></span>
                        <button type="button" class="button" data-inline-next disabled>
                            <?php echo esc_html__('Next', 'calio-addon'); ?>
                            <span class="dashicons dashicons-arrow-right-alt2" aria-hidden="true"></span>
                        </button>
                    </div>
                </footer>
            </section>

            <div class="calio-inline-products__modal" data-inline-modal hidden>
                <div class="calio-inline-products__modal-backdrop" data-inline-modal-close></div>
                <section class="calio-inline-products__modal-dialog" role="dialog" aria-modal="true" aria-labelledby="calio-inline-modal-title">
                    <header>
                        <div>
                            <span><?php echo esc_html__('Product Description', 'calio-addon'); ?></span>
                            <h2 id="calio-inline-modal-title" data-inline-modal-title></h2>
                        </div>
                        <button type="button" class="calio-inline-products__modal-close" data-inline-modal-close aria-label="<?php echo esc_attr__('Close description', 'calio-addon'); ?>">
                            <span class="dashicons dashicons-no-alt" aria-hidden="true"></span>
                        </button>
                    </header>
                    <div class="calio-inline-products__modal-content" data-inline-modal-content></div>
                </section>
            </div>
        </div>
        <?php
    }

    public function ajax_list_products(): void
    {
        if (check_ajax_referer(self::NONCE_ACTION, 'nonce', false) === false) {
            wp_send_json_error(['message' => __('Security check failed. Please refresh the page and try again.', 'calio-addon')], 403);
        }

        $this->verify_ajax_request_context();

        $page = isset($_POST['page']) ? max(1, absint(wp_unslash($_POST['page']))) : 1;
        $search = isset($_POST['search']) ? sanitize_text_field((string) wp_unslash($_POST['search'])) : '';
        $orderby = isset($_POST['orderby']) ? sanitize_key((string) wp_unslash($_POST['orderby'])) : 'title';
        $order = isset($_POST['order']) ? strtoupper(sanitize_key((string) wp_unslash($_POST['order']))) : 'ASC';
        $allowed_orderby = ['title', 'date', 'id'];

        if (!in_array($orderby, $allowed_orderby, true)) {
            $orderby = 'title';
        }
        if ($orderby === 'id') {
            $orderby = 'ID';
        }
        if (!in_array($order, ['ASC', 'DESC'], true)) {
            $order = 'ASC';
        }

        $query = [
            'limit' => self::PER_PAGE,
            'page' => $page,
            'paginate' => true,
            'status' => ['publish', 'draft', 'pending', 'private'],
            'type' => array_merge(array_keys(wc_get_product_types()), ['variation']),
            'orderby' => $orderby,
            'order' => $order,
            'return' => 'objects',
        ];

        if ($search !== '') {
            $data_store = \WC_Data_Store::load('product');
            $ids = $data_store->search_products($search, '', true, true);

            if ($ids === []) {
                wp_send_json_success([
                    'products' => [],
                    'total' => 0,
                    'pages' => 0,
                    'page' => 1,
                ]);
            }

            $query['include'] = $ids;
        }

        $results = wc_get_products($query);
        $products = [];

        foreach ($results->products as $product) {
            if (!$product instanceof \WC_Product) {
                continue;
            }

            $products[] = $this->product_payload($product);
        }

        wp_send_json_success([
            'products' => $products,
            'total' => (int) $results->total,
            'pages' => (int) $results->max_num_pages,
            'page' => min($page, max(1, (int) $results->max_num_pages)),
        ]);
    }

    public function ajax_save_price(): void
    {
        if (check_ajax_referer(self::NONCE_ACTION, 'nonce', false) === false) {
            wp_send_json_error(['message' => __('Security check failed. Please refresh the page and try again.', 'calio-addon')], 403);
        }

        $this->verify_ajax_request_context();

        $product_id = isset($_POST['productId']) ? absint(wp_unslash($_POST['productId'])) : 0;
        $product = $product_id > 0 ? wc_get_product($product_id) : false;

        if (!$product instanceof \WC_Product) {
            wp_send_json_error(['message' => __('The selected product could not be found.', 'calio-addon')], 404);
        }

        if (!$this->is_price_editable($product)) {
            wp_send_json_error(['message' => __('Edit prices on individual variations for this product type.', 'calio-addon')], 409);
        }

        $regular_raw = isset($_POST['regularPrice']) ? sanitize_text_field(wp_unslash($_POST['regularPrice'])) : '';
        $sale_raw = isset($_POST['salePrice']) ? sanitize_text_field(wp_unslash($_POST['salePrice'])) : '';
        $regular_price = $regular_raw === '' ? '' : wc_format_decimal($regular_raw);
        $sale_price = $sale_raw === '' ? '' : wc_format_decimal($sale_raw);

        if ($regular_price !== '' && (float) $regular_price < 0) {
            wp_send_json_error(['message' => __('Regular price cannot be negative.', 'calio-addon')], 422);
        }
        if ($sale_price !== '' && (float) $sale_price < 0) {
            wp_send_json_error(['message' => __('Sale price cannot be negative.', 'calio-addon')], 422);
        }
        if ($regular_price !== '' && $sale_price !== '' && (float) $sale_price > (float) $regular_price) {
            wp_send_json_error(['message' => __('Sale price cannot be greater than the regular price.', 'calio-addon')], 422);
        }

        $product->set_regular_price($regular_price);
        $product->set_sale_price($sale_price);
        $product->set_price($sale_price !== '' ? $sale_price : $regular_price);
        $product->save();

        if ($product->is_type('variation') && $product->get_parent_id() > 0) {
            \WC_Product_Variable::sync($product->get_parent_id());
        }

        wp_send_json_success([
            'message' => __('Price saved.', 'calio-addon'),
            'product' => $this->product_payload(wc_get_product($product_id)),
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function product_payload(\WC_Product $product): array
    {
        $description = $product->get_description();
        if ($description === '' && $product->is_type('variation') && $product->get_parent_id() > 0) {
            $parent = wc_get_product($product->get_parent_id());
            if ($parent instanceof \WC_Product) {
                $description = $parent->get_description();
            }
        }

        return [
            'id' => $product->get_id(),
            'name' => wp_strip_all_tags($product->get_formatted_name()),
            'sku' => sanitize_text_field((string) $product->get_sku()),
            'type' => sanitize_key($product->get_type()),
            'regularPrice' => (string) $product->get_regular_price('edit'),
            'salePrice' => (string) $product->get_sale_price('edit'),
            'regularDisplay' => $this->format_price($product->get_regular_price('edit')),
            'saleDisplay' => $this->format_price($product->get_sale_price('edit')),
            'stock' => $product->get_stock_quantity(),
            'stockStatus' => sanitize_key($product->get_stock_status()),
            'status' => sanitize_key($product->get_status()),
            'editable' => $this->is_price_editable($product),
            'description' => wp_kses_post(wpautop($description)),
            'editUrl' => get_edit_post_link($product->get_id(), 'raw') ?: '',
        ];
    }

    /**
     * @param mixed $price
     */
    private function format_price($price): string
    {
        if ($price === '' || $price === null) {
            return '';
        }

        return wp_strip_all_tags(wc_price((float) $price));
    }

    private function is_price_editable(\WC_Product $product): bool
    {
        return !in_array($product->get_type(), ['variable', 'grouped'], true);
    }

    private function verify_ajax_request_context(): void
    {
        if (!$this->can_manage()) {
            wp_send_json_error(['message' => __('You are not allowed to manage WooCommerce products.', 'calio-addon')], 403);
        }

        if (!function_exists('wc_get_products')) {
            wp_send_json_error(['message' => __('WooCommerce is not available.', 'calio-addon')], 409);
        }
    }

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