<?php

/**
 * Images REST API Controller
 *
 * Handles individual image optimization, stats, and bulk operations
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * ImagesController class
 */


class ImagesController extends \WP_REST_Controller {

    /**
     * MIME types eligible for optimization.
     *
     * @var array<int, string>
     */
    private const OPTIMIZABLE_MIME_TYPES = ['image/jpeg', 'image/png'];
    
    /**
     * Module instance
     *
     * @var object|null
     */
    private $module = null;
    
    /**
     * Constructor
     */
    public function __construct() {
        $this->namespace = 'prorank-seo/v1';
        $this->rest_base = 'images';
    }
    
    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Optimize single image
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/optimize',
            [
                [
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => [$this, 'optimize_image'],
                    'permission_callback' => [$this, 'manage_media_permissions_check'],
                    'args'                => [
                        'attachment_id' => [
                            'required'          => true,
                            'validate_callback' => function($param) {
                                return is_numeric($param);
                            },
                        ],
                    ],
                ],
            ]
        );
        
        // Get unoptimized images
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/unoptimized',
            [
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [$this, 'get_unoptimized_images'],
                    'permission_callback' => [$this, 'manage_media_permissions_check'],
                ],
            ]
        );
        
        // NOTE: Single-image /images/{id}/optimization-stats is registered by
        // ImageOptimizationController. Do NOT duplicate it here to avoid route conflicts.
    }
    
    /**
     * Get module instance
     *
     * @return object|null
     */
    private function get_module() {
        if ($this->module !== null) {
            return $this->module;
        }

        $plugin = \ProRank\SEO\Plugin::get_instance();
        if (!$plugin || !$plugin->is_initialized()) {
            return null;
        }

        $module_manager = $plugin->modules();
        if (!$module_manager) {
            return null;
        }

        $module = $module_manager->get_module('image_optimization');
        if (!is_object($module)) {
            return null;
        }

        // Avoid hard dependency on a specific class name (free vs premium split)
        foreach (['is_enabled', 'generate_optimized_images', 'get_optimized_path'] as $method) {
            if (!method_exists($module, $method)) {
                return null;
            }
        }

        $this->module = $module;

        return $this->module;
    }
    
    /**
     * Check permissions for managing media
     *
     * @param WP_REST_Request $request Request object
     * @return bool|WP_Error
     */
    public function manage_media_permissions_check($request) {
        if (!current_user_can('upload_files')) {
            return new WP_Error(
                'rest_forbidden',
                __('Sorry, you are not allowed to manage media files.', 'prorank-seo'),
                ['status' => 403]
            );
        }
        
        return true;
    }
    
    /**
     * Optimize a single image
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function optimize_image(WP_REST_Request $request) {
        $attachment_id = (int) $request->get_param('attachment_id');
        
        // Verify attachment exists and is an image
        if (!wp_attachment_is_image($attachment_id)) {
            return new WP_Error(
                'invalid_attachment',
                __('Invalid image attachment.', 'prorank-seo'),
                ['status' => 400]
            );
        }
        
        $module = $this->get_module();
        if (!$module) {
            return new WP_Error(
                'module_not_found',
                __('Image optimization module not found.', 'prorank-seo'),
                ['status' => 404]
            );
        }
        
        if (!$module->is_enabled()) {
            return new WP_Error(
                'module_disabled',
                __('Image optimization module is disabled.', 'prorank-seo'),
                ['status' => 400]
            );
        }
        
        // Get attachment metadata
        $metadata = wp_get_attachment_metadata($attachment_id);
        if (!$metadata) {
            return new WP_Error(
                'no_metadata',
                __('Could not retrieve image metadata.', 'prorank-seo'),
                ['status' => 500]
            );
        }
        
        // Get original file info
        $file_path = get_attached_file($attachment_id);
        $original_size = filesize($file_path);
        
        // Generate optimized images
        $result = $module->generate_optimized_images($metadata, $attachment_id);
        
        // Calculate savings
        $new_size = filesize($file_path);
        $saved_bytes = $original_size - $new_size;
        $saved_percent = ($saved_bytes / $original_size) * 100;
        
        // Check if WebP/AVIF were generated
        $webp_generated = false;
        $avif_generated = false;
        
        $webp_path = $module->get_optimized_path($file_path, 'webp');
        if (file_exists($webp_path)) {
            $webp_generated = true;
        }
        
        $avif_path = $module->get_optimized_path($file_path, 'avif');
        if (file_exists($avif_path)) {
            $avif_generated = true;
        }
        
        return rest_ensure_response([
            'success' => true,
            'attachment_id' => $attachment_id,
            'original_size' => size_format($original_size),
            'new_size' => size_format($new_size),
            'saved_size' => size_format($saved_bytes),
            'saved_percent' => round($saved_percent, 2),
            'webp_generated' => $webp_generated,
            'avif_generated' => $avif_generated,
            'message' => sprintf(
/* translators: %1$: value, %2$: value */
                __('Image optimized! Saved %1$s (%2$s%%)', 'prorank-seo'),
                size_format($saved_bytes),
                round($saved_percent, 1)
            ),
        ]);
    }
    
    /**
     * Get list of unoptimized images
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_unoptimized_images(WP_REST_Request $request) {
        global $wpdb;
        
        // Get all image attachments that haven't been optimized
        $args = [
            'post_type'      => 'attachment',
            'post_mime_type' => self::OPTIMIZABLE_MIME_TYPES,
            'post_status'    => 'inherit',
            'posts_per_page' => -1,
            'fields'         => 'ids',
            'meta_query'     => [
                'relation' => 'OR',
                [
                    'key'     => '_prorank_optimized',
                    'compare' => 'NOT EXISTS',
                ],
                [
                    'key'     => '_prorank_optimized',
                    'value'   => '1',
                    'compare' => '!=',
                ],
            ],
        ];
        
        $attachment_ids = get_posts($args);
        
        // Get basic info for each unoptimized image
        $images = [];
        foreach (array_slice($attachment_ids, 0, 100) as $id) { // Limit to first 100
            $file_path = get_attached_file($id);
            if ($file_path && file_exists($file_path)) {
                $images[] = [
                    'id' => $id,
                    'title' => get_the_title($id),
                    'size' => filesize($file_path),
                    'size_formatted' => size_format(filesize($file_path)),
                    'mime_type' => get_post_mime_type($id),
                ];
            }
        }
        
        return rest_ensure_response([
            'attachment_ids' => $attachment_ids,
            'total' => count($attachment_ids),
            'images' => $images,
        ]);
    }
    
    /**
     * Get optimization stats for a single image
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_image_stats(WP_REST_Request $request) {
        $attachment_id = (int) $request->get_param('id');
        
        // Check if image is optimized
        $is_optimized = get_post_meta($attachment_id, '_prorank_optimized', true);
        
        if (!$is_optimized) {
            return rest_ensure_response([
                'optimized' => false,
                'stats' => null,
            ]);
        }
        
        // Get optimization stats
        $stats = [
            'original_size' => get_post_meta($attachment_id, '_prorank_original_size', true),
            'optimized_size' => get_post_meta($attachment_id, '_prorank_optimized_size', true),
            'saved_bytes' => get_post_meta($attachment_id, '_prorank_optimization_savings', true),
            'saved_percent' => get_post_meta($attachment_id, '_prorank_optimization_percent', true),
            'optimization_date' => get_post_meta($attachment_id, '_prorank_optimization_date', true),
            'optimization_method' => get_post_meta($attachment_id, '_prorank_optimization_method', true),
        ];
        
        // Check for WebP/AVIF versions
        $file_path = get_attached_file($attachment_id);
        $module = $this->get_module();
        
        if ($module && $file_path) {
            $webp_path = $module->get_optimized_path($file_path, 'webp');
            $avif_path = $module->get_optimized_path($file_path, 'avif');
            
            $stats['webp_exists'] = file_exists($webp_path);
            $stats['avif_exists'] = file_exists($avif_path);
            
            if ($stats['webp_exists']) {
                $stats['webp_size'] = filesize($webp_path);
            }
            
            if ($stats['avif_exists']) {
                $stats['avif_size'] = filesize($avif_path);
            }
        }
        
        return rest_ensure_response([
            'optimized' => true,
            'stats' => $stats,
        ]);
    }
}
