<?php
require_once '../config.php';

// Enforce Rate Limiting (Max 5 attempts per minute per IP)
checkRateLimit('edit_profile', 5, 60);

$data = json_decode(file_get_contents("php://input"), true);

if (empty($data['user_id'])) {
    http_response_code(400);
    echo json_encode(["status" => "error", "message" => "user_id is required."]);
    exit();
}

$userId = intval($data['user_id']);
$fullName = isset($data['full_name']) ? sanitizeInput($data['full_name']) : null;
$avatar = isset($data['avatar']) ? sanitizeInput($data['avatar']) : null;
$newPassword = isset($data['password']) ? $data['password'] : null;

try {
    $db = getDBConnection();

    // 1. Self-Healing Schema Checks: Proactively add and modify columns for base64 uploads
    try {
        $db->exec("ALTER TABLE users ADD COLUMN avatar MEDIUMTEXT DEFAULT NULL");
    } catch (Exception $e) {
        // Column already exists, ignore
    }
    try {
        $db->exec("ALTER TABLE users MODIFY COLUMN avatar MEDIUMTEXT DEFAULT NULL");
    } catch (Exception $e) {
        // Ignore
    }
    try {
        $db->exec("ALTER TABLE users ADD COLUMN last_profile_edit DATETIME DEFAULT NULL");
    } catch (Exception $e) {
        // Column already exists, ignore
    }
    try {
        $db->exec("ALTER TABLE users ADD COLUMN temp_pass_expires_at DATETIME DEFAULT NULL");
    } catch (Exception $e) {
        // Ignore
    }
    try {
        $db->exec("ALTER TABLE users ADD COLUMN temp_pass_active TINYINT DEFAULT 0");
    } catch (Exception $e) {
        // Ignore
    }

    // 2. Retrieve user and check profile cooldown
    $stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$userId]);
    $user = $stmt->fetch();

    if (!$user) {
        http_response_code(404);
        echo json_encode(["status" => "error", "message" => "Account not found."]);
        exit();
    }

    // Commented out 30-day lockout check to allow testing/demo updates
    /*
    $lastEditTime = $user['last_profile_edit'];
    if ($lastEditTime !== null) {
        $lastEdit = new DateTime($lastEditTime);
        $now = new DateTime();
        $interval = $now->diff($lastEdit);
        $daysPassed = $interval->days;

        if ($daysPassed < 30) {
            $daysRemaining = 30 - $daysPassed;
            http_response_code(403);
            echo json_encode([
                "status" => "error",
                "cooldown" => true,
                "days_remaining" => $daysRemaining,
                "message" => "Security Lockout: You can only edit your profile details once every 30 days. Please wait $daysRemaining more day(s)."
            ]);
            exit();
        }
    }
    */

    // 3. Assemble and apply updates
    $updates = [];
    $params = [];

    if (!empty($fullName)) {
        $updates[] = "full_name = ?";
        $params[] = $fullName;
    }

    if (!empty($avatar)) {
        $updates[] = "avatar = ?";
        $params[] = $avatar;
    }

    if (!empty($newPassword)) {
        $passwordHash = password_hash($newPassword, PASSWORD_BCRYPT);
        $updates[] = "password_hash = ?";
        $params[] = $passwordHash;
        $updates[] = "temp_pass_active = 0";
        $updates[] = "temp_pass_expires_at = NULL";
    }

    if (empty($updates)) {
        http_response_code(400);
        echo json_encode(["status" => "error", "message" => "No information was provided for update."]);
        exit();
    }

    // Lock edit cooldown timestamp to NOW
    $updates[] = "last_profile_edit = NOW()";

    $db->beginTransaction();

    $sql = "UPDATE users SET " . implode(", ", $updates) . " WHERE id = ?";
    $params[] = $userId;

    $stmt = $db->prepare($sql);
    $stmt->execute($params);

    // Fetch updated user data
    $stmt = $db->prepare("SELECT id, full_name, email, phone, avatar, last_profile_edit, points, points_quiz, points_challenges, points_referrals, points_other, temp_pass_active, temp_pass_expires_at FROM users WHERE id = ?");
    $stmt->execute([$userId]);
    $updatedUser = $stmt->fetch();

    // Fetch wallet info
    $stmt = $db->prepare("SELECT balance FROM wallets WHERE user_id = ?");
    $stmt->execute([$userId]);
    $wallet = $stmt->fetch();

    $db->commit();

    echo json_encode([
        "status" => "success",
        "message" => "Profile successfully updated! Cooldown locked for 30 days.",
        "user" => [
            "id" => intval($updatedUser['id']),
            "full_name" => $updatedUser['full_name'],
            "email" => $updatedUser['email'],
            "phone" => $updatedUser['phone'],
            "avatar" => $updatedUser['avatar'] ?? null,
            "last_profile_edit" => $updatedUser['last_profile_edit'],
            "balance" => floatval($wallet ? $wallet['balance'] : 0.00),
            "today_winnings" => getTodayWinnings($userId),
            "points" => intval($updatedUser['points'] ?? 0),
            "points_quiz" => intval($updatedUser['points_quiz'] ?? 0),
            "points_challenges" => intval($updatedUser['points_challenges'] ?? 0),
            "points_referrals" => intval($updatedUser['points_referrals'] ?? 0),
            "points_other" => intval($updatedUser['points_other'] ?? 0),
            "temp_pass_active" => intval($updatedUser['temp_pass_active'] ?? 0),
            "temp_pass_expires_at" => $updatedUser['temp_pass_expires_at'] ?? null
        ]
    ]);

} catch(Exception $e) {
    if (isset($db) && $db->inTransaction()) {
        $db->rollBack();
    }
    logSecurityError("Edit Profile Database failure (User ID: $userId): " . $e->getMessage());
    http_response_code(500);
    echo json_encode(["status" => "error", "message" => "Failed to update profile details. Security rollback executed."]);
}
?>
