import sqlite3
import threading

class InsufficientFundsError(Exception):
    pass

class LocalWallet:
    def __init__(self, db_path="wallet.db"):
        self.db_path = db_path
        self.lock = threading.Lock()
        self._init_db()

    def _init_db(self):
        with self.lock:
            conn = sqlite3.connect(self.db_path)
            try:
                with conn:
                    cursor = conn.cursor()
                    cursor.execute('''
                        CREATE TABLE IF NOT EXISTS wallet (
                            id INTEGER PRIMARY KEY CHECK (id = 1),
                            balance REAL NOT NULL DEFAULT 0.0
                        )
                    ''')
                    cursor.execute('INSERT OR IGNORE INTO wallet (id, balance) VALUES (1, 0.0)')
            finally:
                conn.close()

    def add_credits(self, amount: float):
        if amount <= 0:
            raise ValueError("Amount to add must be positive")
        with self.lock:
            conn = sqlite3.connect(self.db_path)
            try:
                with conn:
                    cursor = conn.cursor()
                    cursor.execute('UPDATE wallet SET balance = balance + ? WHERE id = 1', (amount,))
            finally:
                conn.close()

    def deduct_credits(self, amount: float):
        if amount <= 0:
            raise ValueError("Amount to deduct must be positive")
        with self.lock:
            conn = sqlite3.connect(self.db_path)
            try:
                with conn:
                    cursor = conn.cursor()
                    cursor.execute('SELECT balance FROM wallet WHERE id = 1')
                    balance = cursor.fetchone()[0]
                    if balance < amount:
                        raise InsufficientFundsError(f"Insufficient funds: {balance} available, {amount} required")
                    
                    cursor.execute('UPDATE wallet SET balance = balance - ? WHERE id = 1', (amount,))
            finally:
                conn.close()

    def get_balance(self) -> float:
        with self.lock:
            conn = sqlite3.connect(self.db_path)
            try:
                cursor = conn.cursor()
                cursor.execute('SELECT balance FROM wallet WHERE id = 1')
                return cursor.fetchone()[0]
            finally:
                conn.close()