<?php
class ThumbnailGenerator {
    private $cacheDir;
    private $cacheUrl;
    private $documentRoot;

    public function __construct() {
        // 1. Set up a cache directory
        $this->documentRoot = $_SERVER['DOCUMENT_ROOT'];
        $this->cacheDir = $this->documentRoot . '/cache/og/';
        $this->cacheUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/cache/og/';

        // Create directory if it doesn't exist
        if (!file_exists($this->cacheDir)) {
            mkdir($this->cacheDir, 0755, true);
        }
    }

    /**
     * Resizes and crops an image to fit target dimensions exactly (Center Crop).
     * @param string $sourceUrl The full URL or local path of the original image
     * @param int $width Target width (default 1200 for OG)
     * @param int $height Target height (default 630 for OG)
     * @return string The URL of the processed image
     */
    public function getThumbnail($sourceUrl, $width = 1200, $height = 630) {
        // Generate a unique filename based on source and dimensions
        $ext = 'jpg'; // We force output to JPG for size control
        $hash = md5($sourceUrl);
        $cacheFileName = "{$hash}_{$width}x{$height}.{$ext}";
        $cacheFilePath = $this->cacheDir . $cacheFileName;

        // 1. RETURN CACHED VERSION IF EXISTS
        if (file_exists($cacheFilePath)) {
            return $this->cacheUrl . $cacheFileName;
        }

        // 2. LOCATE LOCAL FILE
        // Convert URL to local path if possible (faster/safer than downloading)
        $localPath = $this->urlToLocalPath($sourceUrl);
        
        if (!$localPath || !file_exists($localPath)) {
            // Fallback: Return original if we can't find it (prevents breaking)
            return $sourceUrl; 
        }

        // 3. PROCESS IMAGE
        try {
            $this->processImage($localPath, $cacheFilePath, $width, $height);
            return $this->cacheUrl . $cacheFileName;
        } catch (Exception $e) {
            // If processing fails, fallback to original
            return $sourceUrl;
        }
    }

    private function urlToLocalPath($url) {
        // Strip the domain to get relative path
        $domain = $_SERVER['HTTP_HOST'];
        $parsed = parse_url($url);
        
        // If it's a relative path already
        if (!isset($parsed['host'])) return $this->documentRoot . '/' . ltrim($url, '/');
        
        // If it matches our domain
        if (strpos($url, $domain) !== false) {
             return $this->documentRoot . $parsed['path'];
        }
        
        return null; // External images not supported in this simplified version
    }

    private function processImage($sourcePath, $destPath, $targetW, $targetH) {
        // Get dimensions and type
        list($srcW, $srcH, $type) = getimagesize($sourcePath);
        
        // Load Source
        switch ($type) {
            case IMAGETYPE_JPEG: $srcImg = imagecreatefromjpeg($sourcePath); break;
            case IMAGETYPE_PNG:  $srcImg = imagecreatefrompng($sourcePath); break;
            case IMAGETYPE_WEBP: $srcImg = imagecreatefromwebp($sourcePath); break;
            default: return; // Unsupported type
        }

        // CALCULATE CENTER CROP
        $srcRatio = $srcW / $srcH;
        $targetRatio = $targetW / $targetH;

        if ($srcRatio > $targetRatio) {
            // Source is wider than target: Crop Left/Right
            $newH = $targetH;
            $newW = $targetH * $srcRatio; // Scale height to match, width overflows
        } else {
            // Source is taller than target: Crop Top/Bottom
            $newW = $targetW;
            $newH = $targetW / $srcRatio; // Scale width to match, height overflows
        }

        // Calculate resize dimensions (The "Virtual" resized image before cropping)
        // We actually do a smart calculation: 
        // 1. Find the smallest multiplier to cover the target area
        $scale = max($targetW / $srcW, $targetH / $srcH);
        $resizeW = ceil($srcW * $scale);
        $resizeH = ceil($srcH * $scale);

        // 2. Calculate offset to center it
        $offsetX = ($resizeW - $targetW) / 2;
        $offsetY = ($resizeH - $targetH) / 2;

        // Create blank canvas
        $destImg = imagecreatetruecolor($targetW, $targetH);
        
        // Handle transparency for PNGs (converted to white background for JPG)
        $white = imagecolorallocate($destImg, 255, 255, 255);
        imagefilledrectangle($destImg, 0, 0, $targetW, $targetH, $white);

        // Resample (Resize + Crop)
        // dst_image, src_image, dst_x, dst_y, src_x, src_y, dst_w, dst_h, src_w, src_h
        // We copy the WHOLE source into the Resized Virtual area, but map it to negative offsets
        imagecopyresampled($destImg, $srcImg, -$offsetX, -$offsetY, 0, 0, $resizeW, $resizeH, $srcW, $srcH);

        // Save as optimized JPEG (Quality 75 is the sweet spot for < 300KB)
        imagejpeg($destImg, $destPath, 75);

        // Cleanup
        imagedestroy($srcImg);
        imagedestroy($destImg);
    }
}
?>