<?php

namespace WooNooW\Frontend;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Shop Controller - Customer-facing product catalog API
 * Handles product listing, search, and categories for customer-spa
 */
class ShopController
{

    /**
     * Register REST API routes
     */
    public static function register_routes()
    {
        $namespace = 'woonoow/v1';

        // Get products (public)
        register_rest_route($namespace, '/shop/products', [
            'methods'             => 'GET',
            'callback'            => [__CLASS__, 'get_products'],
            'permission_callback' => '__return_true',
            'args'                => [
                'page'     => [
                    'default'           => 1,
                    'sanitize_callback' => 'absint',
                ],
                'per_page' => [
                    'default'           => 12,
                    'sanitize_callback' => 'absint',
                ],
                'category' => [
                    'default'           => '',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'search'   => [
                    'default'           => '',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'orderby'  => [
                    'default'           => 'date',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'order'    => [
                    'default'           => 'DESC',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'slug'     => [
                    'default'           => '',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
            ],
        ]);

        // Get single product (public)
        register_rest_route($namespace, '/shop/products/(?P<id>\d+)', [
            'methods'             => 'GET',
            'callback'            => [__CLASS__, 'get_product'],
            'permission_callback' => '__return_true',
            'args'                => [
                'id' => [
                    'validate_callback' => function ($param) {
                        return is_numeric($param);
                    },
                ],
            ],
        ]);

        // Get categories (public)
        register_rest_route($namespace, '/shop/categories', [
            'methods'             => 'GET',
            'callback'            => [__CLASS__, 'get_categories'],
            'permission_callback' => '__return_true',
        ]);

        // Search products (public)
        register_rest_route($namespace, '/shop/search', [
            'methods'             => 'GET',
            'callback'            => [__CLASS__, 'search_products'],
            'permission_callback' => '__return_true',
            'args'                => [
                's' => [
                    'required'          => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
            ],
        ]);
    }

    /**
     * Get products list
     */
    public static function get_products(WP_REST_Request $request)
    {
        $page     = $request->get_param('page');
        $per_page = $request->get_param('per_page');
        $category = $request->get_param('category');
        $search   = $request->get_param('search');
        $orderby  = $request->get_param('orderby');
        $order    = $request->get_param('order');
        $slug     = $request->get_param('slug');
        $include  = $request->get_param('include');
        $exclude  = $request->get_param('exclude');

        $args = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => $per_page,
            'paged'          => $page,
            'orderby'        => $orderby,
            'order'          => $order,
        ];

        // Add slug filter (for single product lookup)
        if (!empty($slug)) {
            $args['name'] = $slug;
        }

        // Add include filter (specific product IDs)
        if (!empty($include)) {
            $ids = array_map('intval', explode(',', $include));
            $args['post__in'] = $ids;
            $args['orderby'] = 'post__in'; // Maintain order of IDs
        }

        // Add exclude filter (exclude specific product IDs)
        if (!empty($exclude)) {
            $ids = array_map('intval', explode(',', $exclude));
            $args['post__not_in'] = $ids;
        }

        // Add category filter
        if (!empty($category)) {
            // Check if category is numeric (ID) or string (slug)
            $field = is_numeric($category) ? 'term_id' : 'slug';
            $args['tax_query'] = [
                [
                    'taxonomy' => 'product_cat',
                    'field'    => $field,
                    'terms'    => $category,
                ],
            ];
        }

        // Add search
        if (!empty($search)) {
            $args['s'] = $search;
        }

        $query = new \WP_Query($args);

        // Check if this is a single product request (by slug)
        $is_single = !empty($slug);

        $products = [];
        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                $product = wc_get_product(get_the_ID());

                if ($product) {
                    // Return detailed data for single product requests
                    $products[] = self::format_product($product, $is_single);
                }
            }
            wp_reset_postdata();
        }

        return new WP_REST_Response([
            'products'    => $products,
            'total'       => $query->found_posts,
            'total_pages' => $query->max_num_pages,
            'page'        => $page,
            'per_page'    => $per_page,
        ], 200);
    }

    /**
     * Get single product
     */
    public static function get_product(WP_REST_Request $request)
    {
        $product_id = $request->get_param('id');
        $product    = wc_get_product($product_id);

        if (!$product) {
            return new WP_Error('product_not_found', 'Product not found', ['status' => 404]);
        }

        return new WP_REST_Response(self::format_product($product, true), 200);
    }

    /**
     * Get categories
     */
    public static function get_categories(WP_REST_Request $request)
    {
        $terms = get_terms([
            'taxonomy'   => 'product_cat',
            'hide_empty' => true,
        ]);

        if (is_wp_error($terms)) {
            return new WP_Error('categories_error', 'Failed to get categories', ['status' => 500]);
        }

        $categories = [];
        foreach ($terms as $term) {
            $thumbnail_id = get_term_meta($term->term_id, 'thumbnail_id', true);
            $categories[] = [
                'id'    => $term->term_id,
                'name'  => $term->name,
                'slug'  => $term->slug,
                'count' => $term->count,
                'image' => $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : '',
            ];
        }

        return new WP_REST_Response($categories, 200);
    }

    /**
     * Search products
     */
    public static function search_products(WP_REST_Request $request)
    {
        $search = $request->get_param('s');

        $args = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => 10,
            's'              => $search,
        ];

        $query = new \WP_Query($args);

        $products = [];
        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                $product = wc_get_product(get_the_ID());

                if ($product) {
                    $products[] = self::format_product($product);
                }
            }
            wp_reset_postdata();
        }

        return new WP_REST_Response($products, 200);
    }

    /**
     * Format product data for API response
     */
    private static function format_product($product, $detailed = false)
    {
        $data = [
            'id'          => $product->get_id(),
            'name'        => $product->get_name(),
            'slug'        => $product->get_slug(),
            'price'       => $product->get_price(),
            'regular_price' => $product->get_regular_price(),
            'sale_price'  => $product->get_sale_price(),
            'price_html'  => $product->get_price_html(),
            'on_sale'     => $product->is_on_sale(),
            'in_stock'    => $product->is_in_stock(),
            'stock_status' => $product->get_stock_status(),
            'stock_quantity' => $product->get_stock_quantity(),
            'type'        => $product->get_type(),
            'image'       => wp_get_attachment_url($product->get_image_id()),
            'permalink'   => get_permalink($product->get_id()),
            'categories'  => wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'all']),
            'virtual'     => $product->is_virtual(),
            'downloadable' => $product->is_downloadable(),
        ];

        // Add detailed info if requested
        if ($detailed) {
            $data['description']       = wpautop($product->get_description());
            $data['short_description'] = wpautop($product->get_short_description());
            $data['sku'] = $product->get_sku();
            $data['tags'] = wp_get_post_terms($product->get_id(), 'product_tag', ['fields' => 'names']);

            // Gallery images
            $gallery_ids = $product->get_gallery_image_ids();
            $data['gallery'] = array_map('wp_get_attachment_url', $gallery_ids);

            // Images array (featured + gallery) for frontend
            $images = [];
            if ($data['image']) {
                $images[] = $data['image'];
            }
            $images = array_merge($images, $data['gallery']);
            $data['images'] = $images;

            // Attributes and Variations for variable products
            if ($product->is_type('variable')) {
                $data['attributes'] = self::get_product_attributes($product);
                $data['variations'] = self::get_product_variations($product);
            }

            // Related products
            $related_ids = wc_get_related_products($product->get_id(), 4);
            $data['related_products'] = array_map(function ($id) {
                $related = wc_get_product($id);
                return $related ? self::format_product($related) : null;
            }, $related_ids);
            $data['related_products'] = array_filter($data['related_products']);
        }

        return $data;
    }

    /**
     * Get product attributes
     */
    private static function get_product_attributes($product)
    {
        $attributes = [];

        foreach ($product->get_attributes() as $attribute) {
            $attribute_data = [
                'name' => wc_attribute_label($attribute->get_name()),
                'slug' => sanitize_title($attribute->get_name()),
                'options' => [],
                'visible' => $attribute->get_visible(),
                'variation' => $attribute->get_variation(),
            ];

            // Get attribute options
            if ($attribute->is_taxonomy()) {
                $terms = wc_get_product_terms($product->get_id(), $attribute->get_name(), ['fields' => 'names']);
                $attribute_data['options'] = $terms;
            } else {
                $attribute_data['options'] = $attribute->get_options();
            }

            $attributes[] = $attribute_data;
        }

        return $attributes;
    }

    /**
     * Get product variations
     */
    private static function get_product_variations($product)
    {
        $variations = [];

        foreach ($product->get_available_variations() as $variation) {
            $variation_obj = wc_get_product($variation['variation_id']);

            if ($variation_obj) {
                // Use attributes directly from WooCommerce's get_available_variations()
                // This correctly handles custom attributes, taxonomy attributes, and "Any" selections
                $attributes = $variation['attributes'];
                $variation_id = $variation['variation_id'];

                $variations[] = [
                    'id'         => $variation_id,
                    'attributes' => $attributes,
                    'price'      => $variation_obj->get_price(),
                    'regular_price' => $variation_obj->get_regular_price(),
                    'sale_price' => $variation_obj->get_sale_price(),
                    'in_stock'   => $variation_obj->is_in_stock(),
                    'stock_quantity' => $variation_obj->get_stock_quantity(),
                    'image'      => wp_get_attachment_url($variation_obj->get_image_id()),
                ];
            }
        }

        return $variations;
    }
}
