<?php

defined('APP_BOOTSTRAPPED') or exit('No direct access.');

class WalletRepository
{
    private $pdo;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function findByUserId($userId)
    {
        $stmt = $this->pdo->prepare(
            'SELECT user_id, balance, locked_balance, version, updated_at
             FROM wallets
             WHERE user_id = :user_id
             LIMIT 1'
        );

        $stmt->execute(array('user_id' => (int) $userId));

        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return $row ?: null;
    }

    public function lockByUserId($userId)
    {
        $stmt = $this->pdo->prepare(
            'SELECT user_id, balance, locked_balance, version, updated_at
             FROM wallets
             WHERE user_id = :user_id
             LIMIT 1
             FOR UPDATE'
        );

        $stmt->execute(array('user_id' => (int) $userId));

        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return $row ?: null;
    }

    public function createIfMissing($userId)
    {
        $stmt = $this->pdo->prepare(
            'INSERT IGNORE INTO wallets
                (user_id, balance, locked_balance, version, updated_at)
             VALUES
                (:user_id, 0.00, 0.00, 0, NOW())'
        );

        return $stmt->execute(array(
            'user_id' => (int) $userId,
        ));
    }

    public function updateBalance($userId, $balance, $expectedVersion)
    {
        $stmt = $this->pdo->prepare(
            'UPDATE wallets
             SET
                balance = :balance,
                version = version + 1,
                updated_at = NOW()
             WHERE user_id = :user_id
               AND version = :expected_version'
        );

        $stmt->execute(array(
            'balance' => number_format((float) $balance, 2, '.', ''),
            'user_id' => (int) $userId,
            'expected_version' => (int) $expectedVersion,
        ));

        return $stmt->rowCount() === 1;
    }
}
