<?php
/**
 * GGM Commerce Product Resources
 *
 * MCP Resources for exposing product data to AI assistants
 * Resources are read-only data sources
 *
 * @package GGM_Commerce
 * @since 1.0.0
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

class GGM_Commerce_Product_Resources {

    /**
     * MCP Server instance
     * @var GGM_Commerce_MCP_Server
     */
    private $server;

    /**
     * Constructor
     *
     * @param GGM_Commerce_MCP_Server $server MCP server instance
     */
    public function __construct($server) {
        $this->server = $server;
        $this->register_resources();
    }

    /**
     * Register all product resources
     */
    private function register_resources() {
        // Product catalog
        $this->server->register_resource(
            'product://catalog',
            'Product Catalog',
            'Complete product catalog with pricing, inventory, and details',
            [$this, 'get_product_catalog']
        );

        // Individual product by ID
        $this->server->register_resource(
            'product://{id}',
            'Product Details',
            'Detailed information for a specific product by ID',
            [$this, 'get_product']
        );

        // Product categories
        $this->server->register_resource(
            'product://categories',
            'Product Categories',
            'All product categories with hierarchy',
            [$this, 'get_categories']
        );

        // Products by category
        $this->server->register_resource(
            'product://category/{category_id}',
            'Products by Category',
            'All products in a specific category',
            [$this, 'get_products_by_category']
        );

        // Product tags
        $this->server->register_resource(
            'product://tags',
            'Product Tags',
            'All product tags',
            [$this, 'get_tags']
        );

        // Products by tag
        $this->server->register_resource(
            'product://tag/{tag_id}',
            'Products by Tag',
            'All products with a specific tag',
            [$this, 'get_products_by_tag']
        );

        // Product inventory status
        $this->server->register_resource(
            'product://inventory',
            'Inventory Status',
            'Stock levels and availability for all products',
            [$this, 'get_inventory_status']
        );

        // Low stock products
        $this->server->register_resource(
            'product://inventory/low-stock',
            'Low Stock Products',
            'Products with stock below threshold (default: 10 units)',
            [$this, 'get_low_stock_products']
        );
    }

    /**
     * Get complete product catalog
     *
     * @param array $params URI parameters
     * @return array Product catalog data
     */
    public function get_product_catalog($params = []) {
        global $wpdb;

        $products = $wpdb->get_results(
            "SELECT p.*
            FROM {$wpdb->prefix}ggmc_products p
            WHERE (p.status = 'active' OR p.status IS NULL)
            ORDER BY p.name ASC"
        );

        // Process images and add categories for each product
        foreach ($products as &$product) {
            $product = $this->process_product_data($product);
            // Get categories from relationship table
            $categories = $wpdb->get_results($wpdb->prepare(
                "SELECT c.name, c.slug
                FROM {$wpdb->prefix}ggmc_categories c
                INNER JOIN {$wpdb->prefix}ggmc_product_categories pc ON c.id = pc.category_id
                WHERE pc.product_id = %d AND c.status = 'active'",
                $product->id
            ));
            $product->categories = $categories;
            // For backwards compatibility
            $product->category_name = !empty($categories) ? $categories[0]->name : null;
            $product->category_slug = !empty($categories) ? $categories[0]->slug : null;
        }

        return [
            'products' => $products,
            'total_count' => count($products),
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get single product details
     *
     * @param array $params URI parameters (expects 'id')
     * @return array Product data
     */
    public function get_product($params) {
        if (!isset($params['id'])) {
            return ['error' => 'Product ID is required'];
        }

        global $wpdb;

        $product = $wpdb->get_row($wpdb->prepare(
            "SELECT p.*
            FROM {$wpdb->prefix}ggmc_products p
            WHERE p.id = %d",
            intval($params['id'])
        ));

        if (!$product) {
            return ['error' => 'Product not found'];
        }

        $product = $this->process_product_data($product);

        // Get categories from relationship table
        $categories = $wpdb->get_results($wpdb->prepare(
            "SELECT c.*
            FROM {$wpdb->prefix}ggmc_categories c
            INNER JOIN {$wpdb->prefix}ggmc_product_categories pc ON c.id = pc.category_id
            WHERE pc.product_id = %d AND c.status = 'active'",
            intval($params['id'])
        ));
        $product->categories = $categories;
        // For backwards compatibility
        $product->category_name = !empty($categories) ? $categories[0]->name : null;
        $product->category_slug = !empty($categories) ? $categories[0]->slug : null;

        // Get product tags (active tags only)
        $tags = $wpdb->get_results($wpdb->prepare(
            "SELECT t.*
            FROM {$wpdb->prefix}ggmc_tags t
            INNER JOIN {$wpdb->prefix}ggmc_product_tags pt ON t.id = pt.tag_id
            WHERE pt.product_id = %d AND t.status = 'active'",
            intval($params['id'])
        ));

        $product->tags = $tags;

        // Get product barcodes
        $barcodes = $wpdb->get_results($wpdb->prepare(
            "SELECT barcode, barcode_type
            FROM {$wpdb->prefix}ggmc_product_barcodes
            WHERE product_id = %d",
            intval($params['id'])
        ));

        $product->barcodes = $barcodes;

        return [
            'product' => $product,
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get all categories
     *
     * @param array $params URI parameters
     * @return array Categories data
     */
    public function get_categories($params = []) {
        global $wpdb;

        $categories = $wpdb->get_results(
            "SELECT * FROM {$wpdb->prefix}ggmc_categories
            WHERE status = 'active'
            ORDER BY name ASC"
        );

        // Build category hierarchy with product counts, images, and archive URLs
        $categories_with_counts = [];
        foreach ($categories as $category) {
            $product_count = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT pc.product_id)
                FROM {$wpdb->prefix}ggmc_product_categories pc
                INNER JOIN {$wpdb->prefix}ggmc_products p ON pc.product_id = p.id
                WHERE pc.category_id = %d AND (p.status = 'active' OR p.status IS NULL)",
                $category->id
            ));

            $category->product_count = (int) $product_count;

            // Add image URL if image_id exists
            if (!empty($category->image_id)) {
                $category->image_url = wp_get_attachment_image_url($category->image_id, 'medium');
                $category->image_url_full = wp_get_attachment_image_url($category->image_id, 'full');
            } else {
                $category->image_url = null;
                $category->image_url_full = null;
            }

            // Add archive URL
            if (class_exists('GGM_Commerce_Helpers')) {
                $category->archive_url = GGM_Commerce_Helpers::get_category_archive_url($category->slug);
            } else {
                $category->archive_url = null;
            }

            $categories_with_counts[] = $category;
        }

        return [
            'categories' => $categories_with_counts,
            'total_count' => count($categories_with_counts),
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get products by category
     *
     * @param array $params URI parameters (expects 'category_id')
     * @return array Products data
     */
    public function get_products_by_category($params) {
        if (!isset($params['category_id'])) {
            return ['error' => 'Category ID is required'];
        }

        global $wpdb;

        // Get category info
        $category = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_categories WHERE id = %d",
            intval($params['category_id'])
        ));

        if (!$category) {
            return ['error' => 'Category not found'];
        }

        // Add image URL if image_id exists
        if (!empty($category->image_id)) {
            $category->image_url = wp_get_attachment_image_url($category->image_id, 'medium');
            $category->image_url_full = wp_get_attachment_image_url($category->image_id, 'full');
        } else {
            $category->image_url = null;
            $category->image_url_full = null;
        }

        // Add archive URL
        if (class_exists('GGM_Commerce_Helpers')) {
            $category->archive_url = GGM_Commerce_Helpers::get_category_archive_url($category->slug);
        } else {
            $category->archive_url = null;
        }

        // Get products in this category via relationship table
        $products = $wpdb->get_results($wpdb->prepare(
            "SELECT p.* FROM {$wpdb->prefix}ggmc_products p
            INNER JOIN {$wpdb->prefix}ggmc_product_categories pc ON p.id = pc.product_id
            WHERE pc.category_id = %d AND (p.status = 'active' OR p.status IS NULL)
            ORDER BY p.name ASC",
            intval($params['category_id'])
        ));

        foreach ($products as &$product) {
            $product = $this->process_product_data($product);
        }

        return [
            'category' => $category,
            'products' => $products,
            'product_count' => count($products),
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get all tags
     *
     * @param array $params URI parameters
     * @return array Tags data
     */
    public function get_tags($params = []) {
        global $wpdb;

        $tags = $wpdb->get_results(
            "SELECT * FROM {$wpdb->prefix}ggmc_tags
            WHERE status = 'active'
            ORDER BY name ASC"
        );

        // Add product counts and archive URLs
        foreach ($tags as $tag) {
            $product_count = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}ggmc_product_tags
                WHERE tag_id = %d",
                $tag->id
            ));

            $tag->product_count = (int) $product_count;

            // Add archive URL
            if (class_exists('GGM_Commerce_Helpers')) {
                $tag->archive_url = GGM_Commerce_Helpers::get_tag_archive_url($tag->slug);
            } else {
                $tag->archive_url = null;
            }
        }

        return [
            'tags' => $tags,
            'total_count' => count($tags),
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get products by tag
     *
     * @param array $params URI parameters (expects 'tag_id')
     * @return array Products data
     */
    public function get_products_by_tag($params) {
        if (!isset($params['tag_id'])) {
            return ['error' => 'Tag ID is required'];
        }

        global $wpdb;

        // Get tag info
        $tag = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_tags WHERE id = %d",
            intval($params['tag_id'])
        ));

        if (!$tag) {
            return ['error' => 'Tag not found'];
        }

        // Add archive URL
        if (class_exists('GGM_Commerce_Helpers')) {
            $tag->archive_url = GGM_Commerce_Helpers::get_tag_archive_url($tag->slug);
        } else {
            $tag->archive_url = null;
        }

        // Get products with this tag
        $products = $wpdb->get_results($wpdb->prepare(
            "SELECT p.*
            FROM {$wpdb->prefix}ggmc_products p
            INNER JOIN {$wpdb->prefix}ggmc_product_tags pt ON p.id = pt.product_id
            WHERE pt.tag_id = %d AND (p.status = 'active' OR p.status IS NULL)
            ORDER BY p.name ASC",
            intval($params['tag_id'])
        ));

        foreach ($products as &$product) {
            $product = $this->process_product_data($product);
        }

        return [
            'tag' => $tag,
            'products' => $products,
            'product_count' => count($products),
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get inventory status for all products
     *
     * @param array $params URI parameters
     * @return array Inventory data
     */
    public function get_inventory_status($params = []) {
        global $wpdb;

        $inventory = $wpdb->get_results(
            "SELECT
                id,
                name,
                sku,
                stock,
                stock_status,
                low_stock_threshold,
                restock_date
            FROM {$wpdb->prefix}ggmc_products
            WHERE (status = 'active' OR status IS NULL)
            ORDER BY stock ASC"
        );

        // Calculate statistics
        $total_products = count($inventory);
        $in_stock = 0;
        $low_stock = 0;
        $out_of_stock = 0;

        foreach ($inventory as $item) {
            $stock = (int) $item->stock;
            $threshold = isset($item->low_stock_threshold) ? (int) $item->low_stock_threshold : 10;

            if ($stock <= 0) {
                $out_of_stock++;
            } elseif ($stock <= $threshold) {
                $low_stock++;
            } else {
                $in_stock++;
            }
        }

        return [
            'inventory' => $inventory,
            'statistics' => [
                'total_products' => $total_products,
                'in_stock' => $in_stock,
                'low_stock' => $low_stock,
                'out_of_stock' => $out_of_stock
            ],
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Get low stock products
     *
     * @param array $params URI parameters
     * @return array Low stock products data
     */
    public function get_low_stock_products($params = []) {
        global $wpdb;

        $products = $wpdb->get_results(
            "SELECT
                id,
                name,
                sku,
                stock,
                stock_status,
                low_stock_threshold,
                restock_date,
                price
            FROM {$wpdb->prefix}ggmc_products
            WHERE (status = 'active' OR status IS NULL)
                AND stock > 0
                AND stock <= COALESCE(low_stock_threshold, 10)
            ORDER BY stock ASC"
        );

        return [
            'low_stock_products' => $products,
            'count' => count($products),
            'alert_message' => count($products) > 0
                ? 'Attention: ' . count($products) . ' product(s) are running low on stock'
                : 'All products have adequate stock levels',
            'timestamp' => current_time('mysql')
        ];
    }

    /**
     * Process product data (parse images, format fields)
     *
     * @param object $product Product object
     * @return object Processed product
     */
    private function process_product_data($product) {
        // Build images array from image_id and gallery_ids
        $product->images = [];

        // Add main image from image_id
        if (!empty($product->image_id)) {
            $image_url = wp_get_attachment_url($product->image_id);
            if ($image_url) {
                $product->images[] = $image_url;
                $product->image_url = $image_url; // For backwards compatibility
            }
        }

        // Add gallery images from gallery_ids
        if (!empty($product->gallery_ids)) {
            $gallery_ids = array_filter(array_map('intval', explode(',', $product->gallery_ids)));
            foreach ($gallery_ids as $gallery_id) {
                $gallery_url = wp_get_attachment_url($gallery_id);
                if ($gallery_url) {
                    $product->images[] = $gallery_url;
                }
            }
        }

        // Ensure numeric fields are properly typed
        $product->id = (int) $product->id;
        $product->price = (float) $product->price;
        $product->sale_price = isset($product->sale_price) ? (float) $product->sale_price : null;
        $product->stock = isset($product->stock) ? (int) $product->stock : 0;

        // Add stock availability flag
        $product->is_available = ($product->stock > 0 && $product->stock_status === 'instock');

        return $product;
    }
}
