<?php
/**
 * Subtitle extraction API for Main VPS (Web Version)
 * This version calls the CLI service instead of using shell_exec
 * Place this file in the web root of each main VPS as /api/subtitle.php
 */

// Include shared configuration
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/PersianNormalizer.php';

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// Main execution
try {
    $action = $_GET['action'] ?? '';
    $file = $_GET['file'] ?? '';
    
    if (empty($file)) {
        throw new Exception('File parameter is required');
    }
    
    if (!validatePath($file)) {
        throw new Exception('Invalid file path or security violation');
    }
    
    $fullPath = $BASE_PATH . $file;
    
    if (!file_exists($fullPath)) {
        throw new Exception('File not found: ' . $file);
    }
    
    switch ($action) {
        case 'list':
            header('Content-Type: application/json');
            
            // Check if cached tracks are available and valid
            $tracks = getCachedSubtitleTracks($file);
            if ($tracks !== null) {
                echo json_encode([
                    'success' => true,
                    'tracks' => $tracks,
                    'count' => count($tracks),
                    'cached' => true
                ]);
                break;
            }
            
            // Extract tracks fresh and cache them
            $tracks = getSubtitleTracksWithCache($file);
            
            echo json_encode([
                'success' => true,
                'tracks' => $tracks,
                'count' => count($tracks),
                'cached' => false
            ]);
            break;
            
        case 'extract':
            $trackIndex = intval($_GET['track'] ?? 0);
            $format = $_GET['format'] ?? 'vtt';
            
            $content = null;
            
            // Check if cached content is available and valid
            $content = getCachedSubtitleContent($file, $trackIndex, $format);
            
            // If no cached content, extract fresh
            if ($content === null) {
                $content = extractSubtitleWithMKVExtract($fullPath, $trackIndex, $format);
            }
            
            if (!$content) {
                throw new Exception('Failed to extract subtitle');
            }
            
            header('Content-Type: text/' . $format);
            header('Cache-Control: public, max-age=3600');
            echo $content;
            break;
            
        default:
            throw new Exception('Invalid action. Use "list" or "extract"');
    }
    
} catch (Exception $e) {
    http_response_code(400);
    header('Content-Type: application/json');
    echo json_encode([
        'error' => $e->getMessage(),
        'success' => false
    ]);
}

/**
 * Get subtitle tracks using mkvmerge JSON output with ffprobe fallback
 */
function getSubtitleTracksWithMKVMerge($videoPath) {
    if (!function_exists('shell_exec')) {
        return [];
    }
    
    $escapedPath = escapeshellarg($videoPath);
    
    // First, try mkvmerge -J
    $tempDir = __DIR__ . '/temp';
    if (!is_dir($tempDir)) {
        if (!mkdir($tempDir, 0755, true)) {
            $tempDir = __DIR__;
        }
    }
    
    $tempFile = $tempDir . '/' . uniqid('mkvinfo_') . '.json';
    $escapedTempFile = escapeshellarg($tempFile);
    
    // Use mkvmerge to get subtitle tracks
    $escapedPath = escapeshellarg($videoPath);
    $command = "export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; mkvmerge --output-charset 'UTF-8' -J $escapedPath";
    $output = shell_exec($command);
    $mkvWorked = false;
    
    if ($output) {
        // Check if we got valid JSON
        $testData = json_decode($output, true);
        if ($testData && isset($testData['tracks'])) {
            $mkvWorked = true;
        }
    }
    
    // Fallback to ffprobe if mkvmerge failed
    if (!$mkvWorked) {
        error_log("Falling back to ffprobe");
        return getSubtitleTracksWithFFProbe($videoPath);
    }
    
    $data = json_decode($output, true);
    $tracks = [];
    $subtitleTrackIndex = 0;
    
    foreach ($data['tracks'] as $track) {
        // Only process subtitle tracks
        if ($track['type'] !== 'subtitles') {
            continue;
        }
        
        $trackId = $track['id'];
        $codec = $track['codec'] ?? 'unknown';
        
        // Get language from properties
        $language = 'unknown';
        if (isset($track['properties']['language'])) {
            $language = $track['properties']['language'];
        }
        
        // Get track name/title
        $title = "Subtitle Track $subtitleTrackIndex";
        if (isset($track['properties']['track_name'])) {
            $title = $track['properties']['track_name'];
        } elseif (isset($track['properties']['language']) && $track['properties']['language'] !== 'und') {
            $title = "Subtitle Track $subtitleTrackIndex (" . strtoupper($track['properties']['language']) . ")";
        }
        
        // Get additional properties
        $isDefault = isset($track['properties']['default_track']) ? (bool)$track['properties']['default_track'] : false;
        $isForced = isset($track['properties']['forced_track']) ? (bool)$track['properties']['forced_track'] : false;
        
        $tracks[] = [
            'index' => $subtitleTrackIndex,  // Frontend-friendly sequential index
            'mkvTrackId' => $trackId,        // Actual track ID for mkvextract
            'codec' => $codec,
            'language' => $language,
            'title' => $title,
            'isDefault' => $isDefault,
            'isForced' => $isForced
        ];
        
        $subtitleTrackIndex++;
    }
    
    return $tracks;
}

/**
 * Fallback: Get subtitle tracks using ffprobe
 */
function getSubtitleTracksWithFFProbe($videoPath) {
    if (!function_exists('shell_exec')) {
        return [];
    }
    
    $escapedPath = escapeshellarg($videoPath);
    $command = "ffprobe -v quiet -print_format json -show_streams -select_streams s $escapedPath 2>/dev/null";
    $output = shell_exec($command);
    if (!$output) {
        return [];
    }
    
    $data = json_decode($output, true);
    if (!$data || !isset($data['streams'])) {
        return [];
    }
    
    $tracks = [];
    foreach ($data['streams'] as $index => $stream) {
        $tracks[] = [
            'index' => $index,  // Sequential index for frontend
            'mkvTrackId' => $stream['index'],  // Actual track ID
            'codec' => $stream['codec_name'] ?? 'unknown',
            'language' => $stream['tags']['language'] ?? 'unknown',
            'title' => $stream['tags']['title'] ?? "Subtitle Track $index",
            'isDefault' => false,
            'isForced' => false
        ];
    }
    
    return $tracks;
}

/**
 * Extract subtitle using mkvextract + ffmpeg (no modifications to content)
 */
function extractSubtitleWithMKVExtract($videoPath, $frontendTrackIndex = 0, $format = 'vtt') {
    if (!function_exists('shell_exec')) {
        return null;
    }
    
    // First, get the track list to map frontend index to actual track ID
    $tracks = getSubtitleTracksWithMKVMerge($videoPath);
    if (empty($tracks) || !isset($tracks[$frontendTrackIndex])) {
        return null;
    }
    
    // Get the actual track ID for mkvextract
    $actualTrackId = $tracks[$frontendTrackIndex]['mkvTrackId'];
    
    $escapedPath = escapeshellarg($videoPath);
    
    // Use web-accessible temp directory instead of /tmp
    $tempDir = __DIR__ . '/temp';
    if (!is_dir($tempDir)) {
        if (!mkdir($tempDir, 0755, true)) {
            // Fallback to current directory if temp creation fails
            $tempDir = __DIR__;
        }
    }
    
    // Step 1: Extract original subtitle with mkvextract using actual track ID
    $originalFile = $tempDir . '/' . uniqid('sub_orig_');
    $escapedOriginalFile = escapeshellarg($originalFile);
    
    $extractCommand = "mkvextract tracks $escapedPath $actualTrackId:$escapedOriginalFile 2>/dev/null";
    echo $extractCommand . PHP_EOL;
    shell_exec($extractCommand);
    
    if (!file_exists($originalFile)) {
        return null;
    }
    
    // Step 2: Convert to requested format with ffmpeg
    $finalFile = $tempDir . '/' . uniqid('sub_final_') . '.' . $format;
    $escapedFinalFile = escapeshellarg($finalFile);
    
    // Handle ASS format conversion with vazirmatn rd extrabold font
    if ($format === 'ass') {
        // Convert to ASS with proper subtitle codec
        $convertCommand = "ffmpeg -i $escapedOriginalFile -c:s ass $escapedFinalFile -y 2>/dev/null";
        shell_exec($convertCommand);
        
        // Post-process to set vazirmatn rd extrabold font in ASS structure
        if (file_exists($finalFile)) {
            $assContent = file_get_contents($finalFile);
            
            // Set vazirmatn rd extrabold font in ASS style definitions
            if (strpos($assContent, '[V4+ Styles]') !== false || strpos($assContent, '[V4 Styles]') !== false) {
                // Find and modify the Default style to use vazirmatn rd extrabold font
                $assContent = preg_replace(
                    '/Style: Default,([^,]*),(\d+),/',
                    'Style: Default,Vazirmatn RD ExtraBold,23,',
                    $assContent
                );

                // If no Default style found, ensure any style uses vazirmatn rd extrabold as font
                if (strpos($assContent, 'Vazirmatn RD ExtraBold') === false) {
                    // Replace the font name in any Style line
                    $assContent = preg_replace(
                        '/Style: ([^,]*),([^,]*),(\d+),/',
                        'Style: $1,Vazirmatn RD ExtraBold,23,',
                        $assContent
                    );
                }
                
                // Sanitize ASS content (replace aiofilm with MixFlixTop)
                $assContent = processSubtitleContent($assContent);
                
                file_put_contents($finalFile, $assContent);
                error_log("ASS conversion completed - Vazir font set in style definitions");
            } else {
                error_log("ASS file created but no style section found for font modification");
            }
        } else {
            error_log("FFmpeg ASS conversion failed for: $originalFile");
        }
    } else {
        // Map format to FFmpeg codec for other formats
        $codec = ($format === 'vtt') ? 'webvtt' : $format;
        $convertCommand = "ffmpeg -i $escapedOriginalFile -c:s $codec $escapedFinalFile -y 2>/dev/null";
        shell_exec($convertCommand);
    }
    
    // Clean up original file
    unlink($originalFile);
    
    if (file_exists($finalFile)) {
        $content = file_get_contents($finalFile);
        unlink($finalFile); // Clean up
        
        // Process subtitle content (normalize + sanitize) - unified function handles both
        return processSubtitleContent($content);
    }
    }
    
    return null;
?>