<?php
/**
 * ============================================================================
 * classes/Media.php - Media Upload and Management Class
 * Handles image and video uploads for groups
 * ============================================================================
 */

namespace App;

use Exception;

class Media {
    private $uploadDir;
    private $allowedImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
    private $allowedVideoTypes = ['video/mp4', 'video/webm', 'video/ogg'];
    private $maxImageSize = 5242880; // 5MB
    private $maxVideoSize = 52428800; // 50MB
    
    public function __construct() {
        $this->uploadDir = __DIR__ . '/../assets/uploads/groups/';
        
        // Create upload directories if they don't exist
        $this->createDirectories();
    }
    
    /**
     * Create necessary upload directories
     */
    private function createDirectories() {
        $dirs = [
            $this->uploadDir,
            $this->uploadDir . 'posts/',
            $this->uploadDir . 'avatars/',
            $this->uploadDir . 'covers/',
            $this->uploadDir . 'videos/'
        ];
        
        foreach ($dirs as $dir) {
            if (!is_dir($dir)) {
                mkdir($dir, 0755, true);
            }
        }
    }
    
    /**
     * Upload multiple images
     */
    public function uploadImages($files, $type = 'posts') {
        $uploadedFiles = [];
        $errors = [];
        
        // Handle both single and multiple file uploads
        if (!isset($files['tmp_name'][0])) {
            // Single file
            $files = [
                'name' => [$files['name']],
                'type' => [$files['type']],
                'tmp_name' => [$files['tmp_name']],
                'error' => [$files['error']],
                'size' => [$files['size']]
            ];
        }
        
        $count = count($files['tmp_name']);
        
        for ($i = 0; $i < $count; $i++) {
            if ($files['error'][$i] === UPLOAD_ERR_OK) {
                $result = $this->uploadSingleImage(
                    $files['tmp_name'][$i],
                    $files['name'][$i],
                    $files['type'][$i],
                    $files['size'][$i],
                    $type
                );
                
                if ($result['success']) {
                    $uploadedFiles[] = $result['url'];
                } else {
                    $errors[] = $result['message'];
                }
            }
        }
        
        return [
            'success' => !empty($uploadedFiles),
            'files' => $uploadedFiles,
            'errors' => $errors
        ];
    }
    
    /**
     * Upload a single image
     */
    private function uploadSingleImage($tmpName, $fileName, $fileType, $fileSize, $type) {
        try {
            // Validate file type
            if (!in_array($fileType, $this->allowedImageTypes)) {
                return ['success' => false, 'message' => 'Invalid file type: ' . $fileName];
            }
            
            // Validate file size
            if ($fileSize > $this->maxImageSize) {
                return ['success' => false, 'message' => 'File too large: ' . $fileName];
            }
            
            // Generate unique filename
            $extension = pathinfo($fileName, PATHINFO_EXTENSION);
            $newFileName = uniqid() . '_' . time() . '.' . $extension;
            $uploadPath = $this->uploadDir . $type . '/' . $newFileName;
            
            // Move uploaded file
            if (move_uploaded_file($tmpName, $uploadPath)) {
                // Optimize image
                $this->optimizeImage($uploadPath, $fileType);
                
                // Return relative URL
                $relativeUrl = 'assets/uploads/groups/' . $type . '/' . $newFileName;
                return ['success' => true, 'url' => $relativeUrl];
            } else {
                return ['success' => false, 'message' => 'Failed to upload: ' . $fileName];
            }
            
        } catch (Exception $e) {
            error_log('Image upload error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Upload error: ' . $fileName];
        }
    }
    
    /**
     * Upload video
     */
    public function uploadVideo($file) {
        try {
            if ($file['error'] !== UPLOAD_ERR_OK) {
                return ['success' => false, 'message' => 'Upload error'];
            }
            
            // Validate file type
            if (!in_array($file['type'], $this->allowedVideoTypes)) {
                return ['success' => false, 'message' => 'Invalid video format. Only MP4, WebM, and OGG are allowed.'];
            }
            
            // Validate file size
            if ($file['size'] > $this->maxVideoSize) {
                return ['success' => false, 'message' => 'Video too large. Maximum size is 50MB.'];
            }
            
            // Generate unique filename
            $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
            $newFileName = uniqid() . '_' . time() . '.' . $extension;
            $uploadPath = $this->uploadDir . 'videos/' . $newFileName;
            
            // Move uploaded file
            if (move_uploaded_file($file['tmp_name'], $uploadPath)) {
                $relativeUrl = 'assets/uploads/groups/videos/' . $newFileName;
                return ['success' => true, 'url' => $relativeUrl];
            } else {
                return ['success' => false, 'message' => 'Failed to upload video'];
            }
            
        } catch (Exception $e) {
            error_log('Video upload error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Video upload failed'];
        }
    }
    
    /**
     * Optimize image (resize if too large)
     */
    private function optimizeImage($filePath, $mimeType) {
        try {
            // Get image dimensions
            list($width, $height) = getimagesize($filePath);
            
            // Only optimize if image is larger than 1920px
            $maxWidth = 1920;
            $maxHeight = 1920;
            
            if ($width <= $maxWidth && $height <= $maxHeight) {
                return true;
            }
            
            // Calculate new dimensions
            $ratio = min($maxWidth / $width, $maxHeight / $height);
            $newWidth = round($width * $ratio);
            $newHeight = round($height * $ratio);
            
            // Create new image
            $newImage = imagecreatetruecolor($newWidth, $newHeight);
            
            // Load source image based on type
            switch ($mimeType) {
                case 'image/jpeg':
                    $source = imagecreatefromjpeg($filePath);
                    break;
                case 'image/png':
                    $source = imagecreatefrompng($filePath);
                    imagealphablending($newImage, false);
                    imagesavealpha($newImage, true);
                    break;
                case 'image/gif':
                    $source = imagecreatefromgif($filePath);
                    break;
                case 'image/webp':
                    $source = imagecreatefromwebp($filePath);
                    break;
                default:
                    return false;
            }
            
            // Resize
            imagecopyresampled($newImage, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
            
            // Save optimized image
            switch ($mimeType) {
                case 'image/jpeg':
                    imagejpeg($newImage, $filePath, 85);
                    break;
                case 'image/png':
                    imagepng($newImage, $filePath, 8);
                    break;
                case 'image/gif':
                    imagegif($newImage, $filePath);
                    break;
                case 'image/webp':
                    imagewebp($newImage, $filePath, 85);
                    break;
            }
            
            // Free memory
            imagedestroy($source);
            imagedestroy($newImage);
            
            return true;
            
        } catch (Exception $e) {
            error_log('Image optimization error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Delete a file
     */
    public function deleteFile($fileUrl) {
        try {
            $filePath = __DIR__ . '/../' . $fileUrl;
            
            if (file_exists($filePath)) {
                unlink($filePath);
                return true;
            }
            
            return false;
            
        } catch (Exception $e) {
            error_log('File deletion error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Delete multiple files
     */
    public function deleteFiles($fileUrls) {
        $deleted = 0;
        
        foreach ($fileUrls as $url) {
            if ($this->deleteFile($url)) {
                $deleted++;
            }
        }
        
        return $deleted;
    }
    
    /**
     * Get file info
     */
    public function getFileInfo($fileUrl) {
        $filePath = __DIR__ . '/../' . $fileUrl;
        
        if (!file_exists($filePath)) {
            return null;
        }
        
        return [
            'size' => filesize($filePath),
            'type' => mime_content_type($filePath),
            'modified' => filemtime($filePath)
        ];
    }
    
    /**
     * Validate image
     */
    public function validateImage($file) {
        $errors = [];
        
        if (!in_array($file['type'], $this->allowedImageTypes)) {
            $errors[] = 'Invalid image type. Allowed: JPG, PNG, GIF, WebP';
        }
        
        if ($file['size'] > $this->maxImageSize) {
            $errors[] = 'Image too large. Maximum size: 5MB';
        }
        
        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }
    
    /**
     * Validate video
     */
    public function validateVideo($file) {
        $errors = [];
        
        if (!in_array($file['type'], $this->allowedVideoTypes)) {
            $errors[] = 'Invalid video type. Allowed: MP4, WebM, OGG';
        }
        
        if ($file['size'] > $this->maxVideoSize) {
            $errors[] = 'Video too large. Maximum size: 50MB';
        }
        
        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }
}