<?php
/*******************************************************************************************************************
| Software Name        : EasyStream
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
| Software Author      : (c) Sami Ahmed
|*******************************************************************************************************************
|
|*******************************************************************************************************************
| This source file is subject to the EasyStream Proprietary License Agreement.
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|*******************************************************************************************************************
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|*******************************************************************************************************************/

defined('_ISVALID') or header('Location: /error');

/**
 * Subtitle/Caption Management Class
 *
 * Handles:
 * - Subtitle file uploads (.srt, .vtt)
 * - SRT to VTT conversion
 * - Multiple language tracks
 * - Default subtitle selection
 * - Auto-generated caption integration
 * - Subtitle deletion and management
 */
class VSubtitles
{
    /**
     * Upload subtitle file for a video
     *
     * @param int $file_id File ID
     * @param string $file_type File type (video, short, live, audio)
     * @param array $subtitle_file $_FILES array element
     * @param string $language Language code (en, es, fr, etc.)
     * @param string $label Display label (English, Spanish, etc.)
     * @param bool $is_default Set as default track
     * @return array ['success' => bool, 'message' => string, 'sub_id' => int]
     */
    public static function uploadSubtitle($file_id, $file_type, $subtitle_file, $language = 'en', $label = 'English', $is_default = false)
    {
        global $cfg, $class_database;

        // Get configuration
        $config = $class_database->getConfigurations('subtitles_enabled,subtitles_max_size,subtitles_allowed_formats,subtitles_auto_convert,subtitles_max_per_video,subtitles_require_approval');

        // Check if subtitles are enabled
        if ($config['subtitles_enabled'] != 1) {
            return ['success' => false, 'message' => 'Subtitles are not enabled on this platform'];
        }

        // Validate file upload
        if (!isset($subtitle_file['tmp_name']) || $subtitle_file['error'] !== UPLOAD_ERR_OK) {
            return ['success' => false, 'message' => 'No file uploaded or upload error occurred'];
        }

        // Validate file size
        if ($subtitle_file['size'] > $config['subtitles_max_size']) {
            $max_mb = round($config['subtitles_max_size'] / 1048576, 2);
            return ['success' => false, 'message' => "Subtitle file too large. Maximum size: {$max_mb}MB"];
        }

        // Validate file format
        $file_ext = strtolower(pathinfo($subtitle_file['name'], PATHINFO_EXTENSION));
        $allowed_formats = explode(',', $config['subtitles_allowed_formats']);

        if (!in_array($file_ext, $allowed_formats)) {
            return ['success' => false, 'message' => 'Invalid subtitle format. Allowed: ' . implode(', ', $allowed_formats)];
        }

        // Check subtitle count limit
        $current_count = self::getSubtitleCount($file_id, $file_type);
        if ($current_count >= $config['subtitles_max_per_video']) {
            return ['success' => false, 'message' => "Maximum {$config['subtitles_max_per_video']} subtitle tracks allowed per video"];
        }

        // Get user ID
        $usr_id = isset($_SESSION['USER_ID']) ? (int) $_SESSION['USER_ID'] : 0;
        if ($usr_id == 0) {
            return ['success' => false, 'message' => 'You must be logged in to upload subtitles'];
        }

        // Verify file ownership
        if (!self::verifyFileOwnership($file_id, $file_type, $usr_id)) {
            return ['success' => false, 'message' => 'You do not have permission to add subtitles to this file'];
        }

        // Generate unique filename
        $unique_filename = self::generateSubtitleFilename($file_id, $file_type, $language, $file_ext);
        $subtitle_dir = $cfg['main_dir'] . '/f_data/data_subtitles/';
        $destination = $subtitle_dir . $unique_filename;

        // Ensure directory exists
        if (!file_exists($subtitle_dir)) {
            mkdir($subtitle_dir, 0755, true);
        }

        // Move uploaded file
        if (!move_uploaded_file($subtitle_file['tmp_name'], $destination)) {
            return ['success' => false, 'message' => 'Failed to save subtitle file'];
        }

        // Convert SRT to VTT if needed
        $final_format = $file_ext;
        if ($file_ext === 'srt' && $config['subtitles_auto_convert'] == 1) {
            $vtt_filename = self::convertSrtToVtt($destination, $unique_filename);
            if ($vtt_filename) {
                unlink($destination); // Remove SRT file
                $unique_filename = $vtt_filename;
                $final_format = 'vtt';
            }
        }

        // If this is set as default, unset other defaults
        if ($is_default) {
            self::unsetDefaultSubtitles($file_id, $file_type);
        }

        // Insert into database
        $active = ($config['subtitles_require_approval'] == 1 && !self::isAdmin()) ? 0 : 1;

        $sql = "INSERT INTO `db_subtitles`
                (`file_id`, `file_type`, `usr_id`, `sub_language`, `sub_label`, `sub_filename`,
                 `sub_format`, `sub_kind`, `sub_default`, `sub_filesize`, `active`)
                VALUES (%d, '%s', %d, '%s', '%s', '%s', '%s', 'subtitles', %d, %d, %d)";

        $class_database->doQuery($sql,
            $file_id,
            $class_database->safe_input($file_type),
            $usr_id,
            $class_database->safe_input($language),
            $class_database->safe_input($label),
            $class_database->safe_input($unique_filename),
            $final_format,
            $is_default ? 1 : 0,
            filesize($subtitle_dir . $unique_filename),
            $active
        );

        $sub_id = $class_database->insert_id();

        // Update subtitle count in file table
        self::updateSubtitleCount($file_id, $file_type);

        $message = $active ? 'Subtitle uploaded successfully' : 'Subtitle uploaded and pending approval';

        return ['success' => true, 'message' => $message, 'sub_id' => $sub_id];
    }

    /**
     * Get all subtitles for a file
     *
     * @param int $file_id File ID
     * @param string $file_type File type
     * @param bool $active_only Only return active subtitles
     * @return array Array of subtitle records
     */
    public static function getSubtitles($file_id, $file_type, $active_only = true)
    {
        global $class_database;

        $active_clause = $active_only ? "AND `active` = 1" : "";

        $sql = "SELECT * FROM `db_subtitles`
                WHERE `file_id` = %d AND `file_type` = '%s' $active_clause
                ORDER BY `sub_default` DESC, `sub_language` ASC";

        $result = $class_database->doQuery($sql, $file_id, $class_database->safe_input($file_type));

        $subtitles = [];
        while ($row = $result->fetch_assoc()) {
            $subtitles[] = $row;
        }

        return $subtitles;
    }

    /**
     * Get subtitle track URL for player
     *
     * @param int $file_id File ID
     * @param string $file_type File type
     * @return array Array of subtitle tracks for video player
     */
    public static function getSubtitleTracksForPlayer($file_id, $file_type)
    {
        global $cfg;

        $subtitles = self::getSubtitles($file_id, $file_type, true);
        $tracks = [];

        foreach ($subtitles as $sub) {
            $tracks[] = [
                'kind' => $sub['sub_kind'],
                'label' => $sub['sub_label'],
                'srclang' => $sub['sub_language'],
                'src' => $cfg['main_url'] . '/f_data/data_subtitles/' . $sub['sub_filename'],
                'default' => $sub['sub_default'] == 1
            ];
        }

        return $tracks;
    }

    /**
     * Delete subtitle track
     *
     * @param int $sub_id Subtitle ID
     * @return bool Success
     */
    public static function deleteSubtitle($sub_id)
    {
        global $cfg, $class_database;

        // Get subtitle info
        $sql = "SELECT * FROM `db_subtitles` WHERE `sub_id` = %d LIMIT 1";
        $result = $class_database->doQuery($sql, $sub_id);
        $subtitle = $result->fetch_assoc();

        if (!$subtitle) {
            return false;
        }

        // Verify ownership
        $usr_id = isset($_SESSION['USER_ID']) ? (int) $_SESSION['USER_ID'] : 0;
        if ($subtitle['usr_id'] != $usr_id && !self::isAdmin()) {
            return false;
        }

        // Delete file
        $file_path = $cfg['main_dir'] . '/f_data/data_subtitles/' . $subtitle['sub_filename'];
        if (file_exists($file_path)) {
            unlink($file_path);
        }

        // Delete from database
        $sql = "DELETE FROM `db_subtitles` WHERE `sub_id` = %d";
        $class_database->doQuery($sql, $sub_id);

        // Update count
        self::updateSubtitleCount($subtitle['file_id'], $subtitle['file_type']);

        return true;
    }

    /**
     * Convert SRT to VTT format
     *
     * @param string $srt_path Path to SRT file
     * @param string $original_filename Original filename
     * @return string|false VTT filename or false on failure
     */
    private static function convertSrtToVtt($srt_path, $original_filename)
    {
        global $cfg;

        $srt_content = file_get_contents($srt_path);
        if ($srt_content === false) {
            return false;
        }

        // Add WEBVTT header
        $vtt_content = "WEBVTT\n\n";

        // Convert timestamps from SRT format (00:00:00,000) to VTT format (00:00:00.000)
        $vtt_content .= str_replace(',', '.', $srt_content);

        // Generate VTT filename
        $vtt_filename = str_replace('.srt', '.vtt', $original_filename);
        $vtt_path = $cfg['main_dir'] . '/f_data/data_subtitles/' . $vtt_filename;

        // Write VTT file
        if (file_put_contents($vtt_path, $vtt_content) === false) {
            return false;
        }

        return $vtt_filename;
    }

    /**
     * Generate unique subtitle filename
     */
    private static function generateSubtitleFilename($file_id, $file_type, $language, $ext)
    {
        return $file_type . '_' . $file_id . '_' . $language . '_' . time() . '.' . $ext;
    }

    /**
     * Unset default flag for all other subtitles
     */
    private static function unsetDefaultSubtitles($file_id, $file_type)
    {
        global $class_database;

        $sql = "UPDATE `db_subtitles` SET `sub_default` = 0
                WHERE `file_id` = %d AND `file_type` = '%s'";

        $class_database->doQuery($sql, $file_id, $class_database->safe_input($file_type));
    }

    /**
     * Get subtitle count for a file
     */
    private static function getSubtitleCount($file_id, $file_type)
    {
        global $class_database;

        $sql = "SELECT COUNT(*) as count FROM `db_subtitles`
                WHERE `file_id` = %d AND `file_type` = '%s' AND `active` = 1";

        $result = $class_database->doQuery($sql, $file_id, $class_database->safe_input($file_type));
        $row = $result->fetch_assoc();

        return (int) $row['count'];
    }

    /**
     * Update subtitle count in file table
     */
    private static function updateSubtitleCount($file_id, $file_type)
    {
        global $class_database;

        $count = self::getSubtitleCount($file_id, $file_type);

        $table_map = [
            'video' => 'db_videofiles',
            'short' => 'db_shortfiles',
            'live' => 'db_livefiles',
            'audio' => 'db_audiofiles'
        ];

        if (isset($table_map[$file_type])) {
            $sql = "UPDATE `{$table_map[$file_type]}` SET `subtitle_count` = %d WHERE `db_id` = %d";
            $class_database->doQuery($sql, $count, $file_id);
        }
    }

    /**
     * Verify file ownership
     */
    private static function verifyFileOwnership($file_id, $file_type, $usr_id)
    {
        global $class_database;

        $table_map = [
            'video' => 'db_videofiles',
            'short' => 'db_shortfiles',
            'live' => 'db_livefiles',
            'audio' => 'db_audiofiles'
        ];

        if (!isset($table_map[$file_type])) {
            return false;
        }

        $sql = "SELECT `usr_id` FROM `{$table_map[$file_type]}` WHERE `db_id` = %d LIMIT 1";
        $result = $class_database->doQuery($sql, $file_id);
        $row = $result->fetch_assoc();

        return $row && $row['usr_id'] == $usr_id;
    }

    /**
     * Check if current user is admin
     */
    private static function isAdmin()
    {
        return isset($_SESSION['USER_ADMIN']) && $_SESSION['USER_ADMIN'] == 1;
    }
}
