<?php

defined('ABSPATH') || exit;

class BundlePress_API
{
    private $namespace = 'bundlepress/v1';

    public function __construct()
    {
        add_action('rest_api_init', [$this, 'register_routes']);
    }

    public function register_routes()
    {
        // Core dashboard stats
        register_rest_route($this->namespace, '/api/dashboard/stats', [
            'methods' => 'GET',
            'callback' => [$this, 'get_dashboard_stats'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        // Product Picker Routes (for compatibility)
        register_rest_route($this->namespace, '/api/all-products', [
            'methods' => 'GET',
            'callback' => [$this, 'get_all_products'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        register_rest_route($this->namespace, '/api/product-categories', [
            'methods' => 'GET',
            'callback' => [$this, 'get_product_categories'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        register_rest_route($this->namespace, '/api/product-tags', [
            'methods' => 'GET',
            'callback' => [$this, 'get_product_tags'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        register_rest_route($this->namespace, '/api/products/(?P<id>\d+)/variations', [
            'methods' => 'GET',
            'callback' => [$this, 'get_product_variations'],
            'permission_callback' => [$this, 'check_permission']
        ]);

        register_rest_route($this->namespace, '/api/active-store-notice', [
            'methods' => 'GET',
            'callback' => [$this, 'proxy_store_notice'],
            'permission_callback' => '__return_true'
        ]);

        register_rest_route($this->namespace, '/api/dismiss-store-notice', [
            'methods' => 'POST',
            'callback' => [$this, 'dismiss_store_notice'],
            'permission_callback' => [$this, 'check_permission']
        ]);
    }

    public function check_permission()
    {
        return current_user_can('manage_options');
    }

    public function get_dashboard_stats($request)
    {
        global $wpdb;
        $total_bundles = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}bundlepress_bundles");

        return rest_ensure_response([
            'success' => true,
            'data' => [
                'total_bundles' => (int) $total_bundles,
            ]
        ]);
    }

    public function get_all_products($request)
    {
        $params = $request->get_params();
        $page = $params['page'] ?? 1;
        $per_page = $params['per_page'] ?? 10;
        $search = $params['search'] ?? '';
        $category = $params['category'] ?? '';
        $tag = $params['tag'] ?? '';

        $args = [
            'status' => 'publish',
            'limit' => $per_page,
            'page' => $page,
            'paginate' => true,
            'type' => ['simple', 'variable'],
            'orderby' => 'name',
            'order' => 'ASC',
        ];

        if ($search)
            $args['s'] = $search;
        if ($category)
            $args['category'] = explode(',', $category);
        if ($tag)
            $args['tag'] = explode(',', $tag);

        global $wpdb;
        $fixed_bundle_ids = $wpdb->get_col("SELECT product_id FROM {$wpdb->prefix}bundlepress_bundles WHERE type = 'fixed' AND product_id > 0");
        if (!empty($fixed_bundle_ids)) {
            $args['exclude'] = $fixed_bundle_ids;
        }

        $products_data = wc_get_products($args);
        $products = [];

        foreach ($products_data->products as $product) {
            $products[] = [
                'id' => $product->get_id(),
                'name' => $product->get_name(),
                'type' => $product->get_type(),
                'price' => $product->get_price(),
                'price_html' => $product->get_price_html(),
                'sku' => $product->get_sku(),
                'stock_quantity' => $product->get_stock_quantity(),
                'stock_status' => $product->get_stock_status(),
                'images' => [
                    ['src' => wp_get_attachment_url($product->get_image_id()), 'thumbnail' => wp_get_attachment_thumb_url($product->get_image_id())]
                ],
            ];
        }

        return rest_ensure_response([
            'success' => true,
            'data' => [
                'allProducts' => $products,
                'total' => $products_data->total,
                'pages' => $products_data->max_num_pages,
            ]
        ]);
    }

    public function get_product_categories($request)
    {
        $categories = get_terms(['taxonomy' => 'product_cat', 'hide_empty' => false]);
        $formatted = [];
        foreach ($categories as $cat) {
            $formatted[] = ['id' => $cat->term_id, 'name' => $cat->name];
        }
        return rest_ensure_response(['categories' => $formatted]);
    }

    public function get_product_tags($request)
    {
        $tags = get_terms(['taxonomy' => 'product_tag', 'hide_empty' => false]);
        $formatted = [];
        foreach ($tags as $tag) {
            $formatted[] = ['id' => $tag->term_id, 'name' => $tag->name];
        }
        return rest_ensure_response(['tags' => $formatted]);
    }

    public function get_product_variations($request)
    {
        $id = $request['id'];
        $product = wc_get_product($id);
        if (!$product || $product->get_type() !== 'variable') {
            return rest_ensure_response(['variations' => []]);
        }

        $variations_data = $this->sort_variations_by_attribute_order($product->get_available_variations(), $product);
        $variations = [];

        foreach ($variations_data as $var_data) {
            $variation = wc_get_product($var_data['variation_id']);
            $variations[] = [
                'id' => $variation->get_id(),
                'name' => $variation->get_name(),
                'price' => $variation->get_price(),
                'price_html' => $variation->get_price_html(),
                'sku' => $variation->get_sku(),
                'stock_quantity' => $variation->get_stock_quantity(),
                'stock_status' => $variation->get_stock_status(),
                'attributes' => $var_data['attributes'],
            ];
        }

        return rest_ensure_response(['variations' => $variations]);
    }

    private function sort_variations_by_attribute_order(array $variations_data, $product): array
    {
        $attributes = $product->get_attributes();

        usort($attributes, function ($a, $b) {
            return $a->get_position() <=> $b->get_position();
        });

        $attr_value_order = [];
        foreach ($attributes as $attr) {
            $attr_name = $attr->get_name();
            $attr_key = strpos($attr_name, 'pa_') === 0
                ? 'attribute_' . $attr_name
                : 'attribute_' . strtolower(sanitize_title($attr_name));

            $options = $attr->get_options();
            $ordered_slugs = [];

            if ($attr->is_taxonomy()) {
                foreach ($options as $term_id) {
                    $term = get_term($term_id);
                    if ($term && !is_wp_error($term)) {
                        $ordered_slugs[] = $term->slug;
                    }
                }
            } else {
                $ordered_slugs = array_map(function ($val) {
                    return strtolower(sanitize_title($val));
                }, $options);
            }

            $attr_value_order[$attr_key] = array_flip($ordered_slugs);
        }

        usort($variations_data, function ($a, $b) use ($attr_value_order) {
            foreach ($attr_value_order as $attr_key => $value_order) {
                $val_a = $a['attributes'][$attr_key] ?? '';
                $val_b = $b['attributes'][$attr_key] ?? '';

                $pos_a = ($val_a !== '') ? ($value_order[$val_a] ?? PHP_INT_MAX) : PHP_INT_MAX;
                $pos_b = ($val_b !== '') ? ($value_order[$val_b] ?? PHP_INT_MAX) : PHP_INT_MAX;

                if ($pos_a !== $pos_b) {
                    return $pos_a <=> $pos_b;
                }
            }
            return 0;
        });

        return $variations_data;
    }

    public function proxy_store_notice($request)
    {
        if (class_exists('BundlePress_Store_Notice')) {
            $shop_url = parse_url(home_url(), PHP_URL_HOST);
            $api_url = 'https://dominopress.com/api/active-store-notice';
            
            $api_endpoint = add_query_arg(['shop_url' => $shop_url], $api_url);
            $response = wp_remote_get($api_endpoint, [
                'timeout' => 15,
                'headers' => [
                    'Authorization' => 'Bearer z1yN6YtKp3dQw8VhR2cU9mlb7XjA4DFMG0He9qPiDoSrTuWvYlZkBnCfDgEhJiY5',
                ],
            ]);

            if (is_wp_error($response)) {
                return rest_ensure_response(['success' => false, 'message' => $response->get_error_message()]);
            }

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

            // Normalize structure: if the API returns a naked notice object without 'data' wrapper
            if (isset($data['id']) && !isset($data['success'])) {
                $data = [
                    'success' => true,
                    'data' => $data
                ];
            }

            // Check if this notice has been dismissed
            if ($data && !empty($data['data']['id'])) {
                $notice_id = (int)$data['data']['id'];
                $dismissed_notices = get_option('bundlepress_dismissed_notices', []);
                if (in_array($notice_id, $dismissed_notices)) {
                    $data['data']['is_enabled'] = false;
                }
            }

            return rest_ensure_response($data);
        }

        return rest_ensure_response(['success' => false, 'message' => 'Notice handler not found']);
    }

    public function dismiss_store_notice($request)
    {
        $id = $request->get_param('id');
        if (!$id) {
            return rest_ensure_response(['success' => false, 'message' => 'Notice ID is required']);
        }

        $id = (int) $id;
        $dismissed_notices = get_option('bundlepress_dismissed_notices', []);
        
        if (!in_array($id, $dismissed_notices)) {
            $dismissed_notices[] = $id;
            update_option('bundlepress_dismissed_notices', $dismissed_notices);
        }

        return rest_ensure_response(['success' => true]);
    }
}
