<?php
/**
 * User API Endpoint
 * Handles user profile and account operations
 *
 * Supported Actions:
 * - GET profile: Get user profile
 * - PUT update: Update user profile
 * - POST avatar: Upload avatar
 * - GET stats: Get user statistics
 * - GET videos: Get user's videos
 */

// 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'] : 'profile';
    $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':
            switch ($action) {
                case 'profile':
                case 'me':
                    handleGetProfile($userId);
                    break;
                case 'stats':
                    handleGetStats($userId);
                    break;
                case 'videos':
                    handleGetUserVideos($userId);
                    break;
                case 'subscriptions':
                    handleGetSubscriptions($userId);
                    break;
                case 'subscribers':
                    handleGetSubscribers($userId);
                    break;
                default:
                    // Get another user's public profile
                    $targetUserId = isset($_GET['id']) ? (int)$_GET['id'] : null;
                    if ($targetUserId) {
                        handleGetPublicProfile($targetUserId, $userId);
                    } else {
                        handleGetProfile($userId);
                    }
            }
            break;

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

            switch ($action) {
                case 'avatar':
                    handleUploadAvatar($userId);
                    break;
                case 'subscribe':
                    handleSubscribe($userId);
                    break;
                case 'unsubscribe':
                    handleUnsubscribe($userId);
                    break;
                default:
                    throw new Exception('Invalid action', 400);
            }
            break;

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

        case 'DELETE':
            if (!$userId) {
                throw new Exception('Authentication required', 401);
            }
            handleDeleteAccount($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 current user's profile
 */
function handleGetProfile($userId) {
    global $class_database, $response;

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

    $sql = "SELECT usr_id, usr_user, usr_dname, usr_email, usr_fname, usr_lname,
                   usr_avatar, usr_about, usr_website, usr_location,
                   usr_verified, usr_partner, usr_affiliate,
                   usr_joined, usr_lastlogin, usr_profile_privacy
            FROM db_users
            WHERE usr_id = ?";

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

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

    $user = $result->fields;

    // Get user stats
    $statsSql = "SELECT
                    (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = ? AND approved = 1) as video_count,
                    (SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = ?) as subscriber_count,
                    (SELECT COUNT(*) FROM db_subscriptions WHERE usr_id = ?) as subscription_count,
                    (SELECT SUM(file_views) FROM db_videofiles WHERE usr_id = ?) as total_views
                 FROM dual";

    $stats = $class_database->execute($statsSql, [$userId, $userId, $userId, $userId]);

    if ($stats && $stats->RecordCount() > 0) {
        $user['stats'] = [
            'videos' => (int)$stats->fields['video_count'],
            'subscribers' => (int)$stats->fields['subscriber_count'],
            'subscriptions' => (int)$stats->fields['subscription_count'],
            'views' => (int)$stats->fields['total_views']
        ];
    }

    // Get preferences if they exist
    $prefSql = "SELECT * FROM db_user_preferences WHERE usr_id = ?";
    $prefs = $class_database->execute($prefSql, [$userId]);

    if ($prefs && $prefs->RecordCount() > 0) {
        $user['preferences'] = $prefs->fields;
    }

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

    echo json_encode($response);
}

/**
 * Get another user's public profile
 */
function handleGetPublicProfile($targetUserId, $currentUserId) {
    global $class_database, $response;

    $sql = "SELECT usr_id, usr_user, usr_dname, usr_avatar, usr_about,
                   usr_website, usr_location, usr_verified, usr_partner,
                   usr_joined, usr_profile_privacy
            FROM db_users
            WHERE usr_id = ?";

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

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

    $user = $result->fields;

    // Check privacy settings
    if ($user['usr_profile_privacy'] === 'private' && $targetUserId != $currentUserId) {
        throw new Exception('This profile is private', 403);
    }

    // Get public stats
    $statsSql = "SELECT
                    (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = ? AND approved = 1 AND privacy = 'public') as video_count,
                    (SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = ?) as subscriber_count,
                    (SELECT SUM(file_views) FROM db_videofiles WHERE usr_id = ? AND approved = 1) as total_views
                 FROM dual";

    $stats = $class_database->execute($statsSql, [$targetUserId, $targetUserId, $targetUserId]);

    if ($stats && $stats->RecordCount() > 0) {
        $user['stats'] = [
            'videos' => (int)$stats->fields['video_count'],
            'subscribers' => (int)$stats->fields['subscriber_count'],
            'views' => (int)$stats->fields['total_views']
        ];
    }

    // Check if current user is subscribed
    if ($currentUserId) {
        $subSql = "SELECT 1 FROM db_subscriptions WHERE usr_id = ? AND channel_id = ?";
        $subResult = $class_database->execute($subSql, [$currentUserId, $targetUserId]);
        $user['is_subscribed'] = $subResult && $subResult->RecordCount() > 0;
    }

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

    echo json_encode($response);
}

/**
 * Update user profile
 */
function handleUpdateProfile($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);
    }

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

    $allowedFields = [
        'usr_dname', 'usr_fname', 'usr_lname', 'usr_about',
        'usr_website', 'usr_location', 'usr_profile_privacy'
    ];

    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[] = $userId;

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

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

    // Log the update
    VLogger::log('info', 'Profile updated', ['user_id' => $userId, 'fields' => array_keys($input)]);

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

    echo json_encode($response);
}

/**
 * Upload avatar
 */
function handleUploadAvatar($userId) {
    global $class_database, $response;

    if (!isset($_FILES['avatar']) || $_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
        throw new Exception('No file uploaded or upload error occurred', 400);
    }

    $file = $_FILES['avatar'];

    // Validate file type
    $allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimeType = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);

    if (!in_array($mimeType, $allowedTypes)) {
        throw new Exception('Invalid file type. Only JPG, PNG, and GIF are allowed', 400);
    }

    // Validate file size (max 5MB)
    if ($file['size'] > 5 * 1024 * 1024) {
        throw new Exception('File too large. Maximum size is 5MB', 400);
    }

    // Create upload directory if it doesn't exist
    $uploadDir = dirname(__FILE__) . '/../f_data/data_userfiles/user_profile/' . $userId . '/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }

    // Generate unique filename
    $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
    $filename = 'avatar_' . time() . '.' . $extension;
    $targetPath = $uploadDir . $filename;

    // Move uploaded file
    if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
        throw new Exception('Failed to save uploaded file', 500);
    }

    // Update user avatar in database
    $avatarUrl = '/f_data/data_userfiles/user_profile/' . $userId . '/' . $filename;
    $sql = "UPDATE db_users SET usr_avatar = ? WHERE usr_id = ?";
    $result = $class_database->execute($sql, [$avatarUrl, $userId]);

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

    $response['success'] = true;
    $response['data'] = [
        'message' => 'Avatar uploaded successfully',
        'avatar_url' => $avatarUrl
    ];

    echo json_encode($response);
}

/**
 * Get user statistics
 */
function handleGetStats($userId) {
    global $class_database, $response;

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

    $sql = "SELECT
                (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = ? AND approved = 1) as total_videos,
                (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = ? AND upload_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)) as videos_last_30_days,
                (SELECT SUM(file_views) FROM db_videofiles WHERE usr_id = ?) as total_views,
                (SELECT COUNT(*) FROM db_subscriptions WHERE channel_id = ?) as total_subscribers,
                (SELECT COUNT(*) FROM db_subscriptions WHERE usr_id = ?) as total_subscriptions,
                (SELECT COUNT(*) FROM db_comments WHERE usr_id = ?) as total_comments,
                (SELECT COUNT(*) FROM db_likes WHERE usr_id = ?) as total_likes_given
            FROM dual";

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

    if (!$result || $result->RecordCount() === 0) {
        throw new Exception('Failed to fetch statistics', 500);
    }

    $response['success'] = true;
    $response['data'] = $result->fields;

    echo json_encode($response);
}

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

    $targetUserId = isset($_GET['id']) ? (int)$_GET['id'] : $userId;

    if (!$targetUserId) {
        throw new Exception('User ID required', 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;

    // Privacy filter
    $privacyWhere = ($targetUserId == $userId) ? "" : "AND privacy = 'public'";

    // Get total count
    $countSql = "SELECT COUNT(*) FROM db_videofiles WHERE usr_id = ? AND approved = 1 $privacyWhere";
    $total = (int)$class_database->singleFieldValue($countSql, [$targetUserId]);

    // Get videos
    $sql = "SELECT file_key, file_title, file_description, file_duration,
                   file_views, privacy, upload_date, thumbnail, featured,
                   (SELECT COUNT(*) FROM db_likes WHERE file_key = db_videofiles.file_key AND like_type = 'like') as like_count,
                   (SELECT COUNT(*) FROM db_comments WHERE file_key = db_videofiles.file_key) as comment_count
            FROM db_videofiles
            WHERE usr_id = ? AND approved = 1 $privacyWhere
            ORDER BY upload_date DESC
            LIMIT ? OFFSET ?";

    $videos = $class_database->execute($sql, [$targetUserId, $limit, $offset]);

    $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 user's subscriptions
 */
function handleGetSubscriptions($userId) {
    global $class_database, $response;

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

    $sql = "SELECT u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar,
                   s.sub_date,
                   (SELECT COUNT(*) FROM db_videofiles WHERE usr_id = u.usr_id AND approved = 1) as video_count
            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]);

    $response['success'] = true;
    $response['data'] = $result ? $result->GetArray() : [];

    echo json_encode($response);
}

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

    $targetUserId = isset($_GET['id']) ? (int)$_GET['id'] : $userId;

    if (!$targetUserId) {
        throw new Exception('User ID required', 400);
    }

    $sql = "SELECT u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar, 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";

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

    $response['success'] = true;
    $response['data'] = $result ? $result->GetArray() : [];

    echo json_encode($response);
}

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

    $input = json_decode(file_get_contents('php://input'), true);
    $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 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', 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]);

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

    echo json_encode($response);
}

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

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

    if (!$channelId) {
        throw new Exception('Channel ID is required', 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);
    }

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

    echo json_encode($response);
}

/**
 * Delete user account
 */
function handleDeleteAccount($userId) {
    global $class_database, $response;

    // This is a destructive operation, so we'll just mark the account as deleted
    // rather than actually deleting it
    $sql = "UPDATE db_users SET usr_status = 'deleted', usr_email = CONCAT('deleted_', usr_id, '@deleted.com')
            WHERE usr_id = ?";

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

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

    // Log out the user
    VAuth::logout();

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

    echo json_encode($response);
}
