<?php
namespace PrimeLink\Helpers;

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

/**
 * Image helper using Intervention Image if available, with fallback to WooCommerce functions.
 */
final class ImageHelper {

    /**
     * Check if Intervention Image is available (prefixed or normal).
     *
     * @return bool
     */
    public static function has_intervention_image() {
        // Intervention Image 2.7 requires PHP 8.0.2+
        if ( version_compare( PHP_VERSION, '8.0.2', '<' ) ) {
            return false;
        }
        
        return class_exists( '\PrimeLink\Vendor\Intervention\Image\ImageManager' ) ||
               class_exists( '\Intervention\Image\ImageManager' );
    }

    /**
     * Get Intervention Image Manager class.
     *
     * @return string|null
     */
    private static function get_image_manager_class() {
        if ( class_exists( '\PrimeLink\Vendor\Intervention\Image\ImageManager' ) ) {
            return '\PrimeLink\Vendor\Intervention\Image\ImageManager';
        } elseif ( class_exists( '\Intervention\Image\ImageManager' ) ) {
            return '\Intervention\Image\ImageManager';
        }
        return null;
    }

    /**
     * Get Image Manager instance (v2 API).
     *
     * @return object|null ImageManager instance or null.
     */
    private static function get_image_manager() {
        if ( ! self::has_intervention_image() ) {
            return null;
        }

        $manager_class = self::get_image_manager_class();
        if ( ! $manager_class ) {
            return null;
        }

        // Intervention Image v2 uses config array, not Driver objects
        // Try Imagick first (better quality), then GD
        $config = array();
        if ( extension_loaded( 'imagick' ) ) {
            $config['driver'] = 'imagick';
        } elseif ( extension_loaded( 'gd' ) ) {
            $config['driver'] = 'gd';
        } else {
            return null; // No image library available
        }

        return new $manager_class( $config );
    }

    /**
     * Validate image file.
     *
     * @param string $file_path File path.
     * @return array{valid: bool, error?: string, width?: int, height?: int, mime?: string}
     */
    public static function validate( $file_path ) {
        if ( ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
            return array(
                'valid' => false,
                'error' => 'File not found or not readable.',
            );
        }

        if ( self::has_intervention_image() ) {
            try {
                $manager = self::get_image_manager();
                if ( $manager ) {
                    $image = $manager->make( $file_path );
                    
                    return array(
                        'valid'  => true,
                        'width'  => $image->width(),
                        'height' => $image->height(),
                        'mime'   => $image->mime(),
                    );
                }
            } catch ( \Exception $e ) {
                return array(
                    'valid' => false,
                    'error' => 'Invalid image: ' . $e->getMessage(),
                );
            }
        }

        // Fallback to WooCommerce function
        $image_info = @getimagesize( $file_path );
        if ( $image_info === false ) {
            return array(
                'valid' => false,
                'error' => 'Invalid image file.',
            );
        }

        return array(
            'valid'  => true,
            'width'  => $image_info[0],
            'height' => $image_info[1],
            'mime'   => $image_info['mime'],
        );
    }

    /**
     * Optimize image (resize, compress, convert format).
     *
     * @param string $source_path Source file path.
     * @param string $destination_path Destination file path.
     * @param array  $options Options:
     *   - max_width (int): Maximum width (0 = no limit)
     *   - max_height (int): Maximum height (0 = no limit)
     *   - quality (int): JPEG quality 1-100 (default: 85)
     *   - format (string): Output format (jpg, png, webp, avif) or null to keep original
     *   - strip_metadata (bool): Remove EXIF metadata (default: true)
     * @return array{success: bool, path?: string, original_size?: int, optimized_size?: int, error?: string}
     */
    public static function optimize( $source_path, $destination_path, array $options = array() ) {
        $defaults = array(
            'max_width'      => 0,
            'max_height'     => 0,
            'quality'        => 85,
            'format'         => null, // Keep original format
            'strip_metadata' => true,
        );
        $options = wp_parse_args( $options, $defaults );

        if ( ! file_exists( $source_path ) || ! is_readable( $source_path ) ) {
            return array(
                'success' => false,
                'error'   => 'Source file not found or not readable.',
            );
        }

        $original_size = filesize( $source_path );

        if ( self::has_intervention_image() ) {
            try {
                $manager = self::get_image_manager();
                if ( ! $manager ) {
                    throw new \Exception( 'Image manager not available.' );
                }

                $image = $manager->make( $source_path );

                // Resize if needed
                if ( $options['max_width'] > 0 || $options['max_height'] > 0 ) {
                    $width = $image->width();
                    $height = $image->height();

                    $max_width = $options['max_width'] > 0 ? $options['max_width'] : $width;
                    $max_height = $options['max_height'] > 0 ? $options['max_height'] : $height;

                    if ( $width > $max_width || $height > $max_height ) {
                        // Resize maintaining aspect ratio
                        $image->resize( $max_width, $max_height, function ( $constraint ) {
                            $constraint->aspectRatio();
                            $constraint->upsize();
                        } );
                    }
                }

                // Strip metadata if requested (v2 doesn't have strip(), but we can encode without EXIF)
                // Note: v2 doesn't have explicit strip() method, metadata is handled during encoding

                // Determine output format
                $format = $options['format'];
                if ( empty( $format ) ) {
                    // Keep original format
                    $mime = $image->mime();
                    if ( $mime === 'image/jpeg' ) {
                        $format = 'jpg';
                    } elseif ( $mime === 'image/png' ) {
                        $format = 'png';
                    } elseif ( $mime === 'image/webp' ) {
                        $format = 'webp';
                    } else {
                        $format = 'jpg'; // Default fallback
                    }
                }

                // Save with format and quality
                $destination_dir = dirname( $destination_path );
                if ( ! file_exists( $destination_dir ) ) {
                    wp_mkdir_p( $destination_dir );
                }

                if ( $format === 'jpg' || $format === 'jpeg' ) {
                    $image->encode( 'jpg', $options['quality'] )->save( $destination_path );
                } elseif ( $format === 'png' ) {
                    $image->encode( 'png' )->save( $destination_path );
                } elseif ( $format === 'webp' ) {
                    $image->encode( 'webp', $options['quality'] )->save( $destination_path );
                } else {
                    // Fallback to original format
                    $image->save( $destination_path, $options['quality'] );
                }

                $optimized_size = file_exists( $destination_path ) ? filesize( $destination_path ) : 0;

                return array(
                    'success'        => true,
                    'path'           => $destination_path,
                    'original_size'  => $original_size,
                    'optimized_size' => $optimized_size,
                );
            } catch ( \Exception $e ) {
                LoggerHelper::warning( 'Image optimization failed', array(
                    'source' => $source_path,
                    'error'  => $e->getMessage(),
                ) );
                
                // Fallback: copy original file
                if ( copy( $source_path, $destination_path ) ) {
                    return array(
                        'success'        => true,
                        'path'           => $destination_path,
                        'original_size'  => $original_size,
                        'optimized_size' => $original_size,
                    );
                }

                return array(
                    'success' => false,
                    'error'   => 'Optimization failed: ' . $e->getMessage(),
                );
            }
        }

        // Fallback: copy original file without optimization
        $destination_dir = dirname( $destination_path );
        if ( ! file_exists( $destination_dir ) ) {
            wp_mkdir_p( $destination_dir );
        }

        if ( copy( $source_path, $destination_path ) ) {
            return array(
                'success'        => true,
                'path'           => $destination_path,
                'original_size'  => $original_size,
                'optimized_size' => $original_size,
            );
        }

        return array(
            'success' => false,
            'error'   => 'Failed to copy file.',
        );
    }

    /**
     * Resize image to specific dimensions.
     *
     * @param string $source_path Source file path.
     * @param string $destination_path Destination file path.
     * @param int    $width Target width.
     * @param int    $height Target height.
     * @param bool   $maintain_aspect_ratio Maintain aspect ratio (default: true).
     * @param string $fit Fit mode: 'contain', 'cover', 'fill' (default: 'contain').
     * @return array{success: bool, path?: string, error?: string}
     */
    public static function resize( $source_path, $destination_path, $width, $height, $maintain_aspect_ratio = true, $fit = 'contain' ) {
        if ( ! file_exists( $source_path ) || ! is_readable( $source_path ) ) {
            return array(
                'success' => false,
                'error'   => 'Source file not found or not readable.',
            );
        }

        if ( self::has_intervention_image() ) {
            try {
                $manager = self::get_image_manager();
                if ( ! $manager ) {
                    throw new \Exception( 'Image manager not available.' );
                }

                $image = $manager->make( $source_path );

                if ( $maintain_aspect_ratio ) {
                    if ( $fit === 'cover' ) {
                        $image->fit( $width, $height );
                    } else {
                        $image->resize( $width, $height, function ( $constraint ) {
                            $constraint->aspectRatio();
                        } );
                    }
                } else {
                    $image->resize( $width, $height );
                }

                $destination_dir = dirname( $destination_path );
                if ( ! file_exists( $destination_dir ) ) {
                    wp_mkdir_p( $destination_dir );
                }

                $image->save( $destination_path );

                return array(
                    'success' => true,
                    'path'    => $destination_path,
                );
            } catch ( \Exception $e ) {
                LoggerHelper::warning( 'Image resize failed', array(
                    'source' => $source_path,
                    'error'  => $e->getMessage(),
                ) );

                return array(
                    'success' => false,
                    'error'   => 'Resize failed: ' . $e->getMessage(),
                );
            }
        }

        // Fallback: use WooCommerce image editor
        if ( function_exists( 'wp_get_image_editor' ) ) {
            $editor = wp_get_image_editor( $source_path );
            if ( ! is_wp_error( $editor ) ) {
                $editor->resize( $width, $height, $maintain_aspect_ratio );
                $saved = $editor->save( $destination_path );
                if ( ! is_wp_error( $saved ) ) {
                    return array(
                        'success' => true,
                        'path'    => $saved['path'],
                    );
                }
            }
        }

        return array(
            'success' => false,
            'error'   => 'Resize not available.',
        );
    }
}

