<?php
/**
 * GGM Commerce Media Tools
 *
 * MCP Tools for media/image 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_Media_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 media management tools
     */
    private function register_tools() {
        // Upload image from URL
        $this->server->register_tool(
            'upload_image_from_url',
            'Download an image from a URL and upload it to the WordPress media library',
            [
                'type' => 'object',
                'properties' => [
                    'url' => [
                        'type' => 'string',
                        'description' => 'The URL of the image to download and upload'
                    ],
                    'filename' => [
                        'type' => 'string',
                        'description' => 'Optional filename for the uploaded image (without extension)'
                    ],
                    'title' => [
                        'type' => 'string',
                        'description' => 'Optional title for the media attachment'
                    ],
                    'alt_text' => [
                        'type' => 'string',
                        'description' => 'Optional alt text for the image'
                    ],
                    'caption' => [
                        'type' => 'string',
                        'description' => 'Optional caption for the image'
                    ]
                ],
                'required' => ['url']
            ],
            [$this, 'upload_image_from_url']
        );

        // Set product image
        $this->server->register_tool(
            'set_product_image',
            'Set the featured image for a product using an attachment ID or image URL',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Product ID',
                        'minimum' => 1
                    ],
                    'image_id' => [
                        'type' => 'integer',
                        'description' => 'WordPress attachment ID (use this OR image_url)',
                        'minimum' => 1
                    ],
                    'image_url' => [
                        'type' => 'string',
                        'description' => 'URL of image to download and set (use this OR image_id)'
                    ]
                ],
                'required' => ['product_id']
            ],
            [$this, 'set_product_image']
        );

        // Add to product gallery
        $this->server->register_tool(
            'add_product_gallery_image',
            'Add an image to a product gallery',
            [
                'type' => 'object',
                'properties' => [
                    'product_id' => [
                        'type' => 'integer',
                        'description' => 'Product ID',
                        'minimum' => 1
                    ],
                    'image_id' => [
                        'type' => 'integer',
                        'description' => 'WordPress attachment ID (use this OR image_url)',
                        'minimum' => 1
                    ],
                    'image_url' => [
                        'type' => 'string',
                        'description' => 'URL of image to download and add (use this OR image_id)'
                    ]
                ],
                'required' => ['product_id']
            ],
            [$this, 'add_product_gallery_image']
        );

        // Get media library images
        $this->server->register_tool(
            'list_media_images',
            'List images from the WordPress media library',
            [
                'type' => 'object',
                'properties' => [
                    'search' => [
                        'type' => 'string',
                        'description' => 'Search term to filter images'
                    ],
                    'limit' => [
                        'type' => 'integer',
                        'description' => 'Maximum number of images to return',
                        'minimum' => 1,
                        'maximum' => 100,
                        'default' => 20
                    ],
                    'offset' => [
                        'type' => 'integer',
                        'description' => 'Offset for pagination',
                        'minimum' => 0,
                        'default' => 0
                    ]
                ]
            ],
            [$this, 'list_media_images']
        );

        // Upload image from base64 data
        $this->server->register_tool(
            'upload_image_base64',
            'Upload an image from base64-encoded data to the WordPress media library',
            [
                'type' => 'object',
                'properties' => [
                    'data' => [
                        'type' => 'string',
                        'description' => 'Base64-encoded image data'
                    ],
                    'filename' => [
                        'type' => 'string',
                        'description' => 'Filename including extension (e.g. photo.jpg)'
                    ],
                    'mime' => [
                        'type' => 'string',
                        'description' => 'MIME type (e.g. image/jpeg)',
                        'default' => 'image/jpeg'
                    ],
                    'title' => [
                        'type' => 'string',
                        'description' => 'Optional title for the media attachment'
                    ],
                    'alt_text' => [
                        'type' => 'string',
                        'description' => 'Optional alt text for the image'
                    ]
                ],
                'required' => ['data', 'filename']
            ],
            [$this, 'upload_image_base64']
        );
    }

    /**
     * Upload image from URL
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function upload_image_from_url($args) {
        $url = esc_url_raw($args['url']);

        if (empty($url)) {
            return [
                'success' => false,
                'error' => 'Invalid URL provided'
            ];
        }

        // Include required WordPress files
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
        require_once(ABSPATH . 'wp-admin/includes/image.php');

        // Download file to temp location
        $temp_file = download_url($url, 30);

        if (is_wp_error($temp_file)) {
            return [
                'success' => false,
                'error' => 'Failed to download image: ' . $temp_file->get_error_message()
            ];
        }

        // Get file info
        $file_info = wp_check_filetype(basename(parse_url($url, PHP_URL_PATH)));

        // Check if it's an image
        $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

        // Try to determine MIME type
        $mime_type = $file_info['type'];
        if (empty($mime_type)) {
            $mime_type = mime_content_type($temp_file);
        }

        if (!in_array($mime_type, $allowed_types)) {
            @unlink($temp_file);
            return [
                'success' => false,
                'error' => 'File is not a valid image type. Detected: ' . ($mime_type ?: 'unknown')
            ];
        }

        // Determine extension
        $extension = '';
        switch ($mime_type) {
            case 'image/jpeg':
                $extension = 'jpg';
                break;
            case 'image/png':
                $extension = 'png';
                break;
            case 'image/gif':
                $extension = 'gif';
                break;
            case 'image/webp':
                $extension = 'webp';
                break;
        }

        // Create filename
        if (!empty($args['filename'])) {
            $filename = sanitize_file_name($args['filename']) . '.' . $extension;
        } else {
            $filename = sanitize_file_name(basename(parse_url($url, PHP_URL_PATH)));
            if (empty(pathinfo($filename, PATHINFO_EXTENSION))) {
                $filename .= '.' . $extension;
            }
        }

        // Prepare file array for sideload
        $file_array = [
            'name' => $filename,
            'tmp_name' => $temp_file
        ];

        // Upload the file
        $attachment_id = media_handle_sideload($file_array, 0);

        if (is_wp_error($attachment_id)) {
            @unlink($temp_file);
            return [
                'success' => false,
                'error' => 'Failed to upload image: ' . $attachment_id->get_error_message()
            ];
        }

        // Update attachment metadata
        if (!empty($args['title'])) {
            wp_update_post([
                'ID' => $attachment_id,
                'post_title' => sanitize_text_field($args['title'])
            ]);
        }

        if (!empty($args['alt_text'])) {
            update_post_meta($attachment_id, '_wp_attachment_image_alt', sanitize_text_field($args['alt_text']));
        }

        if (!empty($args['caption'])) {
            wp_update_post([
                'ID' => $attachment_id,
                'post_excerpt' => sanitize_text_field($args['caption'])
            ]);
        }

        // Get attachment info
        $attachment_url = wp_get_attachment_url($attachment_id);
        $attachment_metadata = wp_get_attachment_metadata($attachment_id);

        return [
            'success' => true,
            'message' => 'Image uploaded successfully',
            'attachment_id' => $attachment_id,
            'url' => $attachment_url,
            'filename' => $filename,
            'width' => $attachment_metadata['width'] ?? null,
            'height' => $attachment_metadata['height'] ?? null,
            'filesize' => filesize(get_attached_file($attachment_id))
        ];
    }

    /**
     * Set product image
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function set_product_image($args) {
        global $wpdb;

        $product_id = intval($args['product_id']);

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

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

        $image_id = null;

        // If image_url is provided, upload it first
        if (!empty($args['image_url'])) {
            $upload_result = $this->upload_image_from_url([
                'url' => $args['image_url'],
                'title' => $product->name . ' - Featured Image'
            ]);

            if (!$upload_result['success']) {
                return $upload_result;
            }

            $image_id = $upload_result['attachment_id'];
        } elseif (!empty($args['image_id'])) {
            $image_id = intval($args['image_id']);

            // Verify attachment exists
            if (!wp_attachment_is_image($image_id)) {
                return [
                    'success' => false,
                    'error' => 'Invalid image attachment ID'
                ];
            }
        } else {
            return [
                'success' => false,
                'error' => 'Either image_id or image_url must be provided'
            ];
        }

        // Update product
        $updated = $wpdb->update(
            "{$wpdb->prefix}ggmc_products",
            [
                'image_id' => $image_id,
                'updated_at' => current_time('mysql')
            ],
            ['id' => $product_id]
        );

        if ($updated === false) {
            return [
                'success' => false,
                'error' => 'Failed to update product image'
            ];
        }

        return [
            'success' => true,
            'message' => 'Product image updated successfully',
            'product_id' => $product_id,
            'product_name' => $product->name,
            'image_id' => $image_id,
            'image_url' => wp_get_attachment_url($image_id)
        ];
    }

    /**
     * Add image to product gallery
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function add_product_gallery_image($args) {
        global $wpdb;

        $product_id = intval($args['product_id']);

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

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

        $image_id = null;

        // If image_url is provided, upload it first
        if (!empty($args['image_url'])) {
            $upload_result = $this->upload_image_from_url([
                'url' => $args['image_url'],
                'title' => $product->name . ' - Gallery Image'
            ]);

            if (!$upload_result['success']) {
                return $upload_result;
            }

            $image_id = $upload_result['attachment_id'];
        } elseif (!empty($args['image_id'])) {
            $image_id = intval($args['image_id']);

            // Verify attachment exists
            if (!wp_attachment_is_image($image_id)) {
                return [
                    'success' => false,
                    'error' => 'Invalid image attachment ID'
                ];
            }
        } else {
            return [
                'success' => false,
                'error' => 'Either image_id or image_url must be provided'
            ];
        }

        // Parse existing gallery IDs
        $gallery_ids = [];
        if (!empty($product->gallery_ids)) {
            $gallery_ids = array_filter(array_map('intval', explode(',', $product->gallery_ids)));
        }

        // Add new image if not already in gallery
        if (!in_array($image_id, $gallery_ids)) {
            $gallery_ids[] = $image_id;
        }

        // Update product
        $updated = $wpdb->update(
            "{$wpdb->prefix}ggmc_products",
            [
                'gallery_ids' => implode(',', $gallery_ids),
                'updated_at' => current_time('mysql')
            ],
            ['id' => $product_id]
        );

        if ($updated === false) {
            return [
                'success' => false,
                'error' => 'Failed to update product gallery'
            ];
        }

        // Build gallery info
        $gallery_info = [];
        foreach ($gallery_ids as $gid) {
            $gallery_info[] = [
                'id' => $gid,
                'url' => wp_get_attachment_url($gid)
            ];
        }

        return [
            'success' => true,
            'message' => 'Image added to product gallery',
            'product_id' => $product_id,
            'product_name' => $product->name,
            'added_image_id' => $image_id,
            'added_image_url' => wp_get_attachment_url($image_id),
            'gallery_count' => count($gallery_ids),
            'gallery' => $gallery_info
        ];
    }

    /**
     * List media library images
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function list_media_images($args) {
        $limit = isset($args['limit']) ? min(100, max(1, intval($args['limit']))) : 20;
        $offset = isset($args['offset']) ? max(0, intval($args['offset'])) : 0;

        $query_args = [
            'post_type' => 'attachment',
            'post_mime_type' => 'image',
            'post_status' => 'inherit',
            'posts_per_page' => $limit,
            'offset' => $offset,
            'orderby' => 'date',
            'order' => 'DESC'
        ];

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

        $query = new WP_Query($query_args);
        $images = [];

        foreach ($query->posts as $post) {
            $metadata = wp_get_attachment_metadata($post->ID);
            $images[] = [
                'id' => $post->ID,
                'title' => $post->post_title,
                'filename' => basename(get_attached_file($post->ID)),
                'url' => wp_get_attachment_url($post->ID),
                'thumbnail' => wp_get_attachment_image_url($post->ID, 'thumbnail'),
                'width' => $metadata['width'] ?? null,
                'height' => $metadata['height'] ?? null,
                'alt_text' => get_post_meta($post->ID, '_wp_attachment_image_alt', true),
                'uploaded' => $post->post_date
            ];
        }

        return [
            'success' => true,
            'total' => $query->found_posts,
            'returned' => count($images),
            'offset' => $offset,
            'images' => $images
        ];
    }

    /**
     * Upload image from base64 data
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function upload_image_base64($args) {
        $data = $args['data'] ?? '';
        $filename = sanitize_file_name($args['filename'] ?? 'upload.jpg');
        $mime = $args['mime'] ?? 'image/jpeg';

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

        // Validate MIME type
        $allowed_mimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
        if (!in_array($mime, $allowed_mimes, true)) {
            return [
                'success' => false,
                'error' => 'Invalid image type. Allowed: jpeg, png, gif, webp'
            ];
        }

        // Decode base64
        $decoded = base64_decode($data, true);
        if ($decoded === false) {
            return [
                'success' => false,
                'error' => 'Invalid base64 data'
            ];
        }

        // Limit file size (10MB)
        if (strlen($decoded) > 10 * 1024 * 1024) {
            return [
                'success' => false,
                'error' => 'Image exceeds 10MB size limit'
            ];
        }

        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
        require_once(ABSPATH . 'wp-admin/includes/image.php');

        // Write to temp file
        $upload_dir = wp_upload_dir();
        $temp_file = $upload_dir['basedir'] . '/' . wp_unique_filename($upload_dir['basedir'], $filename);

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
        if (file_put_contents($temp_file, $decoded) === false) {
            return [
                'success' => false,
                'error' => 'Failed to write temporary file'
            ];
        }

        // Prepare file array for media_handle_sideload
        $file_array = [
            'name'     => $filename,
            'type'     => $mime,
            'tmp_name' => $temp_file,
            'error'    => 0,
            'size'     => strlen($decoded),
        ];

        // Upload to media library
        $attachment_id = media_handle_sideload($file_array, 0);

        // Clean up temp file if it still exists
        if (file_exists($temp_file)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink
            unlink($temp_file);
        }

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

        // Set alt text if provided
        if (!empty($args['alt_text'])) {
            update_post_meta($attachment_id, '_wp_attachment_image_alt', sanitize_text_field($args['alt_text']));
        }

        // Set title if provided
        if (!empty($args['title'])) {
            wp_update_post([
                'ID' => $attachment_id,
                'post_title' => sanitize_text_field($args['title']),
            ]);
        }

        $url = wp_get_attachment_url($attachment_id);
        $metadata = wp_get_attachment_metadata($attachment_id);

        return [
            'success' => true,
            'message' => 'Image uploaded successfully',
            'attachment_id' => $attachment_id,
            'url' => $url,
            'filename' => $filename,
            'width' => $metadata['width'] ?? null,
            'height' => $metadata['height'] ?? null,
            'filesize' => strlen($decoded)
        ];
    }
}
