<?php
/**
 * Image Processor for resizing
 *
 * @package PackshotPhotoAI
 */

namespace PackshotPhotoAI\Core;

defined('ABSPATH') || exit;

/**
 * Handles image resizing operations
 */
class ImageProcessor {

    /**
     * Register hooks — called from Plugin.php
     */
    public function register_hooks(): void {
        add_action('added_post_meta', [$this, 'maybe_auto_resize'], 8, 4);
    }

    /**
     * Check if auto-resize should run on upload
     * Fires on 'added_post_meta' for _wp_attachment_metadata — AFTER thumbnails are generated
     *
     * @param int    $meta_id    Meta ID
     * @param int    $post_id    Post ID
     * @param string $meta_key   Meta key
     * @param mixed  $meta_value Meta value
     */
    public function maybe_auto_resize($meta_id, $post_id, $meta_key, $meta_value): void {
        if ($meta_key !== '_wp_attachment_metadata') {
            return;
        }

        $max_size = (int) get_option('packshotphoto_max_image_size', 0);
        if ($max_size <= 0) {
            return;
        }

        $mime_type = get_post_mime_type($post_id);
        if (!$mime_type || strpos($mime_type, 'image/') !== 0) {
            return;
        }


        static $processed = [];
        if (isset($processed[$post_id])) {
            return;
        }
        $processed[$post_id] = true;

        $file_path = get_attached_file($post_id);
        if (!$file_path || !file_exists($file_path)) {
            return;
        }

        $image_data = @getimagesize($file_path);
        if (!$image_data) {
            return;
        }

        $longest = max($image_data[0], $image_data[1]);
        if ($longest <= $max_size) {
            return;
        }

        remove_action('added_post_meta', [$this, 'maybe_auto_resize'], 8);
        try {
            $this->resize($post_id, $max_size);
        } finally {
            add_action('added_post_meta', [$this, 'maybe_auto_resize'], 8, 4);
        }
    }

    /**
     * Resize an attachment image
     *
     * @param int $post_id  Attachment ID
     * @param int $max_size Maximum dimension for longest edge
     * @return array{success: bool, message?: string}
     */
    public function resize(int $post_id, int $max_size): array {
        MemoryManager::ensure_memory_limit();
        $file_path = \get_attached_file($post_id);
        
        if (!$file_path || !file_exists($file_path)) {
            return [
                'success' => false,
                'message' => __('File does not exist', 'packshotphoto-ai'),
            ];
        }

        $mime_type = get_post_mime_type($post_id);
        
        $supported = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif'];
        if (!in_array($mime_type, $supported, true)) {
            return [
                'success' => false,
                'message' => __('Unsupported format', 'packshotphoto-ai'),
            ];
        }

        $image_data = getimagesize($file_path);
        if (!$image_data) {
            return [
                'success' => false,
                'message' => __('Cannot read image', 'packshotphoto-ai'),
            ];
        }

        [$width, $height] = $image_data;

        $longest = max($width, $height);
        
        // If image is already smaller or equal to max size, skip resizing but return success
        if ($longest <= $max_size) {
            $size = filesize($file_path);
            $ext  = strtoupper(pathinfo($file_path, PATHINFO_EXTENSION));
            return [
                'success' => true,
                'message' => sprintf(
                    /* translators: 1: width, 2: height */
                    __('Skipped: Image is already within maximum dimensions (%1$dx%2$d)', 'packshotphoto-ai'),
                    $width, $height
                ),
                'data' => [
                    'old_width'     => $width,
                    'old_height'    => $height,
                    'new_width'     => $width,
                    'new_height'    => $height,
                    'file'          => $file_path,
                    'before_format' => $ext,
                    'after_format'  => $ext,
                    'before_size'   => size_format($size),
                    'after_size'    => size_format($size),
                    'savings'       => 0,
                ],
            ];
        }

        if ($width > $height) {
            $new_width  = $max_size;
            $new_height = (int) round($height * ($max_size / $width));
        } else {
            $new_height = $max_size;
            $new_width  = (int) round($width * ($max_size / $height));
        }

        // WordPress image editor doesn't support upscaling - check for Imagick first
        $use_imagick = extension_loaded('imagick');

        if (!$use_imagick && ($new_width > $width || $new_height > $height)) {
            return [
                'success' => false,
                'message' => __('Cannot upscale images without Imagick extension. Target size is larger than original dimensions.', 'packshotphoto-ai'),
            ];
        }



        Logger::info('ImageProcessor: Resize attempt', [
            'post_id' => $post_id,
            'original' => $width . 'x' . $height,
            'target' => $max_size,
            'calculated' => $new_width . 'x' . $new_height,
            'file' => $file_path,
            'imagick' => $use_imagick
        ]);

        if ($new_width <= 0 || $new_height <= 0) {
            Logger::error('ImageProcessor: Invalid calculated dimensions', [
                'post_id' => $post_id,
                'width' => $width,
                'height' => $height,
                'max_size' => $max_size,
                'new_width' => $new_width,
                'new_height' => $new_height,
                'file' => $file_path
            ]);
            return [
                'success' => false,
                'message' => sprintf(
                    /* translators: 1: original width, 2: original height, 3: target max size */
                    __('Could not calculate resized image dimensions. Original: %1$dx%2$d, Target: %3$d', 'packshotphoto-ai'),
                    $width,
                    $height,
                    $max_size
                ),
            ];
        }

        // Backup original file first
        $delete_mode = get_option('packshotphoto_delete_mode', 'trash');
        $path_info     = pathinfo($file_path);
        $timestamp     = time();
        $backup_name   = $path_info['filename'] . '-original-' . $timestamp . '.' . $path_info['extension'];
        $upload_dir    = \wp_upload_dir();
        
        $trash_dir = $upload_dir['basedir'] . '/packshotphoto-trash';
        if (!file_exists($trash_dir)) {
            \wp_mkdir_p($trash_dir);
        }
        
        $backup_path = $trash_dir . '/' . $backup_name;
        $backup_rel  = 'packshotphoto-trash/' . $backup_name;

        if (!copy($file_path, $backup_path)) {
            Logger::error('Resize: Failed to create backup', ['id' => $post_id, 'source' => $file_path, 'backup' => $backup_path]);
            return [
                'success' => false,
                'message' => __('Cannot create backup', 'packshotphoto-ai'),
            ];
        }

        $before_size = filesize($backup_path);

        // Use Imagick for resize (supports both up and downscale)
        if ($use_imagick) {
            try {
                $imagick = new \Imagick($file_path);
                $imagick->resizeImage($new_width, $new_height, \Imagick::FILTER_LANCZOS, 1);
                $imagick->writeImage($file_path);
                $imagick->destroy();
                Logger::info('ImageProcessor: Resized with Imagick', ['post_id' => $post_id]);
            } catch (\Exception $e) {
                // Restore backup on error
                @copy($backup_path, $file_path);
                wp_delete_file($backup_path);
                Logger::error('ImageProcessor: Imagick resize failed', ['error' => $e->getMessage()]);
                return [
                    'success' => false,
                    'message' => sprintf(
                        /* translators: %s: error message */
                        __('Resize failed: %s', 'packshotphoto-ai'),
                        $e->getMessage()
                    ),
                ];
            }
        } elseif ('image/avif' === $mime_type) {
            // GD manual resize for AVIF (since standard WP editor may not support it)
            if (function_exists('imagecreatefromavif') && function_exists('imageavif')) {
                $src = @imagecreatefromavif($file_path);
                if ($src) {
                    $dst = imagecreatetruecolor($new_width, $new_height);
                    if ($dst) {
                        imagealphablending($dst, false);
                        imagesavealpha($dst, true);
                        imagecopyresampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
                        $saved = imageavif($dst, $file_path, 85, 9);
                        imagedestroy($dst);
                        imagedestroy($src);
                        if ($saved) {
                            Logger::info('ImageProcessor: Resized AVIF manually with GD', ['post_id' => $post_id]);
                        } else {
                            @copy($backup_path, $file_path);
                            wp_delete_file($backup_path);
                            return ['success' => false, 'message' => __('Failed to save resized AVIF image using GD.', 'packshotphoto-ai')];
                        }
                    } else {
                        imagedestroy($src);
                        @copy($backup_path, $file_path);
                        wp_delete_file($backup_path);
                        return ['success' => false, 'message' => __('Failed to create truecolor image resource.', 'packshotphoto-ai')];
                    }
                } else {
                    @copy($backup_path, $file_path);
                    wp_delete_file($backup_path);
                    return ['success' => false, 'message' => __('Failed to read AVIF image using GD.', 'packshotphoto-ai')];
                }
            } else {
                @copy($backup_path, $file_path);
                wp_delete_file($backup_path);
                return ['success' => false, 'message' => __('GD AVIF support is missing on this server.', 'packshotphoto-ai')];
            }
        } else {
            // Fallback to GD (only supports downscale)
            $editor = \wp_get_image_editor($file_path);
            if (\is_wp_error($editor)) {
                @copy($backup_path, $file_path);
                wp_delete_file($backup_path);
                return [
                    'success' => false,
                    'message' => $editor->get_error_message(),
                ];
            }

            $result = $editor->resize($new_width, $new_height, false);
            if (\is_wp_error($result)) {
                @copy($backup_path, $file_path);
                wp_delete_file($backup_path);
                return [
                    'success' => false,
                    'message' => $result->get_error_message(),
                ];
            }

            $save_result = $editor->save($file_path);
            if (\is_wp_error($save_result)) {
                @copy($backup_path, $file_path);
                wp_delete_file($backup_path);
                return [
                    'success' => false,
                    'message' => $save_result->get_error_message(),
                ];
            }
        }

        if ('delete' === $delete_mode) {
            wp_delete_file($backup_path);
        } elseif ('trash' === $delete_mode) {
            $existing_backup = \get_post_meta($post_id, '_pmm_original_backup', true);
            if (empty($existing_backup)) {
                \update_post_meta($post_id, '_pmm_original_backup', $backup_rel);
                // Cache flag for fast column rendering (avoid 8 FS ops per row!)
                \update_post_meta($post_id, '_pmm_has_file_backup', '1');
            }
        }

        // Delete old thumbnails and regenerate
        $old_metadata = \wp_get_attachment_metadata($post_id);
        if (!empty($old_metadata['sizes'])) {
            $old_file_path = \get_attached_file($post_id);
            foreach ($old_metadata['sizes'] as $size_info) {
                if (!empty($size_info['file'])) {
                    $old_thumb_path = dirname($old_file_path) . '/' . $size_info['file'];
                    if (file_exists($old_thumb_path)) {
                        wp_delete_file($old_thumb_path);
                    }
                }
            }
        }

        \delete_post_meta($post_id, '_wp_attachment_metadata');
        
        $metadata = \wp_generate_attachment_metadata($post_id, $file_path);
        if (!empty($metadata) && !\is_wp_error($metadata)) {
            \wp_update_attachment_metadata($post_id, $metadata);
        }

        $after_size = filesize($file_path);
        $before_ext = strtoupper($path_info['extension']);
        $after_ext = strtoupper(pathinfo($file_path, PATHINFO_EXTENSION));

        return [
            'success' => true,
            'message' => sprintf(
                /* translators: 1: original width, 2: original height, 3: target width, 4: target height */
                __('Resized from %1$dx%2$d to %3$dx%4$d', 'packshotphoto-ai'),
                $width, $height, $new_width, $new_height
            ),
            'data' => [
                'old_width'  => $width,
                'old_height' => $height,
                'new_width'  => $new_width,
                'new_height' => $new_height,
                'file'       => $file_path,
                'before_format' => $before_ext,
                'after_format'  => $after_ext,
                'before_size'    => size_format($before_size),
                'after_size'     => size_format($after_size),
                'savings'        => $before_size > 0 ? round((($before_size - $after_size) / $before_size) * 100, 1) : 0,
            ],
        ];
    }

    /**
     * AJAX: Resize image manually
     */
    public function ajax_resize(): void {
        $post_id = isset($_POST['id']) ? \absint($_POST['id']) : 0;
        if (!$post_id) {
            \wp_send_json_error(__('Missing file ID', 'packshotphoto-ai'));
        }

        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        if (!\wp_verify_nonce($nonce, 'packshotphoto_edit_' . $post_id)) {
            \wp_send_json_error(__('Security error', 'packshotphoto-ai'), 403);
        }

        if (!\current_user_can('edit_post', $post_id)) {
            \wp_send_json_error(__('Permission denied', 'packshotphoto-ai'), 403);
        }

        $max_size = isset($_POST['target_width']) ? (int)sanitize_text_field(wp_unslash($_POST['target_width'])) : 0;

        if ($max_size <= 0) {
            $max_size = (int) get_option('packshotphoto_max_image_size', 0);
        }

        if ($max_size <= 0) {
            \wp_send_json_error(__('Provide width or set default in settings.', 'packshotphoto-ai'));
        }

        $result = $this->resize($post_id, $max_size);

        if ($result['success']) {
            \wp_send_json_success($result);
        } else {
            \wp_send_json_error($result);
        }
    }
}
