<?php
/**
 * Comments API Endpoint
 * Handles all comment-related operations
 *
 * Supported Actions:
 * - GET list: List comments for a video
 * - POST create: Create new comment
 * - PUT update: Update comment
 * - DELETE delete: Delete comment
 * - POST like: Like/unlike comment
 * - POST report: Report comment
 */

// 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 comment
                handleGetComment($_GET['id'], $userId);
            } else {
                // List comments
                handleListComments($userId);
            }
            break;

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

            switch ($action) {
                case 'create':
                case null:
                    handleCreateComment($userId);
                    break;
                case 'like':
                    handleLikeComment($userId);
                    break;
                case 'report':
                    handleReportComment($userId);
                    break;
                default:
                    throw new Exception('Invalid action', 400);
            }
            break;

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

        case 'DELETE':
            if (!$userId) {
                throw new Exception('Authentication required', 401);
            }
            handleDeleteComment($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 comments for a video
 */
function handleListComments($userId) {
    global $class_database, $response;

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

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

    $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;
    $sort = isset($_GET['sort']) ? $_GET['sort'] : 'recent'; // recent, top, oldest

    // Determine sort order
    $orderBy = match($sort) {
        'top' => 'c.comment_likes DESC, c.comment_date DESC',
        'oldest' => 'c.comment_date ASC',
        default => 'c.comment_date DESC'
    };

    // Get total count
    $countSql = "SELECT COUNT(*) FROM db_comments WHERE file_key = ? AND parent_id IS NULL";
    $total = (int)$class_database->singleFieldValue($countSql, [$fileKey]);

    // Get top-level comments (not replies)
    $sql = "SELECT c.comment_id, c.usr_id, c.comment_text, c.comment_date,
                   c.comment_likes, c.parent_id,
                   u.usr_user, u.usr_dname, u.usr_avatar, u.usr_verified,
                   (SELECT COUNT(*) FROM db_comments WHERE parent_id = c.comment_id) as reply_count
            FROM db_comments c
            LEFT JOIN db_users u ON c.usr_id = u.usr_id
            WHERE c.file_key = ? AND c.parent_id IS NULL
            ORDER BY $orderBy
            LIMIT ? OFFSET ?";

    $comments = $class_database->execute($sql, [$fileKey, $limit, $offset]);

    $commentList = $comments ? $comments->GetArray() : [];

    // If user is logged in, check which comments they've liked
    if ($userId && !empty($commentList)) {
        $commentIds = array_column($commentList, 'comment_id');
        $placeholders = implode(',', array_fill(0, count($commentIds), '?'));

        $likeSql = "SELECT comment_id FROM db_comment_likes WHERE comment_id IN ($placeholders) AND usr_id = ?";
        $likedComments = $class_database->execute($likeSql, array_merge($commentIds, [$userId]));

        $likedIds = [];
        if ($likedComments) {
            while (!$likedComments->EOF) {
                $likedIds[] = $likedComments->fields['comment_id'];
                $likedComments->MoveNext();
            }
        }

        // Add liked status to comments
        foreach ($commentList as &$comment) {
            $comment['user_liked'] = in_array($comment['comment_id'], $likedIds);
        }
    }

    $response['success'] = true;
    $response['data'] = [
        'comments' => $commentList,
        'pagination' => [
            'page' => $page,
            'limit' => $limit,
            'total' => $total,
            'pages' => ceil($total / $limit)
        ]
    ];

    echo json_encode($response);
}

/**
 * Get single comment with replies
 */
function handleGetComment($commentId, $userId) {
    global $class_database, $response;

    // Get the comment
    $sql = "SELECT c.comment_id, c.usr_id, c.file_key, c.comment_text, c.comment_date,
                   c.comment_likes, c.parent_id,
                   u.usr_user, u.usr_dname, u.usr_avatar, u.usr_verified
            FROM db_comments c
            LEFT JOIN db_users u ON c.usr_id = u.usr_id
            WHERE c.comment_id = ?";

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

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

    $comment = $result->fields;

    // Get replies
    $repliesSql = "SELECT c.comment_id, c.usr_id, c.comment_text, c.comment_date,
                          c.comment_likes, c.parent_id,
                          u.usr_user, u.usr_dname, u.usr_avatar, u.usr_verified
                   FROM db_comments c
                   LEFT JOIN db_users u ON c.usr_id = u.usr_id
                   WHERE c.parent_id = ?
                   ORDER BY c.comment_date ASC";

    $replies = $class_database->execute($repliesSql, [$commentId]);
    $comment['replies'] = $replies ? $replies->GetArray() : [];

    // Check if user liked this comment
    if ($userId) {
        $likeSql = "SELECT 1 FROM db_comment_likes WHERE comment_id = ? AND usr_id = ?";
        $liked = $class_database->execute($likeSql, [$commentId, $userId]);
        $comment['user_liked'] = $liked && $liked->RecordCount() > 0;
    }

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

    echo json_encode($response);
}

/**
 * Create new comment
 */
function handleCreateComment($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);
    }

    $fileKey = isset($input['file_key']) ? $input['file_key'] : null;
    $commentText = isset($input['comment_text']) ? trim($input['comment_text']) : '';
    $parentId = isset($input['parent_id']) ? (int)$input['parent_id'] : null;

    // Validate required fields
    if (!$fileKey) {
        throw new Exception('file_key is required', 400);
    }

    if (empty($commentText)) {
        throw new Exception('Comment text cannot be empty', 400);
    }

    if (strlen($commentText) > 5000) {
        throw new Exception('Comment text too long (max 5000 characters)', 400);
    }

    // Sanitize comment text
    $commentText = VSecurity::sanitize($commentText);

    // Check if video exists
    $videoCheckSql = "SELECT 1 FROM db_videofiles WHERE file_key = ?";
    $videoExists = $class_database->execute($videoCheckSql, [$fileKey]);

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

    // If this is a reply, check if parent comment exists
    if ($parentId) {
        $parentCheckSql = "SELECT usr_id FROM db_comments WHERE comment_id = ?";
        $parentExists = $class_database->execute($parentCheckSql, [$parentId]);

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

        $parentUserId = $parentExists->fields['usr_id'];
    }

    // Insert comment
    $sql = "INSERT INTO db_comments (file_key, usr_id, comment_text, comment_date, parent_id, comment_likes)
            VALUES (?, ?, ?, NOW(), ?, 0)";

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

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

    // Get the inserted comment ID
    $commentId = $class_database->Insert_ID();

    // If this is a reply, create a notification for the parent comment author
    if ($parentId && $parentUserId != $userId) {
        $notifSql = "INSERT INTO db_notifications (usr_id, notif_type, notif_from, notif_ref_id, notif_date)
                     VALUES (?, 'comment_reply', ?, ?, NOW())";
        $class_database->execute($notifSql, [$parentUserId, $userId, $commentId]);
    }

    // Get video owner and create notification
    $videoOwnerSql = "SELECT usr_id FROM db_videofiles WHERE file_key = ?";
    $videoOwner = $class_database->execute($videoOwnerSql, [$fileKey]);

    if ($videoOwner && $videoOwner->fields['usr_id'] != $userId) {
        $notifSql = "INSERT INTO db_notifications (usr_id, notif_type, notif_from, notif_ref_id, notif_date)
                     VALUES (?, 'comment', ?, ?, NOW())";
        $class_database->execute($notifSql, [$videoOwner->fields['usr_id'], $userId, $commentId]);
    }

    // Return the created comment
    $getCommentSql = "SELECT c.comment_id, c.usr_id, c.file_key, c.comment_text, c.comment_date,
                             c.comment_likes, c.parent_id,
                             u.usr_user, u.usr_dname, u.usr_avatar, u.usr_verified
                      FROM db_comments c
                      LEFT JOIN db_users u ON c.usr_id = u.usr_id
                      WHERE c.comment_id = ?";

    $newComment = $class_database->execute($getCommentSql, [$commentId]);

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

    echo json_encode($response);
}

/**
 * Update comment
 */
function handleUpdateComment($userId) {
    global $class_database, $response;

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

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

    // Verify ownership
    $checkSql = "SELECT usr_id FROM db_comments WHERE comment_id = ?";
    $checkResult = $class_database->execute($checkSql, [$commentId]);

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

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

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

    if (!$input || !isset($input['comment_text'])) {
        throw new Exception('comment_text is required', 400);
    }

    $commentText = trim($input['comment_text']);

    if (empty($commentText)) {
        throw new Exception('Comment text cannot be empty', 400);
    }

    if (strlen($commentText) > 5000) {
        throw new Exception('Comment text too long (max 5000 characters)', 400);
    }

    $commentText = VSecurity::sanitize($commentText);

    // Update comment
    $sql = "UPDATE db_comments SET comment_text = ?, comment_edited = 1 WHERE comment_id = ?";
    $result = $class_database->execute($sql, [$commentText, $commentId]);

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

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

    echo json_encode($response);
}

/**
 * Delete comment
 */
function handleDeleteComment($userId) {
    global $class_database, $response;

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

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

    // Verify ownership or admin status
    $checkSql = "SELECT usr_id FROM db_comments WHERE comment_id = ?";
    $checkResult = $class_database->execute($checkSql, [$commentId]);

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

    // Check if user is the comment owner or has admin role
    $isOwner = $checkResult->fields['usr_id'] == $userId;
    $isAdmin = VAuth::hasPermission('comments.delete.any');

    if (!$isOwner && !$isAdmin) {
        throw new Exception('You do not have permission to delete this comment', 403);
    }

    // Delete comment and its replies
    $sql = "DELETE FROM db_comments WHERE comment_id = ? OR parent_id = ?";
    $result = $class_database->execute($sql, [$commentId, $commentId]);

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

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

    echo json_encode($response);
}

/**
 * Like/unlike comment
 */
function handleLikeComment($userId) {
    global $class_database, $response;

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

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

    // Check if comment exists
    $checkSql = "SELECT usr_id FROM db_comments WHERE comment_id = ?";
    $commentExists = $class_database->execute($checkSql, [$commentId]);

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

    $commentOwnerId = $commentExists->fields['usr_id'];

    // Check if already liked
    $likeSql = "SELECT 1 FROM db_comment_likes WHERE comment_id = ? AND usr_id = ?";
    $existing = $class_database->execute($likeSql, [$commentId, $userId]);

    if ($existing && $existing->RecordCount() > 0) {
        // Remove like
        $deleteSql = "DELETE FROM db_comment_likes WHERE comment_id = ? AND usr_id = ?";
        $class_database->execute($deleteSql, [$commentId, $userId]);

        // Decrement like count
        $updateSql = "UPDATE db_comments SET comment_likes = comment_likes - 1 WHERE comment_id = ?";
        $class_database->execute($updateSql, [$commentId]);

        $action = 'unliked';
    } else {
        // Add like
        $insertSql = "INSERT INTO db_comment_likes (comment_id, usr_id, like_date) VALUES (?, ?, NOW())";
        $class_database->execute($insertSql, [$commentId, $userId]);

        // Increment like count
        $updateSql = "UPDATE db_comments SET comment_likes = comment_likes + 1 WHERE comment_id = ?";
        $class_database->execute($updateSql, [$commentId]);

        // Create notification for comment owner
        if ($commentOwnerId != $userId) {
            $notifSql = "INSERT INTO db_notifications (usr_id, notif_type, notif_from, notif_ref_id, notif_date)
                         VALUES (?, 'comment_like', ?, ?, NOW())";
            $class_database->execute($notifSql, [$commentOwnerId, $userId, $commentId]);
        }

        $action = 'liked';
    }

    // Get updated like count
    $countSql = "SELECT comment_likes FROM db_comments WHERE comment_id = ?";
    $countResult = $class_database->execute($countSql, [$commentId]);

    $response['success'] = true;
    $response['data'] = [
        'action' => $action,
        'like_count' => $countResult->fields['comment_likes']
    ];

    echo json_encode($response);
}

/**
 * Report comment
 */
function handleReportComment($userId) {
    global $class_database, $response;

    $input = json_decode(file_get_contents('php://input'), true);
    $commentId = isset($input['comment_id']) ? (int)$input['comment_id'] : null;
    $reason = isset($input['reason']) ? VSecurity::sanitize($input['reason']) : '';

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

    if (empty($reason)) {
        throw new Exception('Reason is required', 400);
    }

    // Check if comment exists
    $checkSql = "SELECT 1 FROM db_comments WHERE comment_id = ?";
    $commentExists = $class_database->execute($checkSql, [$commentId]);

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

    // Check if already reported by this user
    $reportCheckSql = "SELECT 1 FROM db_reports WHERE comment_id = ? AND usr_id = ?";
    $existing = $class_database->execute($reportCheckSql, [$commentId, $userId]);

    if ($existing && $existing->RecordCount() > 0) {
        throw new Exception('You have already reported this comment', 400);
    }

    // Insert report
    $sql = "INSERT INTO db_reports (comment_id, usr_id, report_reason, report_date, report_status)
            VALUES (?, ?, ?, NOW(), 'pending')";

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

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

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

    echo json_encode($response);
}
