<?php
/**
 * Videos API Endpoint
 * Handles all video-related operations
 *
 * Supported Actions:
 * - GET list: List videos with pagination and filters
 * - GET single: Get single video details
 * - POST create: Create/upload new video
 * - PUT update: Update video details
 * - DELETE delete: Delete video
 * - POST like: Like/unlike video
 * - POST view: Increment view count
 */

// Include CORS configuration
require_once __DIR__ . '/cors.config.php';

header('Content-Type: application/json');

// Include core configuration
require_once dirname(__FILE__) . '/../f_core/config.core.php';

// Initialize response
$response = ['success' => false, 'data' => null, 'error' => null];

try {
    // Get action from query parameter
    $action = isset($_GET['action']) ? $_GET['action'] : null;
    $method = $_SERVER['REQUEST_METHOD'];

    // Get authenticated user (supports both session and JWT)
    $userId = null;

    // Try JWT authentication first
    $authHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] :
                 (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : null);

    if ($authHeader && preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
        $token = $matches[1];
        $tokenData = VAuth::verifyToken($token);
        if ($tokenData && isset($tokenData['user_id'])) {
            $userId = $tokenData['user_id'];
        }
    }

    // Fall back to session authentication
    if (!$userId && isset($_SESSION['USER_ID'])) {
        $userId = $_SESSION['USER_ID'];
    } elseif (!$userId && isset($_SESSION['usr_id'])) {
        $userId = $_SESSION['usr_id'];
    }

    // Route based on method and action
    switch ($method) {
        case 'GET':
            if (isset($_GET['id'])) {
                // Get single video
                handleGetVideo($_GET['id'], $userId);
            } elseif ($action === 'search') {
                // Search videos
                handleSearchVideos($userId);
            } else {
                // List videos
                handleListVideos($userId);
            }
            break;

        case 'POST':
            if (!$userId) {
                throw new Exception('Authentication required', 401);
            }

            switch ($action) {
                case 'create':
                case 'upload':
                    handleCreateVideo($userId);
                    break;
                case 'like':
                    handleLikeVideo($userId);
                    break;
                case 'view':
                    handleIncrementView($userId);
                    break;
                case 'watch_later':
                    handleWatchLater($userId);
                    break;
                default:
                    throw new Exception('Invalid action', 400);
            }
            break;

        case 'PUT':
            if (!$userId) {
                throw new Exception('Authentication required', 401);
            }
            handleUpdateVideo($userId);
            break;

        case 'DELETE':
            if (!$userId) {
                throw new Exception('Authentication required', 401);
            }
            handleDeleteVideo($userId);
            break;

        default:
            throw new Exception('Method not allowed', 405);
    }

} catch (Exception $e) {
    http_response_code($e->getCode() >= 400 && $e->getCode() < 600 ? $e->getCode() : 500);
    $response['error'] = $e->getMessage();
    echo json_encode($response);
    exit;
}

/**
 * List videos with pagination and filters
 */
function handleListVideos($userId) {
    global $class_database, $response;

    // Get pagination parameters
    $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
    $limit = isset($_GET['limit']) ? min(100, max(1, (int)$_GET['limit'])) : 20;
    $offset = ($page - 1) * $limit;

    // Get filter parameters
    $category = isset($_GET['category']) ? VSecurity::sanitize($_GET['category']) : null;
    $sort = isset($_GET['sort']) ? $_GET['sort'] : 'recent';
    $channelId = isset($_GET['channel_id']) ? (int)$_GET['channel_id'] : null;

    // Build WHERE clause
    $where = ["v.approved = 1"];
    $params = [];

    if ($category) {
        $where[] = "v.file_category = ?";
        $params[] = $category;
    }

    if ($channelId) {
        $where[] = "v.usr_id = ?";
        $params[] = $channelId;
    }

    // Add privacy filter (only show public videos unless it's the owner)
    if ($userId) {
        $where[] = "(v.privacy = 'public' OR v.usr_id = ?)";
        $params[] = $userId;
    } else {
        $where[] = "v.privacy = 'public'";
    }

    $whereClause = implode(' AND ', $where);

    // Build ORDER BY clause
    $orderBy = match($sort) {
        'popular' => 'v.file_views DESC',
        'featured' => 'v.featured DESC, v.file_views DESC',
        'recent' => 'v.upload_date DESC',
        'oldest' => 'v.upload_date ASC',
        'title' => 'v.file_title ASC',
        default => 'v.upload_date DESC'
    };

    // Get total count
    $countSql = "SELECT COUNT(*) FROM db_videofiles v WHERE $whereClause";
    $total = (int)$class_database->singleFieldValue($countSql, $params);

    // Get videos
    $sql = "SELECT v.file_key, v.file_title, v.file_description, v.file_name,
                   v.file_duration, v.file_views, v.privacy, v.upload_date,
                   v.thumbnail, v.featured, v.file_category,
                   u.usr_id, u.usr_user, u.usr_dname,
                   (SELECT COUNT(*) FROM db_likes WHERE file_key = v.file_key AND like_type = 'like') as like_count,
                   (SELECT COUNT(*) FROM db_comments WHERE file_key = v.file_key) as comment_count
            FROM db_videofiles v
            LEFT JOIN db_users u ON v.usr_id = u.usr_id
            WHERE $whereClause
            ORDER BY $orderBy
            LIMIT ? OFFSET ?";

    $params[] = $limit;
    $params[] = $offset;

    $videos = $class_database->execute($sql, $params);

    // Format response
    $response['success'] = true;
    $response['data'] = [
        'videos' => $videos ? $videos->GetArray() : [],
        'pagination' => [
            'page' => $page,
            'limit' => $limit,
            'total' => $total,
            'pages' => ceil($total / $limit)
        ]
    ];

    echo json_encode($response);
}

/**
 * Get single video details
 */
function handleGetVideo($fileKey, $userId) {
    global $class_database, $response;

    $sql = "SELECT v.*,
                   u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar,
                   (SELECT COUNT(*) FROM db_likes WHERE file_key = v.file_key AND like_type = 'like') as like_count,
                   (SELECT COUNT(*) FROM db_likes WHERE file_key = v.file_key AND like_type = 'dislike') as dislike_count,
                   (SELECT COUNT(*) FROM db_comments WHERE file_key = v.file_key) as comment_count,
                   (SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = v.usr_id) as subscriber_count
            FROM db_videofiles v
            LEFT JOIN db_users u ON v.usr_id = u.usr_id
            WHERE v.file_key = ?";

    $result = $class_database->execute($sql, [$fileKey]);

    if (!$result || $result->RecordCount() === 0) {
        throw new Exception('Video not found', 404);
    }

    $video = $result->fields;

    // Check privacy
    if ($video['privacy'] !== 'public' && (!$userId || $userId != $video['usr_id'])) {
        throw new Exception('Video not available', 403);
    }

    // Check if user liked/disliked
    if ($userId) {
        $likeSql = "SELECT like_type FROM db_likes WHERE file_key = ? AND usr_id = ?";
        $likeResult = $class_database->execute($likeSql, [$fileKey, $userId]);
        $video['user_like_status'] = $likeResult && $likeResult->RecordCount() > 0 ? $likeResult->fields['like_type'] : null;

        // Check if subscribed to channel
        $subSql = "SELECT 1 FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
        $subResult = $class_database->execute($subSql, [$userId, $video['usr_id']]);
        $video['user_subscribed'] = $subResult && $subResult->RecordCount() > 0;
    }

    $response['success'] = true;
    $response['data'] = $video;

    echo json_encode($response);
}

/**
 * Search videos
 */
function handleSearchVideos($userId) {
    global $class_database, $response;

    $query = isset($_GET['q']) ? VSecurity::sanitize($_GET['q']) : '';

    if (strlen($query) < 2) {
        throw new Exception('Search query must be at least 2 characters', 400);
    }

    $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
    $limit = isset($_GET['limit']) ? min(100, max(1, (int)$_GET['limit'])) : 20;
    $offset = ($page - 1) * $limit;

    $searchTerm = '%' . $query . '%';

    $where = "(v.file_title LIKE ? OR v.file_description LIKE ? OR v.file_tags LIKE ?)";
    if ($userId) {
        $where .= " AND (v.privacy = 'public' OR v.usr_id = ?)";
        $params = [$searchTerm, $searchTerm, $searchTerm, $userId];
    } else {
        $where .= " AND v.privacy = 'public'";
        $params = [$searchTerm, $searchTerm, $searchTerm];
    }

    // Get total count
    $countSql = "SELECT COUNT(*) FROM db_videofiles v WHERE v.approved = 1 AND $where";
    $total = (int)$class_database->singleFieldValue($countSql, $params);

    // Get results
    $sql = "SELECT v.file_key, v.file_title, v.file_description, v.file_duration,
                   v.file_views, v.upload_date, v.thumbnail,
                   u.usr_id, u.usr_user, u.usr_dname
            FROM db_videofiles v
            LEFT JOIN db_users u ON v.usr_id = u.usr_id
            WHERE v.approved = 1 AND $where
            ORDER BY v.file_views DESC, v.upload_date DESC
            LIMIT ? OFFSET ?";

    $params[] = $limit;
    $params[] = $offset;

    $videos = $class_database->execute($sql, $params);

    $response['success'] = true;
    $response['data'] = [
        'videos' => $videos ? $videos->GetArray() : [],
        'query' => $query,
        'pagination' => [
            'page' => $page,
            'limit' => $limit,
            'total' => $total,
            'pages' => ceil($total / $limit)
        ]
    ];

    echo json_encode($response);
}

/**
 * Create/upload new video
 */
function handleCreateVideo($userId) {
    global $class_database, $response;

    // Get JSON input
    $input = json_decode(file_get_contents('php://input'), true);

    if (!$input) {
        throw new Exception('Invalid JSON input', 400);
    }

    // Validate required fields
    $title = isset($input['title']) ? VSecurity::sanitize($input['title']) : null;
    $description = isset($input['description']) ? VSecurity::sanitize($input['description']) : '';

    if (!$title) {
        throw new Exception('Title is required', 400);
    }

    // Generate file key
    $fileKey = rand(100000, 999999);

    // Get optional fields
    $privacy = isset($input['privacy']) ? $input['privacy'] : 'public';
    $category = isset($input['category']) ? VSecurity::sanitize($input['category']) : null;
    $tags = isset($input['tags']) ? VSecurity::sanitize($input['tags']) : null;

    // Insert video record
    $sql = "INSERT INTO db_videofiles (usr_id, file_key, file_type, file_title, file_description,
                                       privacy, file_category, file_tags, upload_date, approved, file_views)
            VALUES (?, ?, 'video', ?, ?, ?, ?, ?, NOW(), 1, 0)";

    $result = $class_database->execute($sql, [
        $userId, $fileKey, $title, $description, $privacy, $category, $tags
    ]);

    if (!$result) {
        throw new Exception('Failed to create video', 500);
    }

    $response['success'] = true;
    $response['data'] = [
        'file_key' => $fileKey,
        'message' => 'Video created successfully'
    ];

    echo json_encode($response);
}

/**
 * Update video details
 */
function handleUpdateVideo($userId) {
    global $class_database, $response;

    $fileKey = isset($_GET['id']) ? $_GET['id'] : null;

    if (!$fileKey) {
        throw new Exception('Video ID is required', 400);
    }

    // Verify ownership
    $checkSql = "SELECT usr_id FROM db_videofiles WHERE file_key = ?";
    $checkResult = $class_database->execute($checkSql, [$fileKey]);

    if (!$checkResult || $checkResult->RecordCount() === 0) {
        throw new Exception('Video not found', 404);
    }

    if ($checkResult->fields['usr_id'] != $userId) {
        throw new Exception('You do not have permission to edit this video', 403);
    }

    // Get JSON input
    $input = json_decode(file_get_contents('php://input'), true);

    if (!$input) {
        throw new Exception('Invalid JSON input', 400);
    }

    // Build update query dynamically
    $updates = [];
    $params = [];

    $allowedFields = ['file_title', 'file_description', 'privacy', 'file_category', 'file_tags', 'thumbnail'];

    foreach ($allowedFields as $field) {
        if (isset($input[$field])) {
            $updates[] = "$field = ?";
            $params[] = VSecurity::sanitize($input[$field]);
        }
    }

    if (empty($updates)) {
        throw new Exception('No fields to update', 400);
    }

    $params[] = $fileKey;

    $sql = "UPDATE db_videofiles SET " . implode(', ', $updates) . " WHERE file_key = ?";
    $result = $class_database->execute($sql, $params);

    if (!$result) {
        throw new Exception('Failed to update video', 500);
    }

    $response['success'] = true;
    $response['data'] = ['message' => 'Video updated successfully'];

    echo json_encode($response);
}

/**
 * Delete video
 */
function handleDeleteVideo($userId) {
    global $class_database, $response;

    $fileKey = isset($_GET['id']) ? $_GET['id'] : null;

    if (!$fileKey) {
        throw new Exception('Video ID is required', 400);
    }

    // Verify ownership
    $checkSql = "SELECT usr_id, file_name FROM db_videofiles WHERE file_key = ?";
    $checkResult = $class_database->execute($checkSql, [$fileKey]);

    if (!$checkResult || $checkResult->RecordCount() === 0) {
        throw new Exception('Video not found', 404);
    }

    if ($checkResult->fields['usr_id'] != $userId) {
        throw new Exception('You do not have permission to delete this video', 403);
    }

    // Delete video record
    $sql = "DELETE FROM db_videofiles WHERE file_key = ?";
    $result = $class_database->execute($sql, [$fileKey]);

    if (!$result) {
        throw new Exception('Failed to delete video', 500);
    }

    // TODO: Delete associated files from storage

    $response['success'] = true;
    $response['data'] = ['message' => 'Video deleted successfully'];

    echo json_encode($response);
}

/**
 * Like/unlike video
 */
function handleLikeVideo($userId) {
    global $class_database, $response;

    $input = json_decode(file_get_contents('php://input'), true);
    $fileKey = isset($input['file_key']) ? $input['file_key'] : null;
    $likeType = isset($input['like_type']) ? $input['like_type'] : 'like'; // 'like' or 'dislike'

    if (!$fileKey) {
        throw new Exception('Video ID is required', 400);
    }

    // Check if already liked
    $checkSql = "SELECT like_id, like_type FROM db_likes WHERE file_key = ? AND usr_id = ?";
    $existing = $class_database->execute($checkSql, [$fileKey, $userId]);

    if ($existing && $existing->RecordCount() > 0) {
        if ($existing->fields['like_type'] === $likeType) {
            // Remove like/dislike
            $sql = "DELETE FROM db_likes WHERE file_key = ? AND usr_id = ?";
            $class_database->execute($sql, [$fileKey, $userId]);
            $action = 'removed';
        } else {
            // Change like to dislike or vice versa
            $sql = "UPDATE db_likes SET like_type = ? WHERE file_key = ? AND usr_id = ?";
            $class_database->execute($sql, [$likeType, $fileKey, $userId]);
            $action = 'updated';
        }
    } else {
        // Add new like/dislike
        $sql = "INSERT INTO db_likes (file_key, usr_id, like_type, like_date) VALUES (?, ?, ?, NOW())";
        $class_database->execute($sql, [$fileKey, $userId, $likeType]);
        $action = 'added';
    }

    // Get updated counts
    $countSql = "SELECT
                    SUM(CASE WHEN like_type = 'like' THEN 1 ELSE 0 END) as like_count,
                    SUM(CASE WHEN like_type = 'dislike' THEN 1 ELSE 0 END) as dislike_count
                 FROM db_likes WHERE file_key = ?";
    $counts = $class_database->execute($countSql, [$fileKey]);

    $response['success'] = true;
    $response['data'] = [
        'action' => $action,
        'like_count' => $counts->fields['like_count'] ?? 0,
        'dislike_count' => $counts->fields['dislike_count'] ?? 0
    ];

    echo json_encode($response);
}

/**
 * Increment view count
 */
function handleIncrementView($userId) {
    global $class_database, $response;

    $input = json_decode(file_get_contents('php://input'), true);
    $fileKey = isset($input['file_key']) ? $input['file_key'] : null;

    if (!$fileKey) {
        throw new Exception('Video ID is required', 400);
    }

    // Update view count
    $sql = "UPDATE db_videofiles SET file_views = file_views + 1 WHERE file_key = ?";
    $class_database->execute($sql, [$fileKey]);

    // Log view in activity table if it exists
    $activitySql = "INSERT INTO db_user_activity (usr_id, activity_type, file_key, activity_date)
                    VALUES (?, 'view', ?, NOW())";
    $class_database->execute($activitySql, [$userId, $fileKey]);

    $response['success'] = true;
    $response['data'] = ['message' => 'View recorded'];

    echo json_encode($response);
}

/**
 * Add/remove video from watch later
 */
function handleWatchLater($userId) {
    global $class_database, $response;

    $input = json_decode(file_get_contents('php://input'), true);
    $fileKey = isset($input['file_key']) ? $input['file_key'] : null;

    if (!$fileKey) {
        throw new Exception('Video ID is required', 400);
    }

    // Check if already in watch later
    $checkSql = "SELECT 1 FROM db_watchlater WHERE file_key = ? AND usr_id = ?";
    $existing = $class_database->execute($checkSql, [$fileKey, $userId]);

    if ($existing && $existing->RecordCount() > 0) {
        // Remove from watch later
        $sql = "DELETE FROM db_watchlater WHERE file_key = ? AND usr_id = ?";
        $class_database->execute($sql, [$fileKey, $userId]);
        $action = 'removed';
    } else {
        // Add to watch later
        $sql = "INSERT INTO db_watchlater (file_key, usr_id, added_date) VALUES (?, ?, NOW())";
        $class_database->execute($sql, [$fileKey, $userId]);
        $action = 'added';
    }

    $response['success'] = true;
    $response['data'] = ['action' => $action];

    echo json_encode($response);
}
