<?php
/*******************************************************************************************************************
| Enhanced Video Processing Job
| Handles video transcoding and processing in the background with VVideoProcessor
|*******************************************************************************************************************/

class VideoProcessingJob extends BaseJob
{
    private $videoProcessor;
    
    public function __construct()
    {
        parent::__construct();
        $this->videoProcessor = new VVideoProcessor();
    }
    
    /**
     * Handle video processing using VVideoProcessor
     * @param array $data Video processing data
     * @return array Processing result
     */
    public function handle($data)
    {
        $this->validateData($data, ['video_key', 'input_file']);
        
        $videoKey = $data['video_key'];
        $inputFile = $data['input_file'];
        $options = [
            'formats' => $data['formats'] ?? ['1080p', '720p', '480p', '360p'],
            'generate_preview' => $data['generate_preview'] ?? true,
            'generate_hls' => $data['generate_hls'] ?? true
        ];
        
        $this->logProgress('Starting video processing', [
            'video_key' => $videoKey,
            'input_file' => $inputFile,
            'options' => $options
        ]);
        
        try {
            // Process video using enhanced VVideoProcessor
            $result = $this->videoProcessor->processVideo($inputFile, $videoKey, $options);
            
            if ($result['success']) {
                $this->logProgress('Video processing completed successfully', [
                    'video_key' => $videoKey,
                    'formats_processed' => array_keys($result['results']),
                    'video_info' => $result['video_info']
                ]);
                
                // Send success notification to user
                $this->sendUserNotification($videoKey, 'processing_completed', $result);
                
                return $result;
            } else {
                throw new Exception($result['error'] ?? 'Video processing failed');
            }
            
        } catch (Exception $e) {
            $this->logError('Video processing failed', [
                'video_key' => $videoKey,
                'error' => $e->getMessage()
            ]);
            
            // Send failure notification to user
            $this->sendUserNotification($videoKey, 'processing_failed', ['error' => $e->getMessage()]);
            
            throw $e;
        }
    }
    
    /**
     * Process video to specific format
     * @param string $inputFile Input file path
     * @param string $outputDir Output directory
     * @param string $format Format (720p, 480p, etc.)
     * @param string $videoId Video ID
     * @return array Processing result
     */
    private function processVideoFormat($inputFile, $outputDir, $format, $videoId)
    {
        $outputFile = $outputDir . '/' . $videoId . '_' . $format . '.mp4';
        
        // Define format settings
        $formatSettings = [
            '1080p' => ['width' => 1920, 'height' => 1080, 'bitrate' => '5000k'],
            '720p'  => ['width' => 1280, 'height' => 720,  'bitrate' => '2500k'],
            '480p'  => ['width' => 854,  'height' => 480,  'bitrate' => '1000k'],
            '360p'  => ['width' => 640,  'height' => 360,  'bitrate' => '750k'],
            '240p'  => ['width' => 426,  'height' => 240,  'bitrate' => '400k']
        ];
        
        if (!isset($formatSettings[$format])) {
            return [
                'success' => false,
                'error' => "Unknown format: {$format}",
                'output_file' => null
            ];
        }
        
        $settings = $formatSettings[$format];
        
        // Build FFmpeg command
        $ffmpegCmd = sprintf(
            'ffmpeg -i %s -vf "scale=%d:%d:force_original_aspect_ratio=decrease,pad=%d:%d:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -b:v %s -c:a aac -b:a 128k -movflags +faststart %s 2>&1',
            escapeshellarg($inputFile),
            $settings['width'],
            $settings['height'],
            $settings['width'],
            $settings['height'],
            $settings['bitrate'],
            escapeshellarg($outputFile)
        );
        
        $this->logProgress("Executing FFmpeg for {$format}", [
            'command' => $ffmpegCmd,
            'output_file' => $outputFile
        ]);
        
        // Execute FFmpeg
        $output = [];
        $returnCode = 0;
        exec($ffmpegCmd, $output, $returnCode);
        
        if ($returnCode === 0 && file_exists($outputFile)) {
            return [
                'success' => true,
                'output_file' => $outputFile,
                'file_size' => filesize($outputFile),
                'format' => $format
            ];
        } else {
            return [
                'success' => false,
                'error' => 'FFmpeg processing failed',
                'return_code' => $returnCode,
                'output' => implode("\n", $output),
                'output_file' => $outputFile
            ];
        }
    }
    
    /**
     * Generate video thumbnail
     * @param string $inputFile Input file path
     * @param string $outputDir Output directory
     * @param string $videoId Video ID
     * @return array Generation result
     */
    private function generateThumbnail($inputFile, $outputDir, $videoId)
    {
        $thumbnailFile = $outputDir . '/' . $videoId . '_thumb.jpg';
        
        // Generate thumbnail at 10% of video duration
        $ffmpegCmd = sprintf(
            'ffmpeg -i %s -ss 00:00:10 -vframes 1 -vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" %s 2>&1',
            escapeshellarg($inputFile),
            escapeshellarg($thumbnailFile)
        );
        
        $output = [];
        $returnCode = 0;
        exec($ffmpegCmd, $output, $returnCode);
        
        if ($returnCode === 0 && file_exists($thumbnailFile)) {
            return [
                'success' => true,
                'thumbnail_file' => $thumbnailFile,
                'file_size' => filesize($thumbnailFile)
            ];
        } else {
            return [
                'success' => false,
                'error' => 'Thumbnail generation failed',
                'return_code' => $returnCode,
                'output' => implode("\n", $output)
            ];
        }
    }
    
    /**
     * Send notification to user about processing status
     * @param string $videoKey Video key
     * @param string $type Notification type
     * @param array $data Additional data
     */
    private function sendUserNotification($videoKey, $type, $data = [])
    {
        try {
            // Get video and user information
            $db = $this->getDatabase();
            $query = "SELECT vf.*, au.usr_user, au.usr_email 
                      FROM db_videofiles vf 
                      JOIN db_accountuser au ON vf.usr_id = au.usr_id 
                      WHERE vf.file_key = ?";
            $result = $db->doQuery($query, [$videoKey]);
            $video = $db->doFetch($result);
            
            if (!$video) {
                return;
            }
            
            // Create notification
            $notification = [
                'user_id' => $video['usr_id'],
                'type' => 'video_' . $type,
                'title' => $this->getNotificationTitle($type),
                'message' => $this->getNotificationMessage($type, $video['file_title']),
                'data' => json_encode([
                    'video_key' => $videoKey,
                    'video_title' => $video['file_title'],
                    'processing_data' => $data
                ]),
                'created_at' => date('Y-m-d H:i:s'),
                'read_status' => 0
            ];
            
            $db->doInsert('db_notifications', $notification);
            
            $this->logProgress('User notification sent', [
                'video_key' => $videoKey,
                'user_id' => $video['usr_id'],
                'type' => $type
            ]);
            
        } catch (Exception $e) {
            $this->logError('Failed to send user notification', [
                'video_key' => $videoKey,
                'type' => $type,
                'error' => $e->getMessage()
            ]);
        }
    }
    
    /**
     * Get notification title based on type
     * @param string $type Notification type
     * @return string Title
     */
    private function getNotificationTitle($type)
    {
        switch ($type) {
            case 'processing_completed':
                return 'Video Processing Complete';
            case 'processing_failed':
                return 'Video Processing Failed';
            default:
                return 'Video Update';
        }
    }
    
    /**
     * Get notification message based on type
     * @param string $type Notification type
     * @param string $videoTitle Video title
     * @return string Message
     */
    private function getNotificationMessage($type, $videoTitle)
    {
        switch ($type) {
            case 'processing_completed':
                return "Your video '{$videoTitle}' has been processed successfully and is now available for viewing.";
            case 'processing_failed':
                return "Processing failed for your video '{$videoTitle}'. Please try uploading again or contact support.";
            default:
                return "Update for your video '{$videoTitle}'.";
        }
    }
}