<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

require_once '../config/database.php';
require_once '../utils/helpers.php';

$token = getAuthToken();
$user = getUserFromToken($token);

if (!$user) {
    echo json_encode(["status" => "error", "message" => "Unauthorized"]);
    exit;
}

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {
    handle_get($pdo, $user['id']);
} elseif ($method === 'POST') {
    handle_post($pdo, $user['id']);
}

function handle_get($pdo, $userId) {
    try {
        // Fetch Staking Pools
        $stmt = $pdo->query("SELECT * FROM staking_pools WHERE status = 'active'");
        $pools = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Fetch User Stakes
        $stmt = $pdo->prepare("SELECT us.*, sp.symbol, sp.name as pool_name, sp.icon, sp.color, sp.apr 
                               FROM user_stakes us 
                               JOIN staking_pools sp ON us.pool_id = sp.id 
                               WHERE us.user_id = ?");
        $stmt->execute([$userId]);
        $stakes = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Calculate simulated rewards for each stake (based on time since last claim)
        foreach ($stakes as &$stake) {
            $lastClaim = strtotime($stake['last_claim_at']);
            $now = time();
            $secondsElapsed = $now - $lastClaim;
            
            // Daily APR calculation (simplified)
            $dailyRate = $stake['apr'] / 365;
            $secondsInDay = 86400;
            $accrued = $stake['amount'] * ($dailyRate * ($secondsElapsed / $secondsInDay));
            
            $stake['pending_reward'] = round($accrued, 8);
        }

        echo json_encode([
            "status" => "success",
            "data" => [
                "pools" => $pools,
                "stakes" => $stakes
            ]
        ]);
    } catch (PDOException $e) {
        echo json_encode(["status" => "error", "message" => $e->getMessage()]);
    }
}

function handle_post($pdo, $userId) {
    $data = json_decode(file_get_contents("php://input"), true);
    $action = $data['action'] ?? '';

    switch ($action) {
        case 'stake':
            process_stake($pdo, $userId, $data);
            break;
        case 'unstake':
            process_unstake($pdo, $userId, $data);
            break;
        case 'claim':
            process_claim($pdo, $userId, $data);
            break;
        default:
            echo json_encode(["status" => "error", "message" => "Invalid action"]);
    }
}

function process_stake($pdo, $userId, $data) {
    $poolId = $data['pool_id'];
    $amount = floatval($data['amount']);

    try {
        $pdo->beginTransaction();

        // Get pool info
        $stmt = $pdo->prepare("SELECT symbol, min_stake, lock_period_days FROM staking_pools WHERE id = ?");
        $stmt->execute([$poolId]);
        $pool = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$pool) throw new Exception("Pool not found");
        if ($amount < $pool['min_stake']) throw new Exception("Minimum stake is " . $pool['min_stake']);

        // Check wallet balance
        $stmt = $pdo->prepare("SELECT balance FROM user_assets WHERE user_id = ? AND symbol = ?");
        $stmt->execute([$userId, $pool['symbol']]);
        $balance = $stmt->fetchColumn();

        if ($balance === false || $balance < $amount) {
            throw new Exception("Insufficient wallet balance");
        }

        // Deduct from wallet
        $stmt = $pdo->prepare("UPDATE user_assets SET balance = balance - ? WHERE user_id = ? AND symbol = ?");
        $stmt->execute([$amount, $userId, $pool['symbol']]);

        // Create or update stake
        $lockDays = $pool['lock_period_days'];
        $unlockAt = date('Y-m-d H:i:s', strtotime("+$lockDays days"));

        $stmt = $pdo->prepare("INSERT INTO user_stakes (id, user_id, pool_id, amount, unlock_at) VALUES (?, ?, ?, ?, ?)");
        $stmt->execute([uniqid(), $userId, $poolId, $amount, $unlockAt]);

        // Update total staked in pool
        $stmt = $pdo->prepare("UPDATE staking_pools SET total_staked = total_staked + ? WHERE id = ?");
        $stmt->execute([$amount, $poolId]);

        $pdo->commit();
        echo json_encode(["status" => "success", "message" => "Staked $amount successfully"]);
    } catch (Exception $e) {
        $pdo->rollBack();
        echo json_encode(["status" => "error", "message" => $e->getMessage()]);
    }
}

function process_unstake($pdo, $userId, $data) {
    $stakeId = $data['stake_id'];

    try {
        $pdo->beginTransaction();

        $stmt = $pdo->prepare("SELECT us.*, sp.symbol, sp.id as pool_id FROM user_stakes us JOIN staking_pools sp ON us.pool_id = sp.id WHERE us.id = ? AND us.user_id = ?");
        $stmt->execute([$stakeId, $userId]);
        $stake = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$stake) throw new Exception("Stake not found");
        
        // Check lock period
        if (strtotime($stake['unlock_at']) > time()) {
            throw new Exception("Staked assets are locked until " . $stake['unlock_at']);
        }

        // Process claim first
        // (Simplified: just add stake amount back to wallet)
        
        // Add back to wallet
        $stmt = $pdo->prepare("UPDATE user_assets SET balance = balance + ? WHERE user_id = ? AND symbol = ?");
        $stmt->execute([$stake['amount'], $userId, $stake['symbol']]);

        // Update pool
        $stmt = $pdo->prepare("UPDATE staking_pools SET total_staked = total_staked - ? WHERE id = ?");
        $stmt->execute([$stake['amount'], $stake['pool_id']]);

        // Delete stake
        $stmt = $pdo->prepare("DELETE FROM user_stakes WHERE id = ?");
        $stmt->execute([$stakeId]);

        $pdo->commit();
        echo json_encode(["status" => "success", "message" => "Unstaked successfully"]);
    } catch (Exception $e) {
        $pdo->rollBack();
        echo json_encode(["status" => "error", "message" => $e->getMessage()]);
    }
}

function process_claim($pdo, $userId, $data) {
    // Simplified claim: just resets last_claim_at and sends imaginary reward (or adds to wallet)
    // In a real app, rewards would be added to the wallet balance
    $stakeId = $data['stake_id'];
    
    try {
        $pdo->beginTransaction();
        
        $stmt = $pdo->prepare("UPDATE user_stakes SET last_claim_at = CURRENT_TIMESTAMP WHERE id = ? AND user_id = ?");
        $stmt->execute([$stakeId, $userId]);
        
        $pdo->commit();
        echo json_encode(["status" => "success", "message" => "Rewards claimed successfully"]);
    } catch (Exception $e) {
        $pdo->rollBack();
        echo json_encode(["status" => "error", "message" => $e->getMessage()]);
    }
}
