<?php

/**
 * JCOGS Image Pro - Example Variable Provider
 * Demonstrates VariableProvider interface implementation
 * 
 * @category   ExpressionEngine Add-on
 * @package    JCOGS Image Pro
 * @author     JCOGS Design <contact@jcogs.net>
 * @copyright  Copyright (c) 2021 - 2025 JCOGS Design
 * @license    https://jcogs.net/add-ons/license/jcogs_img_pro
 * @version    2.0.6
 * @link       https://JCOGS.net/
 * @since      Provider Architecture v2.0
 */

namespace JCOGSDesign\JCOGSImagePro\Service\Provider;

/**
 * Example Variable Provider
 * 
 * Demonstrates how companion add-ons can implement VariableProviderInterface
 * to add custom template variables to image output.
 * 
 * This example provider adds:
 * - Image file size in bytes and human-readable format
 * - Computed aspect ratio category (portrait/landscape/square)
 * - Basic color mode detection (not implemented - example only)
 * 
 * Usage in companion add-on:
 * ```php
 * // In ext.your_addon.php, hook: jcogs_img_pro_register_providers
 * public function jcogs_img_pro_register_providers($registry) {
 *     $provider = new ExampleVariableProvider();
 *     $registry->registerVariableProvider($provider);
 * }
 * ```
 * 
 * Template usage:
 * ```
 * {exp:jcogs_img_pro:image src="photo.jpg"}
 *   {img_example_file_size} <!-- e.g., "125.3 KB" -->
 *   {img_example_aspect_category} <!-- e.g., "landscape" -->
 * {/exp:jcogs_img_pro:image}
 * ```
 */
class ExampleVariableProvider implements VariableProviderInterface
{
    /**
     * Get provider name for logging/debugging
     * 
     * @return string Provider identifier
     */
    public function getName(): string
    {
        return 'example_variable_provider';
    }
    
    /**
     * Get provider priority
     * 
     * Higher priority providers are called first. If multiple providers
     * return the same variable name, highest priority wins.
     * 
     * Priority guidelines:
     * - 10-50: Fast local computations
     * - 51-99: Moderate complexity operations
     * - 100+: API calls or heavy processing
     * 
     * @return int Priority value
     */
    public function getPriority(): int
    {
        return 20; // Local file operations - moderate priority
    }
    
    /**
     * Check if provider is available and configured
     * 
     * This method can check:
     * - Required PHP extensions (fileinfo, exif, etc.)
     * - API credentials configured
     * - Feature flags enabled
     * - File system access permissions
     * 
     * @return bool True if provider can be used
     */
    public function isAvailable(): bool
    {
        // Example: Check if fileinfo extension is available
        return extension_loaded('fileinfo');
    }
    
    /**
     * Get additional output variables
     * 
     * Called after core variables are generated. Returns associative array
     * of variable names and values to merge into output.
     * 
     * @param array $context Processing context with keys:
     *   - source_path: Original image path
     *   - output_path: Generated cache path URL
     *   - image_resource: GD image resource (may be null at this stage)
     *   - parameters: All tag parameters
     *   - core_variables: Core variables already generated
     *   - image_dimensions: Array with width/height
     *   - responsive_data: srcset/sizes data if applicable
     * 
     * @return array Additional variables as key => value pairs
     */
    public function getAdditionalVariables(array $context): array
    {
        $variables = [];
        
        // Get source path from context
        $source_path = $context['source_path'] ?? '';
        
        if (empty($source_path)) {
            return $variables;
        }
        
        // Convert URL to local file path if needed
        $local_path = $this->url_to_local_path($source_path);
        
        if (!file_exists($local_path)) {
            return $variables;
        }
        
        // Add file size variables
        try {
            $file_size_bytes = filesize($local_path);
            $variables['file_size_bytes'] = $file_size_bytes;
            $variables['file_size'] = $this->format_file_size($file_size_bytes);
        } catch (\Exception $e) {
            // Fail gracefully - don't break output generation
        }
        
        // Add aspect ratio category
        $width = $context['image_dimensions']['width'] ?? 0;
        $height = $context['image_dimensions']['height'] ?? 0;
        
        if ($width > 0 && $height > 0) {
            $variables['aspect_category'] = $this->get_aspect_category($width, $height);
        }
        
        // Example: Add image format from path
        $path_info = pathinfo($local_path);
        $variables['source_format'] = strtoupper($path_info['extension'] ?? 'unknown');
        
        return $variables;
    }
    
    /**
     * Get variable prefix
     * 
     * All variables from this provider will be prefixed with this string.
     * For example, with prefix 'example', variable 'file_size' becomes
     * 'example_file_size' (or 'img_example_file_size' with tag prefix).
     * 
     * @return string|null Variable prefix or null for no prefix
     */
    public function getVariablePrefix(): ?string
    {
        return 'example';
    }
    
    /**
     * Convert URL to local file path
     * 
     * @param string $url Image URL
     * @return string Local file path
     */
    private function url_to_local_path(string $url): string
    {
        // Remove query string
        $url = strtok($url, '?');
        
        // If it's already a local path, return as-is
        if (strpos($url, '://') === false) {
            return $url;
        }
        
        // Convert URL to local path (basic implementation)
        // In production, use EE's path resolution or FilesystemService
        $parsed = parse_url($url);
        $path = $parsed['path'] ?? '';
        
        // Remove leading slash and prepend document root
        $doc_root = $_SERVER['DOCUMENT_ROOT'] ?? '/var/www/html';
        return rtrim($doc_root, '/') . $path;
    }
    
    /**
     * Format file size in human-readable format
     * 
     * @param int $bytes File size in bytes
     * @return string Formatted file size (e.g., "125.3 KB")
     */
    private function format_file_size(int $bytes): string
    {
        $units = ['B', 'KB', 'MB', 'GB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        $bytes /= (1 << (10 * $pow));
        
        return round($bytes, 1) . ' ' . $units[$pow];
    }
    
    /**
     * Determine aspect ratio category
     * 
     * @param int $width Image width
     * @param int $height Image height
     * @return string Category: 'portrait', 'landscape', or 'square'
     */
    private function get_aspect_category(int $width, int $height): string
    {
        $ratio = $width / $height;
        
        // Consider square if ratio is within 5% of 1:1
        if ($ratio >= 0.95 && $ratio <= 1.05) {
            return 'square';
        }
        
        return $ratio > 1 ? 'landscape' : 'portrait';
    }
}
