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

date_default_timezone_set('Asia/Kolkata');

### API Blueprint: /user/daily_checkin
# POST /user/daily_checkin
# Description: Claims daily checkin coins for the user.
# Headers:
#   - Device-ID: <device_id> (required)
#   - Session-Token: <session_token> (required)
# Request Body:
#   - user_id: integer (required)
#   - earned_coins: integer (optional) - If provided, uses this value instead of app settings
# Response:
#   - 200: Success
#     {
#       "status": 200,
#       "message": "Daily checkin claimed successfully",
#       "data": {
#         "coins_earned": 50,
#         "total_coins": 1050,
#         "next_checkin_available": "2025-01-16 10:30:00"
#       },
#       "new_session_token": "new_strong_session_token_64_chars"
#     }
#   - 400: Invalid user_id, Already claimed today
#   - 401: Unauthorized
#   - 429: Too many requests
#   - 500: Database connection failed

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

$device_id = $_SERVER['HTTP_DEVICE_ID'] ?? '';
$session_token = $_SERVER['HTTP_SESSION_TOKEN'] ?? '';

$method = $_SERVER['REQUEST_METHOD'];

if ($method !== 'POST') {
    sendResponse(405, 'Method not allowed');
}

// Get the encrypted payload
$encrypted_payload = file_get_contents('php://input');
if (empty($encrypted_payload)) {
    sendResponse(400, 'Empty request body');
}

// Decrypt the payload
$data = decryptRequestPayload($encrypted_payload);
if (!$data) {
    sendResponse(400, 'Invalid request body');
}

$user_id = $data['user_id'] ?? 0;

if ($user_id <= 0) {
    sendResponse(400, 'Invalid user_id');
}

authenticateSession($user_id, $device_id, $session_token);
rateLimit($user_id);
$new_session_token = generateNewSessionToken($user_id, $device_id);

$conn = getDbConnection();

// Check if user has already claimed today
$today = date('Y-m-d');
$stmt = $conn->prepare("SELECT id FROM daily_checkins WHERE user_id = ? AND DATE(claimed_at) = ?");
$stmt->bind_param("is", $user_id, $today);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    $stmt->close();
    $conn->close();
    sendResponse(400, 'Daily checkin already claimed today', [], $new_session_token);
}

$stmt->close();

// Check if earned_coins is provided in request
$earned_coins = $data['earned_coins'] ?? null;

if ($earned_coins !== null) {
    // Validate earned_coins
    if (!is_numeric($earned_coins) || $earned_coins < 0) {
        sendResponse(400, 'Invalid earned_coins value');
    }
    $daily_checkin_coins = (int)$earned_coins;
} else {
    // Get daily checkin coins from app settings
    $stmt = $conn->prepare("SELECT daily_checkin_coins FROM app_settings WHERE id = 1");
    $stmt->execute();
    $result = $stmt->get_result();
    $settings = $result->fetch_assoc();
    $stmt->close();

    // Default to 50 coins if not set
    $daily_checkin_coins = $settings['daily_checkin_coins'] ?? 50;
}

// Start transaction
$conn->begin_transaction();

try {
    // Update user's coins
    $stmt = $conn->prepare("UPDATE users SET coins = coins + ? WHERE id = ?");
    $stmt->bind_param("ii", $daily_checkin_coins, $user_id);
    $stmt->execute();
    if ($stmt->affected_rows === 0) {
        throw new Exception('Failed to update user coins');
    }
    $stmt->close();

    // Record the daily checkin
    $stmt = $conn->prepare("INSERT INTO daily_checkins (user_id, coins_earned, claimed_at) VALUES (?, ?, NOW())");
    $stmt->bind_param("ii", $user_id, $daily_checkin_coins);
    $stmt->execute();
    if ($stmt->affected_rows === 0) {
        throw new Exception('Failed to record daily checkin');
    }
    $stmt->close();

    // Get updated user coins
    $stmt = $conn->prepare("SELECT coins FROM users WHERE id = ?");
    $stmt->bind_param("i", $user_id);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch_assoc();
    $stmt->close();

    // Calculate next checkin time (midnight of the next calendar day)
    $next_checkin = date('Y-m-d 00:00:00', strtotime($today . ' +1 day'));

    $conn->commit();

    sendResponse(200, 'Daily checkin claimed successfully', [
        'coins_earned' => $daily_checkin_coins,
        'total_coins' => $user['coins'],
        'next_checkin_available' => $next_checkin
    ], $new_session_token);

} catch (mysqli_sql_exception $e) {
    $conn->rollback();
    if ($e->getCode() == 1062) { // Duplicate entry
        sendResponse(400, 'Daily checkin already claimed today', [], $new_session_token);
    } else {
        sendResponse(500, 'Failed to process daily checkin: ' . $e->getMessage());
    }
} catch (Exception $e) {
    $conn->rollback();
    sendResponse(500, 'Failed to process daily checkin: ' . $e->getMessage());
}

$conn->close();
?> 