<?php
declare(strict_types=1);

function ensure_dir(string $dir): void { if (!is_dir($dir) && !mkdir($dir,0755,true) && !is_dir($dir)) throw new RuntimeException('No fue posible crear la carpeta de imágenes.'); }
function public_upload_dir(string $publicId): string { return dirname(__DIR__,2) . '/nueva/uploads/memories/' . $publicId; }
function public_upload_url(string $publicId, string $file): string { return base_url('uploads/memories/' . $publicId . '/' . $file); }

function uploaded_image(array $file, string $kind, string $publicId): array {
    if (($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) return [];
    if (($file['error'] ?? 0) !== UPLOAD_ERR_OK) throw new RuntimeException('No fue posible recibir una de las imágenes.');
    $max = $kind === 'avatar' ? (int)cfg('limits.avatar_bytes') : (int)cfg('limits.memory_image_bytes');
    if (($file['size'] ?? 0) > $max) throw new RuntimeException($kind === 'avatar' ? 'El avatar supera 5 MB.' : 'La fotografía supera 10 MB.');
    $finfo = new finfo(FILEINFO_MIME_TYPE); $mime=$finfo->file($file['tmp_name']);
    $allowed=['image/jpeg','image/png','image/webp']; if(!in_array($mime,$allowed,true)) throw new RuntimeException('Solo se aceptan imágenes JPG, PNG o WebP.');
    $dir=public_upload_dir($publicId); ensure_dir($dir);
    if ($kind==='avatar') {
        render_webp($file['tmp_name'],$dir.'/avatar.webp',240,240,true,82);
        return ['avatar_path'=>public_upload_url($publicId,'avatar.webp')];
    }
    render_webp($file['tmp_name'],$dir.'/memory-large.webp',1600,1600,false,84);
    render_webp($file['tmp_name'],$dir.'/memory-thumb.webp',640,480,true,82);
    return ['image_path'=>public_upload_url($publicId,'memory-large.webp'),'image_thumb_path'=>public_upload_url($publicId,'memory-thumb.webp')];
}

function render_webp(string $src,string $dest,int $targetW,int $targetH,bool $crop,int $quality): void {
    if (class_exists('Imagick')) {
        $im=new Imagick($src); $im->autoOrient(); $im->stripImage(); $im->setImageColorspace(Imagick::COLORSPACE_SRGB);
        if ($crop) { $im->cropThumbnailImage($targetW,$targetH); }
        else { $im->thumbnailImage($targetW,$targetH,true,true); }
        $im->setImageFormat('webp'); $im->setImageCompressionQuality($quality); $im->writeImage($dest); $im->clear(); $im->destroy(); return;
    }
    $info=getimagesize($src); if(!$info) throw new RuntimeException('Imagen inválida.');
    [$w,$h]=$info; $mime=$info['mime'];
    $source=match($mime){'image/jpeg'=>imagecreatefromjpeg($src),'image/png'=>imagecreatefrompng($src),'image/webp'=>imagecreatefromwebp($src),default=>false};
    if(!$source) throw new RuntimeException('No fue posible procesar la imagen.');
    if($crop){ $ratio=max($targetW/$w,$targetH/$h); $nw=(int)ceil($w*$ratio);$nh=(int)ceil($h*$ratio);$x=(int)(($nw-$targetW)/2);$y=(int)(($nh-$targetH)/2); $tmp=imagecreatetruecolor($nw,$nh); imagecopyresampled($tmp,$source,0,0,0,0,$nw,$nh,$w,$h); $out=imagecreatetruecolor($targetW,$targetH); imagecopy($out,$tmp,0,0,$x,$y,$targetW,$targetH); imagedestroy($tmp); }
    else { $ratio=min(1,$targetW/$w,$targetH/$h);$nw=(int)round($w*$ratio);$nh=(int)round($h*$ratio);$out=imagecreatetruecolor($nw,$nh);imagecopyresampled($out,$source,0,0,0,0,$nw,$nh,$w,$h); }
    imagewebp($out,$dest,$quality); imagedestroy($out); imagedestroy($source);
}
