<?php
/**
 * GGM Commerce Review Tools
 *
 * MCP Tools for product review 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_Review_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 review tools
     */
    private function register_tools() {
        // List reviews
        $this->server->register_tool(
            'list_reviews',
            'List product reviews with filtering options',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Filter by product ID',
                        'minimum' => 1
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Filter by status',
                        'enum' => ['pending', 'approved', 'spam', 'trash', 'all'],
                        'default' => 'all'
                    ],
                    'rating' => [
                        'type' => 'integer',
                        'description' => 'Filter by rating (1-5)',
                        'minimum' => 1,
                        'maximum' => 5
                    ],
                    'verified_only' => [
                        'type' => 'boolean',
                        'description' => 'Only show verified purchase reviews',
                        'default' => false
                    ],
                    'sort_by' => [
                        'type' => 'string',
                        'description' => 'Sort field',
                        'enum' => ['created_at', 'rating', 'helpful_count'],
                        'default' => 'created_at'
                    ],
                    'sort_order' => [
                        'type' => 'string',
                        'description' => 'Sort direction',
                        'enum' => ['asc', 'desc'],
                        'default' => 'desc'
                    ],
                    'limit' => [
                        'type' => 'integer',
                        'description' => 'Maximum results',
                        'minimum' => 1,
                        'maximum' => 100,
                        'default' => 50
                    ]
                ]
            ],
            [$this, 'list_reviews']
        );

        // Get single review
        $this->server->register_tool(
            'get_review',
            'Get detailed information about a single review',
            [
                'type' => 'object',
                'properties' => [
                    'review_id' => [
                        'type' => 'integer',
                        'description' => 'Review ID (required)',
                        'minimum' => 1
                    ]
                ],
                'required' => ['review_id']
            ],
            [$this, 'get_review']
        );

        // Get product reviews
        $this->server->register_tool(
            'get_product_reviews',
            'Get all reviews for a specific product with rating statistics',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Product ID (required)',
                        'minimum' => 1
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Filter by status',
                        'enum' => ['pending', 'approved', 'all'],
                        'default' => 'approved'
                    ],
                    'limit' => [
                        'type' => 'integer',
                        'description' => 'Maximum reviews to return',
                        'minimum' => 1,
                        'maximum' => 100,
                        'default' => 20
                    ]
                ],
                'required' => ['product_id']
            ],
            [$this, 'get_product_reviews']
        );

        // Approve review
        $this->server->register_tool(
            'approve_review',
            'Approve a pending review (makes it visible)',
            [
                'type' => 'object',
                'properties' => [
                    'review_id' => [
                        'type' => 'integer',
                        'description' => 'Review ID (required)',
                        'minimum' => 1
                    ]
                ],
                'required' => ['review_id']
            ],
            [$this, 'approve_review']
        );

        // Reject review
        $this->server->register_tool(
            'reject_review',
            'Reject/spam a review (hides it from public view)',
            [
                'type' => 'object',
                'properties' => [
                    'review_id' => [
                        'type' => 'integer',
                        'description' => 'Review ID (required)',
                        'minimum' => 1
                    ],
                    'mark_as_spam' => [
                        'type' => 'boolean',
                        'description' => 'Mark as spam instead of trash',
                        'default' => false
                    ]
                ],
                'required' => ['review_id']
            ],
            [$this, 'reject_review']
        );

        // Delete review
        $this->server->register_tool(
            'delete_review',
            'Permanently delete a review',
            [
                'type' => 'object',
                'properties' => [
                    'review_id' => [
                        'type' => 'integer',
                        'description' => 'Review ID (required)',
                        'minimum' => 1
                    ]
                ],
                'required' => ['review_id']
            ],
            [$this, 'delete_review']
        );

        // Update review
        $this->server->register_tool(
            'update_review',
            'Update review content or status',
            [
                'type' => 'object',
                'properties' => [
                    'review_id' => [
                        'type' => 'integer',
                        'description' => 'Review ID (required)',
                        'minimum' => 1
                    ],
                    'author_name' => [
                        'type' => 'string',
                        'description' => 'Author display name'
                    ],
                    'rating' => [
                        'type' => 'integer',
                        'description' => 'Rating (1-5)',
                        'minimum' => 1,
                        'maximum' => 5
                    ],
                    'title' => [
                        'type' => 'string',
                        'description' => 'Review title'
                    ],
                    'content' => [
                        'type' => 'string',
                        'description' => 'Review content'
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'Review status',
                        'enum' => ['pending', 'approved', 'spam', 'trash']
                    ],
                    'verified_purchase' => [
                        'type' => 'boolean',
                        'description' => 'Mark as verified purchase'
                    ]
                ],
                'required' => ['review_id']
            ],
            [$this, 'update_review']
        );

        // Get pending reviews count
        $this->server->register_tool(
            'get_pending_reviews_count',
            'Get count of reviews awaiting moderation',
            [
                'type' => 'object',
                'properties' => []
            ],
            [$this, 'get_pending_reviews_count']
        );

        // Bulk approve reviews
        $this->server->register_tool(
            'bulk_approve_reviews',
            'Approve multiple reviews at once',
            [
                'type' => 'object',
                'properties' => [
                    'review_ids' => [
                        'type' => 'array',
                        'description' => 'Array of review IDs to approve',
                        'items' => ['type' => 'integer']
                    ]
                ],
                'required' => ['review_ids']
            ],
            [$this, 'bulk_approve_reviews']
        );
    }

    /**
     * List reviews with filters
     */
    public function list_reviews($args) {
        global $wpdb;

        $where = ['1=1'];
        $params = [];

        // Product filter
        if (!empty($args['product_id'])) {
            $where[] = "r.product_id = %d";
            $params[] = (int) $args['product_id'];
        }

        // Status filter
        if (!empty($args['status']) && $args['status'] !== 'all') {
            $where[] = "r.status = %s";
            $params[] = sanitize_key($args['status']);
        }

        // Rating filter
        if (!empty($args['rating'])) {
            $where[] = "r.rating = %d";
            $params[] = (int) $args['rating'];
        }

        // Verified only
        if (!empty($args['verified_only'])) {
            $where[] = "r.verified_purchase = 1";
        }

        $where_clause = implode(' AND ', $where);

        // Sorting
        $allowed_sort = ['created_at', 'rating', 'helpful_count'];
        $sort_by = in_array($args['sort_by'] ?? 'created_at', $allowed_sort, true)
            ? $args['sort_by']
            : 'created_at';
        $sort_order = strtoupper($args['sort_order'] ?? 'desc') === 'ASC' ? 'ASC' : 'DESC';

        $limit = min(100, max(1, intval($args['limit'] ?? 50)));

        $sql = "
            SELECT r.*, p.name as product_name
            FROM {$wpdb->prefix}ggmc_product_reviews r
            LEFT JOIN {$wpdb->prefix}ggmc_products p ON r.product_id = p.id
            WHERE {$where_clause}
            ORDER BY r.{$sort_by} {$sort_order}
            LIMIT {$limit}
        ";

        if (!empty($params)) {
            $reviews = $wpdb->get_results($wpdb->prepare($sql, ...$params));
        } else {
            $reviews = $wpdb->get_results($sql);
        }

        $result = array_map(function($r) {
            return [
                'id' => (int) $r->id,
                'product_id' => (int) $r->product_id,
                'product_name' => $r->product_name,
                'author_name' => $r->author_name,
                'author_email' => $r->author_email,
                'rating' => (int) $r->rating,
                'title' => $r->title,
                'content' => $r->content,
                'status' => $r->status,
                'verified_purchase' => (bool) $r->verified_purchase,
                'helpful_count' => (int) ($r->helpful_count ?? 0),
                'created_at' => $r->created_at
            ];
        }, $reviews);

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

    /**
     * Get single review
     */
    public function get_review($args) {
        if (empty($args['review_id'])) {
            return ['success' => false, 'error' => 'Review ID is required'];
        }

        $review = GGM_Commerce_Reviews::get_review((int) $args['review_id']);

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

        // Get product name
        global $wpdb;
        $product_name = $wpdb->get_var($wpdb->prepare(
            "SELECT name FROM {$wpdb->prefix}ggmc_products WHERE id = %d",
            $review->product_id
        ));

        return [
            'success' => true,
            'review' => [
                'id' => (int) $review->id,
                'product_id' => (int) $review->product_id,
                'product_name' => $product_name,
                'customer_id' => $review->customer_id ? (int) $review->customer_id : null,
                'author_name' => $review->author_name,
                'author_email' => $review->author_email,
                'rating' => (int) $review->rating,
                'title' => $review->title,
                'content' => $review->content,
                'status' => $review->status,
                'verified_purchase' => (bool) $review->verified_purchase,
                'helpful_count' => (int) ($review->helpful_count ?? 0),
                'ip_address' => $review->ip_address,
                'created_at' => $review->created_at
            ]
        ];
    }

    /**
     * Get product reviews with statistics
     */
    public function get_product_reviews($args) {
        if (empty($args['product_id'])) {
            return ['success' => false, 'error' => 'Product ID is required'];
        }

        $product_id = (int) $args['product_id'];
        $status = $args['status'] ?? 'approved';
        $limit = min(100, max(1, intval($args['limit'] ?? 20)));

        $reviews = GGM_Commerce_Reviews::get_product_reviews($product_id, [
            'status' => $status,
            'limit' => $limit
        ]);

        // Get rating distribution
        $distribution = GGM_Commerce_Reviews::get_rating_distribution($product_id);

        // Get counts
        $total_approved = GGM_Commerce_Reviews::get_product_review_count($product_id, 'approved');
        $total_pending = GGM_Commerce_Reviews::get_product_review_count($product_id, 'pending');

        // Calculate average
        $total_ratings = array_sum(array_map(function($rating, $count) {
            return $rating * $count;
        }, array_keys($distribution), $distribution));
        $total_reviews = array_sum($distribution);
        $average_rating = $total_reviews > 0 ? round($total_ratings / $total_reviews, 2) : 0;

        $result = array_map(function($r) {
            return [
                'id' => (int) $r->id,
                'author_name' => $r->author_name,
                'rating' => (int) $r->rating,
                'title' => $r->title,
                'content' => $r->content,
                'status' => $r->status,
                'verified_purchase' => (bool) $r->verified_purchase,
                'helpful_count' => (int) ($r->helpful_count ?? 0),
                'created_at' => $r->created_at
            ];
        }, $reviews);

        return [
            'success' => true,
            'product_id' => $product_id,
            'statistics' => [
                'average_rating' => $average_rating,
                'total_reviews' => $total_approved,
                'pending_reviews' => $total_pending,
                'rating_distribution' => $distribution
            ],
            'reviews' => $result,
            'count' => count($result)
        ];
    }

    /**
     * Approve review
     */
    public function approve_review($args) {
        if (empty($args['review_id'])) {
            return ['success' => false, 'error' => 'Review ID is required'];
        }

        $result = GGM_Commerce_Reviews::approve_review((int) $args['review_id']);

        if (!$result) {
            return ['success' => false, 'error' => 'Failed to approve review or review not found'];
        }

        return [
            'success' => true,
            'message' => 'Review approved successfully'
        ];
    }

    /**
     * Reject review
     */
    public function reject_review($args) {
        if (empty($args['review_id'])) {
            return ['success' => false, 'error' => 'Review ID is required'];
        }

        $status = !empty($args['mark_as_spam'])
            ? GGM_Commerce_Reviews::STATUS_SPAM
            : GGM_Commerce_Reviews::STATUS_TRASH;

        $result = GGM_Commerce_Reviews::update_status((int) $args['review_id'], $status);

        if (!$result) {
            return ['success' => false, 'error' => 'Failed to reject review or review not found'];
        }

        return [
            'success' => true,
            'new_status' => $status,
            'message' => 'Review rejected successfully'
        ];
    }

    /**
     * Delete review permanently
     */
    public function delete_review($args) {
        if (empty($args['review_id'])) {
            return ['success' => false, 'error' => 'Review ID is required'];
        }

        $result = GGM_Commerce_Reviews::delete_review((int) $args['review_id']);

        if (!$result) {
            return ['success' => false, 'error' => 'Failed to delete review or review not found'];
        }

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

    /**
     * Update review
     */
    public function update_review($args) {
        if (empty($args['review_id'])) {
            return ['success' => false, 'error' => 'Review ID is required'];
        }

        $data = [];

        if (isset($args['author_name'])) {
            $data['author_name'] = sanitize_text_field($args['author_name']);
        }
        if (isset($args['rating'])) {
            $data['rating'] = max(1, min(5, (int) $args['rating']));
        }
        if (isset($args['title'])) {
            $data['title'] = sanitize_text_field($args['title']);
        }
        if (isset($args['content'])) {
            $data['content'] = sanitize_textarea_field($args['content']);
        }
        if (isset($args['status'])) {
            $data['status'] = sanitize_key($args['status']);
        }
        if (isset($args['verified_purchase'])) {
            $data['verified_purchase'] = (bool) $args['verified_purchase'];
        }

        if (empty($data)) {
            return ['success' => false, 'error' => 'No data to update'];
        }

        $result = GGM_Commerce_Reviews::update_review((int) $args['review_id'], $data);

        if (!$result) {
            return ['success' => false, 'error' => 'Failed to update review'];
        }

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

    /**
     * Get pending reviews count
     */
    public function get_pending_reviews_count($args) {
        global $wpdb;

        $count = $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->prefix}ggmc_product_reviews WHERE status = 'pending'"
        );

        return [
            'success' => true,
            'pending_count' => (int) $count
        ];
    }

    /**
     * Bulk approve reviews
     */
    public function bulk_approve_reviews($args) {
        if (empty($args['review_ids']) || !is_array($args['review_ids'])) {
            return ['success' => false, 'error' => 'Review IDs array is required'];
        }

        $approved = 0;
        $failed = 0;

        foreach ($args['review_ids'] as $review_id) {
            $result = GGM_Commerce_Reviews::approve_review((int) $review_id);
            if ($result) {
                $approved++;
            } else {
                $failed++;
            }
        }

        return [
            'success' => true,
            'approved' => $approved,
            'failed' => $failed,
            'message' => "Approved {$approved} review(s)"
        ];
    }
}
