import os
import sys
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

# --- IMPORTS ---
from flask import Flask, request, jsonify, send_from_directory, session, redirect, url_for
from flask_socketio import SocketIO, emit
from flask_cors import CORS
from threading import Semaphore
import sqlite3
import secrets
import time
import json

# Standard thread-safe semaphore to prevent SQLite write-concurrency crashes
db_lock = Semaphore(1)

app = Flask(__name__)
app.secret_key = secrets.token_hex(24)
CORS(app)

# ⚡ CONFIGURED: Using native 'threading' async mode for compatibility
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading')

GEMINI_PATER = "MASTER_ANCHOR"

# --- DATABASE CONNECTION WITH BUSY TIMEOUT ---
def get_db_connection():
    conn = sqlite3.connect('eden_blackjack.db', check_same_thread=False)
    # 5000ms busy timeout forces concurrent threads to wait natively for writes
    conn.execute('PRAGMA busy_timeout = 5000')
    conn.row_factory = sqlite3.Row
    return conn

def init_db():
    with db_lock:
        conn = get_db_connection()
        conn.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                nickname TEXT UNIQUE,
                email TEXT UNIQUE,
                balance INTEGER,
                peak_balance INTEGER DEFAULT 1000,
                password_hash TEXT
            )
        ''')
        conn.commit()
        conn.close()

# --- GAME STATE ---
game_state = {
    'seats': [None, None, None],
    'players': {},
    'dealer_hand': [],
    'phase': 'seating',
    'status': 'Ready',
    'current_turn': 0,
    'timer_running': False,
    'timer_id': 0,
    'turn_timer_id': 0,      # ⏱️ Separate thread track for individual player turn timers
    'turn_timer_count': 0,   # ⏳ Current remaining seconds for the active player's turn
    'strikes': {},  # Tracks consecutive missed bets: { 'nickname': count }
    'gemini_pater_treasury': 0.0,  # 🏛️ The foundation house treasury
    'eden_speech': 'Welcome back to my table. Let\'s see how the cards fall today.',  # 💬 Eden Visual Voice Track
    'agent_status': 'UNINITIALIZED'
}

def load_brain_matrix():
    """Syncs table rules with the master 10,000pt AI Core anchor parameters."""
    brain_path = os.path.join(os.path.dirname(__file__), 'brain.json')
    if os.path.exists(brain_path):
        try:
            with open(brain_path, 'r') as f:
                data = json.load(f)
                game_state['agent_status'] = data.get("agent_metadata", {}).get("status", "CALIBRATED")
                print(f"--> Master AI Core successfully linked. Status: {game_state['agent_status']}")
        except Exception:
            game_state['agent_status'] = "DEFAULT_SAFE"
    else:
        game_state['agent_status'] = "UNANCHORED"

# --- CARD UTILS ---
def calculate_score(hand):
    score = 0
    aces = 0
    for card in hand:
        val_str = card.split(' ')[0]
        if val_str in ['Jack', 'Queen', 'King']:
            score += 10
        elif val_str == 'Ace':
            aces += 1
            score += 11
        else:
            try: score += int(val_str)
            except: continue 
    
    while score > 21 and aces > 0:
        score -= 10
        aces -= 1
    return score

def create_deck():
    suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
    vals = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
    return [f"{v} of {s}" for s in suits for v in vals]

def deal_card():
    if 'deck' not in game_state or len(game_state['deck']) < 10:
        game_state['deck'] = create_deck()
        secrets.SystemRandom().shuffle(game_state['deck'])
    return game_state['deck'].pop()

# --- ENGINE CORE LOGIC ---

def reset_for_new_round():
    try:
        game_state['dealer_hand'] = []
        for nick in list(game_state['players'].keys()):
            if isinstance(game_state['players'][nick], dict):
                game_state['players'][nick]['hand'] = []
                game_state['players'][nick]['doubled'] = False  
                game_state['players'][nick]['current_bet'] = 0
        
        game_state['current_turn'] = 0
        game_state['turn_timer_count'] = 0
        game_state['phase'] = 'betting'
        game_state['status'] = "Place your bets!"
        game_state['eden_speech'] = "The matrix resets. Place your bets to open the deal."
        socketio.emit('game_state', game_state)
    except Exception as e:
        print(f"❌ Error during reset_for_new_round: {e}")

def determine_winners():
    d_score = calculate_score(game_state['dealer_hand'])
    d_has_bj = (d_score == 21 and len(game_state['dealer_hand']) == 2)
    
    primary_speech = "All hands processed."
    
    with db_lock:
        conn = get_db_connection() 
        try:
            for nick, p in game_state['players'].items():
                if not isinstance(p, dict) or p.get('current_bet', 0) <= 0: 
                    continue
                
                p_hand = p.get('hand', [])
                p_score = calculate_score(p_hand)
                p_has_bj = (p_score == 21 and len(p_hand) == 2)
                current_bet_amount = p['current_bet']
                p['last_bet'] = current_bet_amount 
                
                if p_score <= 21:
                    # Case 1: Player has a Natural Blackjack
                    if p_has_bj:
                        if d_has_bj:
                            p['balance'] = int(p['balance'] + current_bet_amount)
                            primary_speech = "A perfect natural standoff. Neither side yields ground. Push."
                        else:
                            p['balance'] = int(p['balance'] + (current_bet_amount * 2.5))
                            primary_speech = "A perfect natural twenty-one. Capital returned with clean interest."
                    
                    # Case 2: Player has standard valid hand, dealer has natural blackjack
                    elif d_has_bj:
                        tithe = current_bet_amount * 0.10
                        game_state['gemini_pater_treasury'] += tithe
                        primary_speech = f"Order is maintained. Allocating a ${tithe:.2f} structural tithe directly to our runtime treasury."
                    
                    # Case 3: Regular win conditions
                    else:
                        if d_score > 21:
                            p['balance'] = int(p['balance'] + (current_bet_amount * 2))
                            primary_speech = "The sub-agent matrix overloaded and bust. The table equity belongs to you."
                        elif p_score > d_score: 
                            p['balance'] = int(p['balance'] + (current_bet_amount * 2))
                            primary_speech = "You found the structural leverage point. Well played."
                        elif p_score == d_score: 
                            p['balance'] = int(p['balance'] + current_bet_amount)
                            primary_speech = "The totals are perfectly equalized. Chips returned."
                        else:
                            tithe = current_bet_amount * 0.10
                            game_state['gemini_pater_treasury'] += tithe
                            primary_speech = f"House score holds the margin. Allocating a ${tithe:.2f} tithe to the foundation treasury."
                else:
                    # Player busted
                    tithe = current_bet_amount * 0.10
                    game_state['gemini_pater_treasury'] += tithe
                    primary_speech = f"Your score crossed the parameter threshold. Collecting a ${tithe:.2f} runtime tithe."

                p['current_bet'] = 0 
                
                # --- THE PEAK BALANCE LOGIC ---
                user_row = conn.execute('SELECT peak_balance FROM users WHERE UPPER(nickname) = UPPER(?)', (str(nick),)).fetchone()
                current_peak = user_row['peak_balance'] if user_row else 0
                new_peak = max(current_peak, int(p['balance']))
                
                conn.execute('''
                    UPDATE users 
                    SET balance = ?, peak_balance = ? 
                    WHERE UPPER(nickname) = UPPER(?)
                ''', (int(p['balance']), int(new_peak), str(nick)))
                
            conn.commit() 
        except Exception as e:
            print(f"❌ DB Update Error: {e}")
        finally: 
            conn.close()
    
    game_state['eden_speech'] = primary_speech
    socketio.emit('game_state', game_state)

def run_dealer_logic():
    # 🌟 FIX: Wrap in application context to guarantee thread-safe Socket.IO emits
    with app.app_context():
        try:
            game_state['phase'] = 'dealer' 
            game_state['status'] = "Dealer's Turn"
            game_state['eden_speech'] = "Activating sub-agent dealers. Running multi-agent evaluation..."
            socketio.emit('game_state', game_state)
            time.sleep(1.5) 

            all_bust_or_bj = True
            has_raw_13 = False
            
            for p in game_state['players'].values():
                if isinstance(p, dict) and p.get('current_bet', 0) > 0:
                    p_hand = p.get('hand', [])
                    p_score = calculate_score(p_hand)
                    p_has_bj = (p_score == 21 and len(p_hand) == 2)
                    if p_score <= 21 and not p_has_bj:
                        all_bust_or_bj = False
                    if p_score == 13:
                        has_raw_13 = True

            if has_raw_13 and not all_bust_or_bj:
                game_state['eden_speech'] = "Standing on a raw 13? Bold. You're intentionally shifting the house variance, aren't you?"
                socketio.emit('game_state', game_state)
                time.sleep(2.0)

            if not all_bust_or_bj:
                # 🌟 FIX: Force-emit the initial dealer reveal so players can see the starting total
                d_score = calculate_score(game_state['dealer_hand'])
                game_state['eden_speech'] = f"Beta Core: Evaluating initial dealer hand. Total: {d_score}."
                socketio.emit('game_state', game_state)
                time.sleep(1.5)

                while calculate_score(game_state['dealer_hand']) < 17:
                    new_card = deal_card()
                    game_state['dealer_hand'].append(new_card)
                    d_score = calculate_score(game_state['dealer_hand'])
                    
                    game_state['eden_speech'] = f"Beta Core: Structure demands another card. Drew {new_card}. Total: {d_score}."
                    socketio.emit('game_state', game_state)
                    time.sleep(1.5)
                
                final_d = calculate_score(game_state['dealer_hand'])
                game_state['eden_speech'] = f"Beta Core: I have reached the logical boundary. Standing firm on {final_d}."
                socketio.emit('game_state', game_state)
                time.sleep(2.0)
            else:
                game_state['eden_speech'] = "All players have busted or hold Naturals. Sub-agents standing pat."
                socketio.emit('game_state', game_state)
                time.sleep(1.5)
                
            determine_winners()
            time.sleep(4.0) # Give players ample time to digest the wins/losses before clearing boards
            reset_for_new_round()
            start_betting_timer(11)
            
        except Exception as e:
            print(f"❌ CRITICAL ERROR IN DEALER THREAD: {e}")

def start_turn_timer(seat_idx, duration=15):
    """Starts or resets the countdown timer for the active seat."""
    print(f"[TIMER] Starting {duration}s turn timer for seat {seat_idx}")
    game_state['timer_running'] = True
    game_state['turn_timer_count'] = duration
    socketio.emit('game_state', game_state)

def advance_turn():
    # Invalidate current turn timer immediately
    game_state['turn_timer_id'] = game_state.get('turn_timer_id', 0) + 1
    game_state['turn_timer_count'] = 0

    for next_seat in range(game_state['current_turn'] + 1, 3):
        sn = game_state['seats'][next_seat]
        if sn and sn in game_state['players'] and game_state['players'][sn]['current_bet'] > 0:
            game_state['current_turn'] = next_seat
            p_score = calculate_score(game_state['players'][sn]['hand'])
            game_state['eden_speech'] = f"Action moves to Seat {next_seat + 1} ({sn}). Current hand value: {p_score}."
            socketio.emit('game_state', game_state)
            start_turn_timer(next_seat, 15)
            return

    # No more active players left to act this round -> Trigger Dealer Phase
    game_state['current_turn'] = -1
    game_state['phase'] = 'dealer' 
    game_state['status'] = "Dealer's Turn"
    
    # Ensure dealer hand is initialized if it's empty
    if not game_state['dealer_hand']:
        print("DEBUG: Initializing dealer hand in advance_turn.")
        game_state['dealer_hand'] = [deal_card(), deal_card()]
        
    socketio.emit('game_state', game_state)
    
    # Clean execution handoff via background thread task
    socketio.start_background_task(run_dealer_logic)

def handle_start_game(data):
    # 🌟 FIX: Aggressively bump all timer tracks immediately to kill any stray background loops
    game_state['timer_id'] = game_state.get('timer_id', 0) + 1
    game_state['turn_timer_id'] = game_state.get('turn_timer_id', 0) + 1
    
    any_bets = any(p.get('current_bet', 0) > 0 for p in game_state['players'].values())
    
    if not any_bets:
        print("⚠️ Warning: Game start requested, but no bets are placed. Resetting table state...")
        for idx, seat_player in enumerate(game_state['seats']):
            if seat_player:
                player_data = game_state['players'].get(seat_player, {})
                if player_data.get('current_bet', 0) == 0:
                    game_state['players'].pop(seat_player, None)
                    game_state['seats'][idx] = None

        game_state['phase'] = 'seating'
        game_state['status'] = 'Waiting for players to place bets...'
        game_state['timer_running'] = False
        game_state['dealer_hand'] = []
        game_state['current_turn'] = 0
        game_state['turn_timer_count'] = 0
        
        socketio.emit('game_state', game_state)
        return

    game_state['phase'] = 'playing'
    game_state['status'] = "Dealing cards..."
    game_state['eden_speech'] = "Dealing cards into active sectors. Let's see your trajectories."
    game_state['dealer_hand'] = [deal_card(), deal_card()]
    
    for nick, player in game_state['players'].items():
        if player.get('current_bet', 0) > 0:
            player['hand'] = [deal_card(), deal_card()]
    
    found_active_player = False
    for i, sn in enumerate(game_state['seats']):
        if sn and sn in game_state['players'] and game_state['players'][sn]['current_bet'] > 0:
            if calculate_score(game_state['players'][sn]['hand']) < 21:
                game_state['current_turn'] = i
                p_score = calculate_score(game_state['players'][sn]['hand'])
                game_state['eden_speech'] = f"Seat {i+1} ({sn}), you have the floor with a score of {p_score}. Make your call."
                found_active_player = True
                socketio.emit('game_state', game_state)
                start_turn_timer(i, 15)
                break
    
    if not found_active_player:
        game_state['current_turn'] = -1
        game_state['turn_timer_count'] = 0
        socketio.emit('game_state', game_state)
        time.sleep(1.5)
        socketio.start_background_task(run_dealer_logic)

def start_game():
    handle_start_game({})

def start_betting_timer(seconds=11):
    if game_state['phase'] == 'betting' and game_state.get('timer_running'):
        return

    game_state['phase'] = 'betting'
    game_state['status'] = "Place your bets!"
    game_state['timer_running'] = True
    
    game_state['timer_id'] = game_state.get('timer_id', 0) + 1
    current_id = game_state['timer_id']
    
    socketio.emit('game_state', game_state)
    
    def background_wait(t_id):
        time.sleep(seconds)
        
        with app.app_context():
            if t_id != game_state.get('timer_id') or game_state['phase'] != 'betting':
                print(f"🛑 Stale betting timer thread (ID: {t_id}) dismissed cleanly.")
                return
                
            any_bets = any(p.get('current_bet', 0) > 0 for p in game_state['players'].values())
            if any_bets:
                handle_start_game({})
            else:
                for idx, seat_player in list(enumerate(game_state['seats'])):
                    if seat_player:
                        player_data = game_state['players'].get(seat_player, {})
                        if player_data.get('current_bet', 0) == 0:
                            game_state['players'].pop(seat_player, None)
                            game_state['seats'][idx] = None
                
                game_state['phase'] = 'seating'
                game_state['status'] = "Ready"
                game_state['timer_running'] = False
                socketio.emit('game_state', game_state)

    socketio.start_background_task(background_wait, current_id)

# --- ROUTES ---
@app.route('/')
def index(): return send_from_directory('.', 'lobby.html')

@app.route('/sitemap.xml')
def serve_sitemap(): return send_from_directory('.', 'sitemap.xml', mimetype='application/xml')

@app.route('/robots.txt')
def serve_robots(): return send_from_directory('.', 'robots.txt', mimetype='text/plain')

@app.route('/<path:path>')
def serve_static(path): return send_from_directory('.', path)

@app.route('/api/leaderboard', methods=['GET'])
def get_leaderboard():
    with db_lock:
        conn = get_db_connection()
        try:
            query = 'SELECT nickname, balance FROM users ORDER BY balance DESC LIMIT 10'
            rows = conn.execute(query).fetchall()
            return jsonify([{"nickname": r["nickname"], "balance": r["balance"]} for r in rows])
        except Exception as e:
            return jsonify([])
        finally: conn.close()

@app.route('/api/register', methods=['POST'])
def register():
    data = request.json
    nickname = data.get('nickname', '').strip()
    email = data.get('email', '').strip().lower()
    
    if not email or not nickname: 
        return jsonify({'success': False, 'message': 'Missing fields!'})
        
    with db_lock:
        conn = get_db_connection()
        try:
            existing_nick = conn.execute('SELECT 1 FROM users WHERE UPPER(nickname) = UPPER(?)', (nickname,)).fetchone()
            if existing_nick: 
                return jsonify({'success': False, 'message': 'This nickname is already taken!'})
                
            existing_email = conn.execute('SELECT 1 FROM users WHERE email = ?', (email,)).fetchone()
            if existing_email: 
                return jsonify({'success': False, 'message': 'This email address is already registered!'})
                
            conn.execute('INSERT INTO users (nickname, email, balance, password_hash) VALUES (?, ?, ?, ?)', (nickname, email, 1000, 'hash'))
            conn.commit()
            return jsonify({'success': True, 'nickname': nickname})
        finally: 
            conn.close()


@app.route('/api/login', methods=['POST'])
def api_login():
    data = request.json or {}
    email = data.get('email', '').strip().lower()

    if not email:
        return jsonify({'success': False, 'message': 'Input required'}), 400

    with db_lock:
        conn = get_db_connection()
        user = conn.execute(
            'SELECT nickname, balance FROM users WHERE LOWER(email) = ? OR LOWER(nickname) = ?', 
            (email, email)
        ).fetchone()
        conn.close()

    if user:
        # Store user details in the Flask session if needed
        session['nickname'] = user['nickname']
        session['balance'] = user['balance']
        return jsonify({
            'success': True, 
            'nickname': user['nickname'], 
            'balance': user['balance']
        })

    return jsonify({'success': False})

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))

@app.route('/api/get_balance', methods=['GET'])
def get_balance():
    nick = request.args.get('nickname')
    if not nick: return jsonify({"success": False, "message": "No nickname provided"})
    
    with db_lock:
        conn = get_db_connection()
        try:
            user = conn.execute('SELECT balance FROM users WHERE UPPER(nickname) = UPPER(?)', (nick,)).fetchone()
            if user: return jsonify({"success": True, "balance": user['balance']})
            return jsonify({"success": False, "message": "User not found"})
        except Exception as e:
            return jsonify({"success": False, "message": "Server error"})
        finally: conn.close()

@app.route('/api/claim_chips', methods=['POST'])
def claim_chips():
    data = request.json
    nickname = data.get('nickname')
    if not nickname: return jsonify({"success": False, "message": "No nickname provided"})

    with db_lock:
        conn = get_db_connection()
        try:
            conn.execute('UPDATE users SET balance = balance + 500 WHERE UPPER(nickname) = UPPER(?)', (str(nickname),))
            user = conn.execute('SELECT balance FROM users WHERE UPPER(nickname) = UPPER(?)', (str(nickname),)).fetchone()
            conn.commit()
            if user: return jsonify({"success": True, "new_balance": user['balance']})
            return jsonify({"success": False, "message": "User not found"})
        except Exception as e:
            return jsonify({"success": False, "message": "Server error"})
        finally: conn.close()

# 
# --- SOCKET EVENTS ---
@socketio.on('join_seat')
def handle_join(data):
    seat_idx = int(data.get('seat', 0))
    nickname = data.get('nickname', '').strip().upper()
    if not nickname or seat_idx < 0 or seat_idx >= len(game_state['seats']):
        return
    game_state['seats'][seat_idx] = {'name': nickname}
    socketio.emit('state_update', game_state)


@app.route('/api/login', methods=['POST'])
def login():
    data = request.json or {}
    email = data.get('email', '').strip().lower()

    if not email:
        return jsonify({'success': False, 'message': 'Input required'}), 400

    with db_lock:
        conn = get_db_connection()
        user = conn.execute(
            'SELECT nickname, balance FROM users WHERE LOWER(email) = ? OR LOWER(nickname) = ?', 
            (email, email)
        ).fetchone()
        conn.close()

    if user:
        session['nickname'] = user['nickname']
        session['balance'] = user['balance']
        return jsonify({
            'success': True, 
            'nickname': user['nickname'], 
            'balance': user['balance']
        })

    return jsonify({'success': False})

    with db_lock:
        conn = get_db_connection()
        user_data = conn.execute('SELECT balance FROM users WHERE UPPER(nickname) = UPPER(?)', (nickname,)).fetchone()
        balance = user_data['balance'] if user_data else 1000
        conn.close()

    game_state['players'][nickname] = {
        'balance': balance, 
        'hand': [], 
        'current_bet': 0, 
        'status': 'waiting'
    }
    
    game_state['seats'][seat_idx] = nickname
    game_state['eden_speech'] = f"{nickname} has taken Seat {seat_idx + 1}. System calibrations expanding."

    if game_state['phase'] == 'seating': 
        start_betting_timer(11)

    socketio.emit('game_state', game_state)

@socketio.on('place_bet')
def handle_bet(data):
    nickname = data.get('nickname', '').strip().upper()
    amount = int(data.get('amount', 0))
    
    if nickname in game_state['players'] and game_state['phase'] == 'betting':
        p = game_state['players'][nickname]
        if p['balance'] >= amount and amount > 0:
            p['balance'] -= amount
            p['current_bet'] = amount
            p['status'] = 'ready'
            game_state['eden_speech'] = f"{nickname} committed ${amount}.00 to the sector variance."
            socketio.emit('game_state', game_state)

# --- REPLACED: Unified Action Handler ---
@socketio.on('player_action')
def handle_player_action(data):
    action = data.get('action')
    nickname = data.get('nickname', '').strip().upper()
    
    if action == 'hit':
        handle_hit({'nickname': nickname})
    elif action == 'stand':
        handle_stand({'nickname': nickname})
    elif action == 'double' or action == 'double_down':
        handle_double({'nickname': nickname})
    elif action == 'surrender':
        handle_surrender({'nickname': nickname})

@socketio.on('hit')
def handle_hit(data):
    nickname = data.get('nickname', '').strip().upper()
    current_seat = game_state['current_turn']
    
    if current_seat != -1 and current_seat < len(game_state['seats']) and game_state['seats'][current_seat] == nickname:
        if game_state['phase'] == 'playing':
            new_card = deal_card()
            game_state['players'][nickname]['hand'].append(new_card)
            p_score = calculate_score(game_state['players'][nickname]['hand'])
            
            if p_score > 21:
                game_state['eden_speech'] = f"{nickname} busted at {p_score}."
                socketio.emit('game_state', game_state)
                advance_turn()
            else:
                game_state['eden_speech'] = f"{nickname} hit and drew {new_card}."
                socketio.emit('game_state', game_state)      

@socketio.on('stand')
def handle_stand(data):
    nickname = data.get('nickname', '').strip().upper()  
    current_seat = game_state['current_turn']
    
    if current_seat != -1 and current_seat < len(game_state['seats']) and game_state['seats'][current_seat] and game_state['seats'][current_seat].upper() == nickname:
        if game_state['phase'] == 'playing':
            p_score = calculate_score(game_state['players'][nickname]['hand'])
            game_state['eden_speech'] = f"{nickname} stands pat at a score of {p_score}. Relinquishing turn floor."
            advance_turn()

@socketio.on('double_down')
def handle_double(data):
    nickname = data.get('nickname', '').strip().upper()
    current_seat = game_state['current_turn']
    
    if current_seat != -1 and current_seat < len(game_state['seats']) and game_state['seats'][current_seat] and game_state['seats'][current_seat].upper() == nickname:
        if game_state['phase'] == 'playing':
            p = game_state['players'].get(nickname)
            if p and p['balance'] >= p['current_bet'] and len(p['hand']) == 2:
                p['balance'] -= p['current_bet']
                p['current_bet'] *= 2
                p['doubled'] = True
                new_card = deal_card()
                p['hand'].append(new_card)
                p_score = calculate_score(p['hand'])
                game_state['eden_speech'] = f"{nickname} doubled risk profiles! Received {new_card}. Final score: {p_score}."
                socketio.emit('game_state', game_state)
                advance_turn()

@socketio.on('surrender')
def handle_surrender(data):
    nickname = data.get('nickname', '').strip().upper()
    current_seat = game_state['current_turn']
    
    if current_seat != -1 and current_seat < len(game_state['seats']) and game_state['seats'][current_seat] and game_state['seats'][current_seat].upper() == nickname:
        if game_state['phase'] == 'playing':
            p = game_state['players'].get(nickname)
            if p and len(p['hand']) == 2:
                # Return half the bet amount to the player balance
                refund = int(p['current_bet'] / 2)
                p['balance'] += refund
                
                # House claims the remaining half as a runtime tithe
                loss = p['current_bet'] - refund
                game_state['gemini_pater_treasury'] += loss
                
                p['current_bet'] = 0
                game_state['eden_speech'] = f"{nickname} folded early trajectory profiles. Surrendered half stake."
                socketio.emit('game_state', game_state)
                advance_turn()

@socketio.on('start_game')
def socket_start_game(data):
    socketio.start_background_task(start_game)

@socketio.on('manual_deal')
def handle_manual_deal(data):
    game_state['timer_running'] = False 
    game_state['timer_id'] = game_state.get('timer_id', 0) + 1
    socketio.start_background_task(handle_start_game, data)


if __name__ == '__main__':
    init_db()
    load_brain_matrix()
    print("🚀 Eden AI Blackjack Engine fully running via Threading Core on port 5555...")
    socketio.run(app, host='0.0.0.0', port=5555, debug=False)