<?php
/**
 * Subscriptions API Endpoint
 * Handles subscription-related operations
 *
 * Supported Actions:
 * - GET list: Get user's subscriptions or subscribers
 * - POST subscribe: Subscribe to a channel
 * - DELETE unsubscribe: Unsubscribe from a channel
 * - GET feed: Get activity feed from subscribed channels
 */

// 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'];
    }

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

    // Route based on method and action
    switch ($method) {
        case 'GET':
            switch ($action) {
                case 'list':
                case 'subscriptions':
                case null:
                    handleGetSubscriptions($userId);
                    break;
                case 'subscribers':
                    handleGetSubscribers($userId);
                    break;
                case 'feed':
                    handleGetFeed($userId);
                    break;
                case 'check':
                    handleCheckSubscription($userId);
                    break;
                default:
                    throw new Exception('Invalid action', 400);
            }
            break;

        case 'POST':
            handleSubscribe($userId);
            break;

        case 'DELETE':
            handleUnsubscribe($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;
}

/**
 * Get user's subscriptions
 */
function handleGetSubscriptions($userId) {
    global $class_database, $response;

    $sql = "SELECT u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar,
                   u.usr_verified, u.usr_partner,
                   s.sub_date,
                   (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = u.usr_id AND approved = 1 AND privacy = 'public') as video_count,
                   (SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = u.usr_id) as subscriber_count,
                   (SELECT MAX(upload_date) FROM db_videofiles WHERE usr_id = u.usr_id AND approved = 1) as last_upload
            FROM db_subscriptions s
            LEFT JOIN db_users u ON s.channel_id = u.usr_id
            WHERE s.usr_id = ?
            ORDER BY s.sub_date DESC";

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

    $subscriptions = $result ? $result->GetArray() : [];

    $response['success'] = true;
    $response['data'] = [
        'subscriptions' => $subscriptions,
        'total' => count($subscriptions)
    ];

    echo json_encode($response);
}

/**
 * Get subscribers for a channel
 */
function handleGetSubscribers($userId) {
    global $class_database, $response;

    $channelId = isset($_GET['channel_id']) ? (int)$_GET['channel_id'] : $userId;

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

    // Get total count
    $countSql = "SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = ?";
    $total = (int)$class_database->singleFieldValue($countSql, [$channelId]);

    // Get subscribers
    $sql = "SELECT u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar,
                   u.usr_verified, s.sub_date
            FROM db_subscriptions s
            LEFT JOIN db_users u ON s.usr_id = u.usr_id
            WHERE s.channel_id = ?
            ORDER BY s.sub_date DESC
            LIMIT ? OFFSET ?";

    $result = $class_database->execute($sql, [$channelId, $limit, $offset]);

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

    echo json_encode($response);
}

/**
 * Get activity feed from subscribed channels
 */
function handleGetFeed($userId) {
    global $class_database, $response;

    $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 videos from subscribed channels
    $sql = "SELECT v.file_key, v.file_title, v.file_description, v.file_duration,
                   v.file_views, v.upload_date, v.thumbnail, v.featured,
                   u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar, u.usr_verified,
                   (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
            INNER JOIN db_subscriptions s ON s.channel_id = v.usr_id
            WHERE s.usr_id = ? AND v.approved = 1 AND v.privacy = 'public'
            ORDER BY v.upload_date DESC
            LIMIT ? OFFSET ?";

    $result = $class_database->execute($sql, [$userId, $limit, $offset]);

    // Get total count
    $countSql = "SELECT COUNT(*)
                 FROM db_videofiles v
                 INNER JOIN db_subscriptions s ON s.channel_id = v.usr_id
                 WHERE s.usr_id = ? AND v.approved = 1 AND v.privacy = 'public'";
    $total = (int)$class_database->singleFieldValue($countSql, [$userId]);

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

    echo json_encode($response);
}

/**
 * Check if subscribed to a channel
 */
function handleCheckSubscription($userId) {
    global $class_database, $response;

    $channelId = isset($_GET['channel_id']) ? (int)$_GET['channel_id'] : null;

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

    $sql = "SELECT sub_date FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
    $result = $class_database->execute($sql, [$userId, $channelId]);

    $isSubscribed = $result && $result->RecordCount() > 0;
    $subDate = $isSubscribed ? $result->fields['sub_date'] : null;

    $response['success'] = true;
    $response['data'] = [
        'is_subscribed' => $isSubscribed,
        'subscribed_since' => $subDate
    ];

    echo json_encode($response);
}

/**
 * Subscribe to a channel
 */
function handleSubscribe($userId) {
    global $class_database, $response;

    // Get JSON input or form data
    $input = json_decode(file_get_contents('php://input'), true);
    if (!$input) {
        $input = $_POST;
    }

    $channelId = isset($input['channel_id']) ? (int)$input['channel_id'] : null;

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

    if ($channelId == $userId) {
        throw new Exception('Cannot subscribe to yourself', 400);
    }

    // Check if channel exists
    $channelCheckSql = "SELECT usr_user FROM db_users WHERE usr_id = ?";
    $channelExists = $class_database->execute($channelCheckSql, [$channelId]);

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

    // Check if already subscribed
    $checkSql = "SELECT 1 FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
    $existing = $class_database->execute($checkSql, [$userId, $channelId]);

    if ($existing && $existing->RecordCount() > 0) {
        throw new Exception('Already subscribed to this channel', 400);
    }

    // Add subscription
    $sql = "INSERT INTO db_subscriptions (usr_id, channel_id, sub_date) VALUES (?, ?, NOW())";
    $result = $class_database->execute($sql, [$userId, $channelId]);

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

    // Create notification for channel owner
    $notifSql = "INSERT INTO db_notifications (usr_id, notif_type, notif_from, notif_date)
                 VALUES (?, 'subscription', ?, NOW())";
    $class_database->execute($notifSql, [$channelId, $userId]);

    // Get updated subscriber count
    $countSql = "SELECT COUNT(*) as count FROM db_subscriptions WHERE channel_id = ?";
    $countResult = $class_database->execute($countSql, [$channelId]);
    $subscriberCount = $countResult->fields['count'];

    // Log the subscription
    VLogger::log('info', 'User subscribed to channel', [
        'user_id' => $userId,
        'channel_id' => $channelId
    ]);

    $response['success'] = true;
    $response['data'] = [
        'message' => 'Subscribed successfully',
        'channel_name' => $channelExists->fields['usr_user'],
        'subscriber_count' => $subscriberCount
    ];

    echo json_encode($response);
}

/**
 * Unsubscribe from a channel
 */
function handleUnsubscribe($userId) {
    global $class_database, $response;

    // Get channel ID from query string or JSON body
    $channelId = isset($_GET['channel_id']) ? (int)$_GET['channel_id'] : null;

    if (!$channelId) {
        $input = json_decode(file_get_contents('php://input'), true);
        if (!$input) {
            $input = $_POST;
        }
        $channelId = isset($input['channel_id']) ? (int)$input['channel_id'] : null;
    }

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

    // Check if subscribed
    $checkSql = "SELECT 1 FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
    $existing = $class_database->execute($checkSql, [$userId, $channelId]);

    if (!$existing || $existing->RecordCount() === 0) {
        throw new Exception('Not subscribed to this channel', 400);
    }

    // Remove subscription
    $sql = "DELETE FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
    $result = $class_database->execute($sql, [$userId, $channelId]);

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

    // Get updated subscriber count
    $countSql = "SELECT COUNT(*) as count FROM db_subscriptions WHERE channel_id = ?";
    $countResult = $class_database->execute($countSql, [$channelId]);
    $subscriberCount = $countResult->fields['count'];

    // Log the unsubscription
    VLogger::log('info', 'User unsubscribed from channel', [
        'user_id' => $userId,
        'channel_id' => $channelId
    ]);

    $response['success'] = true;
    $response['data'] = [
        'message' => 'Unsubscribed successfully',
        'subscriber_count' => $subscriberCount
    ];

    echo json_encode($response);
}
