<?php
/**
 * GGM Commerce Taxonomy Tools
 *
 * MCP Tools for category and tag management
 * Tools are executable actions that AI can invoke
 *
 * @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_Taxonomy_Tools {

    /**
     * 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_tools();
    }

    /**
     * Register all taxonomy tools
     */
    private function register_tools() {
        // List categories
        $this->server->register_tool(
            'list_categories',
            'List all product categories with hierarchy',
            [
                'type' => 'object',
                'properties' => [
                    'parent_id' => [
                        'type' => 'integer',
                        'description' => 'Filter by parent category ID (0 for top-level only)',
                        'minimum' => 0
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Filter by status',
                        'enum' => ['active', 'inactive', 'all'],
                        'default' => 'active'
                    ],
                    'include_counts' => [
                        'type' => 'boolean',
                        'description' => 'Include product counts for each category',
                        'default' => false
                    ]
                ]
            ],
            [$this, 'list_categories']
        );

        // Get category
        $this->server->register_tool(
            'get_category',
            'Get a single category by ID or slug',
            [
                'type' => 'object',
                'properties' => [
                    'category_id' => [
                        'type' => 'integer',
                        'description' => 'Category ID',
                        'minimum' => 1
                    ],
                    'slug' => [
                        'type' => 'string',
                        'description' => 'Category slug (alternative to ID)'
                    ]
                ]
            ],
            [$this, 'get_category']
        );

        // Create category
        $this->server->register_tool(
            'create_category',
            'Create a new product category',
            [
                'type' => 'object',
                'properties' => [
                    'name' => [
                        'type' => 'string',
                        'description' => 'Category name (required)'
                    ],
                    'slug' => [
                        'type' => 'string',
                        'description' => 'URL slug (auto-generated from name if not provided)'
                    ],
                    'description' => [
                        'type' => 'string',
                        'description' => 'Category description'
                    ],
                    'parent_id' => [
                        'type' => 'integer',
                        'description' => 'Parent category ID (0 for top-level)',
                        'minimum' => 0,
                        'default' => 0
                    ],
                    'display_order' => [
                        'type' => 'integer',
                        'description' => 'Display order',
                        'default' => 0
                    ]
                ],
                'required' => ['name']
            ],
            [$this, 'create_category']
        );

        // Update category
        $this->server->register_tool(
            'update_category',
            'Update an existing category',
            [
                'type' => 'object',
                'properties' => [
                    'category_id' => [
                        'type' => 'integer',
                        'description' => 'Category ID to update (required)',
                        'minimum' => 1
                    ],
                    'name' => [
                        'type' => 'string',
                        'description' => 'New category name'
                    ],
                    'slug' => [
                        'type' => 'string',
                        'description' => 'New URL slug'
                    ],
                    'description' => [
                        'type' => 'string',
                        'description' => 'Category description'
                    ],
                    'parent_id' => [
                        'type' => 'integer',
                        'description' => 'Parent category ID',
                        'minimum' => 0
                    ],
                    'display_order' => [
                        'type' => 'integer',
                        'description' => 'Display order'
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Category status',
                        'enum' => ['active', 'inactive']
                    ]
                ],
                'required' => ['category_id']
            ],
            [$this, 'update_category']
        );

        // Delete category
        $this->server->register_tool(
            'delete_category',
            'Delete a category (products moved to default category)',
            [
                'type' => 'object',
                'properties' => [
                    'category_id' => [
                        'type' => 'integer',
                        'description' => 'Category ID to delete (required)',
                        'minimum' => 1
                    ],
                    'target_category_id' => [
                        'type' => 'integer',
                        'description' => 'Move orphaned products to this category (uses default if not specified)',
                        'minimum' => 1
                    ]
                ],
                'required' => ['category_id']
            ],
            [$this, 'delete_category']
        );

        // List tags
        $this->server->register_tool(
            'list_tags',
            'List all product tags',
            [
                'type' => 'object',
                'properties' => [
                    'status' => [
                        'type' => 'string',
                        'description' => 'Filter by status',
                        'enum' => ['active', 'inactive', 'all'],
                        'default' => 'active'
                    ],
                    'include_counts' => [
                        'type' => 'boolean',
                        'description' => 'Include product counts for each tag',
                        'default' => false
                    ]
                ]
            ],
            [$this, 'list_tags']
        );

        // Create tag
        $this->server->register_tool(
            'create_tag',
            'Create a new product tag',
            [
                'type' => 'object',
                'properties' => [
                    'name' => [
                        'type' => 'string',
                        'description' => 'Tag name (required)'
                    ],
                    'slug' => [
                        'type' => 'string',
                        'description' => 'URL slug (auto-generated from name if not provided)'
                    ],
                    'description' => [
                        'type' => 'string',
                        'description' => 'Tag description'
                    ]
                ],
                'required' => ['name']
            ],
            [$this, 'create_tag']
        );

        // Update tag
        $this->server->register_tool(
            'update_tag',
            'Update an existing tag',
            [
                'type' => 'object',
                'properties' => [
                    'tag_id' => [
                        'type' => 'integer',
                        'description' => 'Tag ID to update (required)',
                        'minimum' => 1
                    ],
                    'name' => [
                        'type' => 'string',
                        'description' => 'New tag name'
                    ],
                    'slug' => [
                        'type' => 'string',
                        'description' => 'New URL slug'
                    ],
                    'description' => [
                        'type' => 'string',
                        'description' => 'Tag description'
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Tag status',
                        'enum' => ['active', 'inactive']
                    ]
                ],
                'required' => ['tag_id']
            ],
            [$this, 'update_tag']
        );

        // Delete tag
        $this->server->register_tool(
            'delete_tag',
            'Delete a tag (removes from all products)',
            [
                'type' => 'object',
                'properties' => [
                    'tag_id' => [
                        'type' => 'integer',
                        'description' => 'Tag ID to delete (required)',
                        'minimum' => 1
                    ]
                ],
                'required' => ['tag_id']
            ],
            [$this, 'delete_tag']
        );

        // Assign categories to product
        $this->server->register_tool(
            'assign_product_categories',
            'Assign categories to a product',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Product ID (required)',
                        'minimum' => 1
                    ],
                    'category_ids' => [
                        'type' => 'array',
                        'description' => 'Array of category IDs to assign',
                        'items' => ['type' => 'integer']
                    ],
                    'append' => [
                        'type' => 'boolean',
                        'description' => 'Append to existing categories (false replaces all)',
                        'default' => false
                    ]
                ],
                'required' => ['product_id', 'category_ids']
            ],
            [$this, 'assign_product_categories']
        );

        // Assign tags to product
        $this->server->register_tool(
            'assign_product_tags',
            'Assign tags to a product',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Product ID (required)',
                        'minimum' => 1
                    ],
                    'tag_ids' => [
                        'type' => 'array',
                        'description' => 'Array of tag IDs to assign',
                        'items' => ['type' => 'integer']
                    ],
                    'append' => [
                        'type' => 'boolean',
                        'description' => 'Append to existing tags (false replaces all)',
                        'default' => false
                    ]
                ],
                'required' => ['product_id', 'tag_ids']
            ],
            [$this, 'assign_product_tags']
        );
    }

    /**
     * List categories
     */
    public function list_categories($args) {
        global $wpdb;

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $query_args = [
            'orderby' => 'display_order',
            'order' => 'ASC'
        ];

        if (isset($args['status']) && $args['status'] !== 'all') {
            $query_args['status'] = $args['status'];
        } else {
            $query_args['status'] = null;
        }

        if (isset($args['parent_id'])) {
            $query_args['parent_id'] = (int) $args['parent_id'];
        }

        $categories = $taxonomy->get_categories($query_args);

        $result = array_map(function($cat) use ($wpdb, $args) {
            $data = [
                'id' => (int) $cat->id,
                'name' => $cat->name,
                'slug' => $cat->slug,
                'description' => $cat->description,
                'parent_id' => (int) $cat->parent_id,
                'display_order' => (int) $cat->display_order,
                'status' => $cat->status
            ];

            if (!empty($args['include_counts'])) {
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$wpdb->prefix}ggmc_product_categories WHERE category_id = %d",
                    $cat->id
                ));
                $data['product_count'] = (int) $count;
            }

            return $data;
        }, $categories);

        return [
            'success' => true,
            'categories' => $result,
            'count' => count($result)
        ];
    }

    /**
     * Get single category
     */
    public function get_category($args) {
        if (empty($args['category_id']) && empty($args['slug'])) {
            return ['success' => false, 'error' => 'Category ID or slug is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();

        if (!empty($args['slug'])) {
            $category = $taxonomy->get_category($args['slug'], true);
        } else {
            $category = $taxonomy->get_category((int) $args['category_id']);
        }

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

        return [
            'success' => true,
            'category' => [
                'id' => (int) $category->id,
                'name' => $category->name,
                'slug' => $category->slug,
                'description' => $category->description,
                'parent_id' => (int) $category->parent_id,
                'display_order' => (int) $category->display_order,
                'image_id' => (int) $category->image_id,
                'status' => $category->status
            ]
        ];
    }

    /**
     * Create category
     */
    public function create_category($args) {
        if (empty($args['name'])) {
            return ['success' => false, 'error' => 'Category name is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $result = $taxonomy->create_category([
            'name' => sanitize_text_field($args['name']),
            'slug' => sanitize_title($args['slug'] ?? ''),
            'description' => sanitize_textarea_field($args['description'] ?? ''),
            'parent_id' => intval($args['parent_id'] ?? 0),
            'display_order' => intval($args['display_order'] ?? 0),
            'status' => 'active'
        ]);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'category_id' => $result,
            'message' => 'Category created successfully'
        ];
    }

    /**
     * Update category
     */
    public function update_category($args) {
        if (empty($args['category_id'])) {
            return ['success' => false, 'error' => 'Category ID is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $data = [];

        if (isset($args['name'])) {
            $data['name'] = sanitize_text_field($args['name']);
        }
        if (isset($args['slug'])) {
            $data['slug'] = sanitize_title($args['slug']);
        }
        if (isset($args['description'])) {
            $data['description'] = sanitize_textarea_field($args['description']);
        }
        if (isset($args['parent_id'])) {
            $data['parent_id'] = intval($args['parent_id']);
        }
        if (isset($args['display_order'])) {
            $data['display_order'] = intval($args['display_order']);
        }
        if (isset($args['status'])) {
            $data['status'] = sanitize_key($args['status']);
        }

        $result = $taxonomy->update_category((int) $args['category_id'], $data);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'message' => 'Category updated successfully'
        ];
    }

    /**
     * Delete category
     */
    public function delete_category($args) {
        if (empty($args['category_id'])) {
            return ['success' => false, 'error' => 'Category ID is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $target_id = isset($args['target_category_id']) ? (int) $args['target_category_id'] : null;

        $result = $taxonomy->delete_category((int) $args['category_id'], $target_id);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'message' => 'Category deleted successfully'
        ];
    }

    /**
     * List tags
     */
    public function list_tags($args) {
        global $wpdb;

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $status = ($args['status'] ?? 'active') === 'all' ? null : ($args['status'] ?? 'active');

        $tags = $taxonomy->get_tags('name', 'ASC', $status);

        $result = array_map(function($tag) use ($wpdb, $args) {
            $data = [
                'id' => (int) $tag->id,
                'name' => $tag->name,
                'slug' => $tag->slug,
                'description' => $tag->description ?? '',
                'status' => $tag->status ?? 'active'
            ];

            if (!empty($args['include_counts'])) {
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$wpdb->prefix}ggmc_product_tags WHERE tag_id = %d",
                    $tag->id
                ));
                $data['product_count'] = (int) $count;
            }

            return $data;
        }, $tags);

        return [
            'success' => true,
            'tags' => $result,
            'count' => count($result)
        ];
    }

    /**
     * Create tag
     */
    public function create_tag($args) {
        if (empty($args['name'])) {
            return ['success' => false, 'error' => 'Tag name is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $result = $taxonomy->create_tag([
            'name' => sanitize_text_field($args['name']),
            'slug' => sanitize_title($args['slug'] ?? ''),
            'description' => sanitize_textarea_field($args['description'] ?? '')
        ]);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'tag_id' => $result,
            'message' => 'Tag created successfully'
        ];
    }

    /**
     * Update tag
     */
    public function update_tag($args) {
        if (empty($args['tag_id'])) {
            return ['success' => false, 'error' => 'Tag ID is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $data = [];

        if (isset($args['name'])) {
            $data['name'] = sanitize_text_field($args['name']);
        }
        if (isset($args['slug'])) {
            $data['slug'] = sanitize_title($args['slug']);
        }
        if (isset($args['description'])) {
            $data['description'] = sanitize_textarea_field($args['description']);
        }
        if (isset($args['status'])) {
            $data['status'] = sanitize_key($args['status']);
        }

        $result = $taxonomy->update_tag((int) $args['tag_id'], $data);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'message' => 'Tag updated successfully'
        ];
    }

    /**
     * Delete tag
     */
    public function delete_tag($args) {
        if (empty($args['tag_id'])) {
            return ['success' => false, 'error' => 'Tag ID is required'];
        }

        $taxonomy = GGM_Commerce_Taxonomy::get_instance();
        $result = $taxonomy->delete_tag((int) $args['tag_id']);

        if (is_wp_error($result)) {
            return ['success' => false, 'error' => $result->get_error_message()];
        }

        return [
            'success' => true,
            'message' => 'Tag deleted successfully'
        ];
    }

    /**
     * Assign categories to product
     */
    public function assign_product_categories($args) {
        global $wpdb;

        if (empty($args['product_id'])) {
            return ['success' => false, 'error' => 'Product ID is required'];
        }

        if (empty($args['category_ids']) || !is_array($args['category_ids'])) {
            return ['success' => false, 'error' => 'Category IDs array is required'];
        }

        $product_id = (int) $args['product_id'];
        $category_ids = array_map('intval', $args['category_ids']);
        $append = !empty($args['append']);

        // Check product exists
        $product = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}ggmc_products WHERE id = %d",
            $product_id
        ));

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

        // If not appending, remove existing categories
        if (!$append) {
            $wpdb->delete(
                "{$wpdb->prefix}ggmc_product_categories",
                ['product_id' => $product_id],
                ['%d']
            );
        }

        // Get existing category IDs if appending
        $existing = [];
        if ($append) {
            $existing = $wpdb->get_col($wpdb->prepare(
                "SELECT category_id FROM {$wpdb->prefix}ggmc_product_categories WHERE product_id = %d",
                $product_id
            ));
        }

        // Add new categories
        $added = 0;
        foreach ($category_ids as $cat_id) {
            if (in_array($cat_id, $existing, true)) {
                continue;
            }

            $inserted = $wpdb->insert(
                "{$wpdb->prefix}ggmc_product_categories",
                [
                    'product_id' => $product_id,
                    'category_id' => $cat_id
                ],
                ['%d', '%d']
            );

            if ($inserted) {
                $added++;
            }
        }

        return [
            'success' => true,
            'product_id' => $product_id,
            'categories_assigned' => $added,
            'message' => "Assigned {$added} category(ies) to product"
        ];
    }

    /**
     * Assign tags to product
     */
    public function assign_product_tags($args) {
        global $wpdb;

        if (empty($args['product_id'])) {
            return ['success' => false, 'error' => 'Product ID is required'];
        }

        if (empty($args['tag_ids']) || !is_array($args['tag_ids'])) {
            return ['success' => false, 'error' => 'Tag IDs array is required'];
        }

        $product_id = (int) $args['product_id'];
        $tag_ids = array_map('intval', $args['tag_ids']);
        $append = !empty($args['append']);

        // Check product exists
        $product = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}ggmc_products WHERE id = %d",
            $product_id
        ));

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

        // If not appending, remove existing tags
        if (!$append) {
            $wpdb->delete(
                "{$wpdb->prefix}ggmc_product_tags",
                ['product_id' => $product_id],
                ['%d']
            );
        }

        // Get existing tag IDs if appending
        $existing = [];
        if ($append) {
            $existing = $wpdb->get_col($wpdb->prepare(
                "SELECT tag_id FROM {$wpdb->prefix}ggmc_product_tags WHERE product_id = %d",
                $product_id
            ));
        }

        // Add new tags
        $added = 0;
        foreach ($tag_ids as $tag_id) {
            if (in_array($tag_id, $existing, true)) {
                continue;
            }

            $inserted = $wpdb->insert(
                "{$wpdb->prefix}ggmc_product_tags",
                [
                    'product_id' => $product_id,
                    'tag_id' => $tag_id
                ],
                ['%d', '%d']
            );

            if ($inserted) {
                $added++;
            }
        }

        return [
            'success' => true,
            'product_id' => $product_id,
            'tags_assigned' => $added,
            'message' => "Assigned {$added} tag(s) to product"
        ];
    }
}
