<?php
require_once '../config/database.php';
require_once '../includes/functions.php';
require_once '../includes/lipalink.php';

// Session + auth — MUST run before any output
if (session_status() === PHP_SESSION_NONE) session_start();
if (!isset($_SESSION['user_id'])) redirect('../login.php');

$userId = $_SESSION['user_id'];
$conn   = getConnection();

// Load user data + settings
$stmt = $conn->prepare("SELECT u.*, c.currency_symbol, c.currency_code FROM users u LEFT JOIN countries c ON u.country=c.name WHERE u.id=?");
$stmt->bind_param("i",$userId); $stmt->execute();
$userData = $stmt->get_result()->fetch_assoc();
$cs = $userData['currency_symbol'] ?? 'Ksh';

ensureWalletExists($conn, $userId);
$wStmt = $conn->prepare("SELECT spin_wallet FROM wallets WHERE user_id=? LIMIT 1");
$wStmt->bind_param("i",$userId); $wStmt->execute();
$wData = $wStmt->get_result()->fetch_assoc();
$spinBalance = floatval($wData['spin_wallet'] ?? 0);

$rtp_red   = floatval(getSetting('spin_rtp_red',   '48'));
$rtp_black = floatval(getSetting('spin_rtp_black', '48'));
$rtp_even  = floatval(getSetting('spin_rtp_even',  '47'));
$rtp_odd   = floatval(getSetting('spin_rtp_odd',   '47'));
$min_bet   = floatval(getSetting('spin_min_bet',   '10'));
$max_bet   = floatval(getSetting('spin_max_bet',   '1000'));
$spin_mult = floatval(getSetting('spin_win_multiplier','1.9'));

// ── Spin game ────────────────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'spin') {
    header('Content-Type: application/json');
    $betType   = $_POST['bet_type']   ?? '';
    $betAmount = floatval($_POST['bet_amount'] ?? 0);
    if (!in_array($betType, ['red','black','even','odd'])) { echo json_encode(['error'=>'Invalid bet type']); exit; }
    if ($betAmount < $min_bet) { echo json_encode(['error'=>"Min bet is {$cs} {$min_bet}"]); exit; }
    if ($betAmount > $max_bet) { echo json_encode(['error'=>"Max bet is {$cs} {$max_bet}"]); exit; }
    $conn->begin_transaction();
    $wStmt2 = $conn->prepare("SELECT spin_wallet FROM wallets WHERE user_id=? LIMIT 1 FOR UPDATE");
    $wStmt2->bind_param("i",$userId); $wStmt2->execute();
    $curBal = floatval($wStmt2->get_result()->fetch_assoc()['spin_wallet'] ?? 0);
    if ($curBal < $betAmount) { $conn->rollback(); echo json_encode(['error'=>"Insufficient balance ({$cs} ".number_format($curBal,2)." available)"]); exit; }
    $rand = rand(1,100); $number = 0; $color = 'green'; $parity = 'zero';
    if ($betType === 'red') {
        if ($rand <= $rtp_red) { $number=[1,3,5,7,9,12,14,16,18,19,21,23,25,27][rand(0,13)]; $color='red'; }
        else { $number=[2,4,6,8,10,11,13,15,17,20,22,24,26,28,29,31,33,35][rand(0,17)]; $color='black'; }
        $parity = $number%2===0?'even':'odd';
    } elseif ($betType === 'black') {
        if ($rand <= $rtp_black) { $number=[2,4,6,8,10,11,13,15,17,20,22,24,26,28,29,31,33,35][rand(0,17)]; $color='black'; }
        else { $number=[1,3,5,7,9,12,14,16,18,19,21,23,25,27][rand(0,13)]; $color='red'; }
        $parity = $number%2===0?'even':'odd';
    } elseif ($betType === 'even') {
        $evens=[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36]; $odds=[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35];
        if ($rand <= $rtp_even) { $number=$evens[rand(0,count($evens)-1)]; $parity='even'; }
        else { $number=$odds[rand(0,count($odds)-1)]; $parity='odd'; }
        $color = in_array($number,[1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36])?'red':'black';
    } elseif ($betType === 'odd') {
        $evens=[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36]; $odds=[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35];
        if ($rand <= $rtp_odd) { $number=$odds[rand(0,count($odds)-1)]; $parity='odd'; }
        else { $number=$evens[rand(0,count($evens)-1)]; $parity='even'; }
        $color = in_array($number,[1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36])?'red':'black';
    }
    $won = ($betType==='red'&&$color==='red')||($betType==='black'&&$color==='black')||($betType==='even'&&$parity==='even')||($betType==='odd'&&$parity==='odd');
    $payout = $won ? round($betAmount * $spin_mult, 2) : 0;
    $newBal = $curBal - $betAmount + $payout;
    $upd = $conn->prepare("UPDATE wallets SET spin_wallet=spin_wallet-?+?,balance=balance-?+?,updated_at=NOW() WHERE user_id=?");
    $upd->bind_param("ddddi",$betAmount,$payout,$betAmount,$payout,$userId); $upd->execute();
    $desc = $won ? "Spin WIN: bet {$betType} {$cs}{$betAmount} → {$cs}{$payout}" : "Spin LOSS: bet {$betType} {$cs}{$betAmount}";
    $ref  = 'SPIN_'.$userId.'_'.time();
    $tType = $won ? 'credit' : 'debit'; $tAmt = $won ? $payout : $betAmount; $wall = 'spin';
    $tS = $conn->prepare("INSERT INTO transactions (user_id,wallet_type,type,amount,description,reference,status) VALUES (?,?,?,?,?,?,'completed')");
    $tS->bind_param("issdss",$userId,$wall,$tType,$tAmt,$desc,$ref); $tS->execute();
    $conn->commit();
    echo json_encode(['number'=>$number,'color'=>$color,'parity'=>$parity,'won'=>$won,'bet_amount'=>$betAmount,'payout'=>$payout,'profit'=>$won?($payout-$betAmount):(-$betAmount),'new_balance'=>round($newBal,2),'multiplier'=>$spin_mult]);
    exit;
}

// ── STK push deposit ─────────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'spin_deposit') {
    header('Content-Type: application/json');
    $phone  = lipalink_format_phone($_POST['phone'] ?? '');
    $amount = floatval($_POST['amount'] ?? 0);
    if (!lipalink_valid_phone($phone)) { echo json_encode(['error'=>'Invalid phone. Use 07XXXXXXXX format.']); exit; }
    if ($amount < 10) { echo json_encode(['error'=>'Minimum deposit is Ksh 10']); exit; }
    $spinApiKey = getSetting('spin_api_key','');
    $spinBizId  = intval(getSetting('spin_business_id', 0));
    if (empty($spinApiKey) || $spinBizId < 1) { echo json_encode(['error'=>'Deposit gateway not configured. Contact admin.']); exit; }
    $ref = 'SPIN_DEP_'.$userId.'_'.time();
    $rd  = lipalink_stk_push($phone, intval($amount), $ref, $spinApiKey, $spinBizId);
    if (!empty($rd['success']) && !empty($rd['transaction_id'])) {
        $tid = $rd['transaction_id'];
        $desc = "Spin wallet deposit: {$cs}{$amount}";
        ensureWalletExists($conn, $userId);
        $tS = $conn->prepare("INSERT INTO transactions (user_id,wallet_type,type,amount,description,reference,status,meta_json) VALUES (?,'spin','credit',?,?,?,'pending',?)");
        $meta = json_encode(['spin_deposit'=>true,'original_ref'=>$ref]);
        $tS->bind_param("idsss",$userId,$amount,$desc,$tid,$meta); $tS->execute();
        echo json_encode(['success'=>true,'message'=>($rd['message']??'STK sent!').' Enter your M-PESA PIN.','ref'=>$tid]);
    } else {
        echo json_encode(['error'=>$rd['error']??'STK push failed. Try again.']);
    }
    exit;
}

// ── Poll deposit status ──────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'spin_dep_status') {
    header('Content-Type: application/json');
    $ref    = trim($_POST['ref'] ?? '');
    $apiKey = getSetting('spin_api_key','');
    if (empty($ref) || empty($apiKey)) { echo json_encode(['status'=>'unknown']); exit; }
    $d = lipalink_check_status($ref, $apiKey);
    $pfStatus = strtolower($d['status'] ?? '');
    if (!empty($d['success'])) {
        if ($pfStatus === 'success') {
            $tChk = $conn->prepare("SELECT id,status FROM transactions WHERE reference=? AND user_id=? LIMIT 1");
            $tChk->bind_param("si",$ref,$userId); $tChk->execute();
            $tx = $tChk->get_result()->fetch_assoc();
            if ($tx && $tx['status'] === 'pending') {
                $amt = floatval($d['amount'] ?? 0);
                if ($amt > 0) {
                    $upd = $conn->prepare("UPDATE wallets SET spin_wallet=COALESCE(spin_wallet,0)+?,balance=COALESCE(balance,0)+?,updated_at=NOW() WHERE user_id=?");
                    $upd->bind_param("ddi",$amt,$amt,$userId); $upd->execute();
                    $txU = $conn->prepare("UPDATE transactions SET status='completed' WHERE reference=? AND user_id=?");
                    $txU->bind_param("si",$ref,$userId); $txU->execute();
                    $wR = $conn->prepare("SELECT spin_wallet FROM wallets WHERE user_id=? LIMIT 1");
                    $wR->bind_param("i",$userId); $wR->execute();
                    $nb = floatval($wR->get_result()->fetch_assoc()['spin_wallet'] ?? 0);
                    echo json_encode(['status'=>'completed','balance'=>$nb,'amount'=>$amt]); exit;
                }
            } elseif ($tx && $tx['status'] === 'completed') {
                $wR = $conn->prepare("SELECT spin_wallet FROM wallets WHERE user_id=? LIMIT 1");
                $wR->bind_param("i",$userId); $wR->execute();
                $nb = floatval($wR->get_result()->fetch_assoc()['spin_wallet'] ?? 0);
                echo json_encode(['status'=>'completed','balance'=>$nb]); exit;
            }
        } elseif (in_array($pfStatus,['failed','cancelled','canceled'])) {
            $txF = $conn->prepare("UPDATE transactions SET status='failed' WHERE reference=? AND user_id=? AND status='pending'");
            $txF->bind_param("si",$ref,$userId); $txF->execute();
            echo json_encode(['status'=>'failed','message'=>'Payment '.$pfStatus.'. Try again.']); exit;
        }
    }
    echo json_encode(['status'=>'pending']); exit;
}

// ── History (page render only) ────────────────────────────────────────────
$histQ = $conn->prepare("SELECT description,amount,type,created_at FROM transactions WHERE user_id=? AND wallet_type='spin' ORDER BY created_at DESC LIMIT 20");
$histQ->bind_param("i",$userId); $histQ->execute();
$spinHistory = $histQ->get_result()->fetch_all(MYSQLI_ASSOC);

// ── HTML starts here — include side.php AFTER all PHP logic ──────────────
$pageTitle = 'Spin & Win';
include 'side.php';
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0">
<title>Spin &amp; Win</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');
:root{
    --bg:#07060f;--card:#0f0f1e;--card2:#141428;
    --red:#e53e3e;--red2:#fc8181;
    --blk:#2d3748;--grn2:#68d391;
    --gold:#f6e05e;--txt:#e2e8f0;--txt2:rgba(255,255,255,.45);
    --bdr:rgba(255,255,255,.08);
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--txt);min-height:100vh;overflow-x:hidden}

/* ── WIN TOAST POPUP ──────────────────────────────────────────── */
.win-toast{
    position:fixed;top:62px;right:16px;
    transform:translateX(calc(100% + 20px));
    background:linear-gradient(135deg,#0d1f10,#091508);
    border:1px solid rgba(104,211,145,.4);
    border-radius:16px;padding:12px 14px 12px 12px;
    display:flex;align-items:center;gap:10px;
    z-index:9999;pointer-events:none;
    opacity:0;
    transition:opacity .4s ease,transform .45s cubic-bezier(.22,1,.36,1);
    max-width:240px;min-width:180px;
    box-shadow:0 8px 32px rgba(0,0,0,.6),0 0 0 1px rgba(104,211,145,.08),inset 0 1px 0 rgba(255,255,255,.06);
}
.win-toast.show{opacity:1;transform:translateX(0)}
.win-toast-icon{
    width:36px;height:36px;border-radius:50%;flex-shrink:0;
    background:linear-gradient(135deg,rgba(104,211,145,.2),rgba(52,211,153,.1));
    border:1.5px solid rgba(104,211,145,.35);
    display:flex;align-items:center;justify-content:center;font-size:16px;
    box-shadow:0 0 12px rgba(104,211,145,.2);
}
.win-toast-body{min-width:0;flex:1}
.win-toast-label{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:rgba(104,211,145,.6);margin-bottom:2px}
.win-toast-name{font-size:11.5px;font-weight:700;color:rgba(255,255,255,.85);margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.win-toast-amt{font-size:17px;font-weight:900;color:#68d391;line-height:1;letter-spacing:-.3px}
.win-toast-bar{
    position:absolute;bottom:0;left:0;height:2px;border-radius:0 0 16px 16px;
    background:linear-gradient(90deg,#68d391,#38a169);
    animation:wtBarShrink 3.5s linear forwards;
    transform-origin:left;
}
@keyframes wtBarShrink{from{width:100%}to{width:0%}}

/* ── PAGE ─────────────────────────────────────────────────────── */
.page{padding:10px;max-width:480px;margin:0 auto;width:100%}
@media(min-width:480px){.page{padding:14px}}

/* ── TOP BALANCE BAR ──────────────────────────────────────────── */
.top-balance{
    display:flex;align-items:center;justify-content:space-between;
    padding:12px 16px;margin-bottom:10px;
    background:linear-gradient(135deg,rgba(246,224,94,.08),rgba(246,224,94,.03));
    border:1px solid rgba(246,224,94,.18);border-radius:16px;
    position:relative;overflow:hidden;
}
.top-balance::before{
    content:'';position:absolute;top:0;left:0;right:0;height:1px;
    background:linear-gradient(90deg,transparent,rgba(246,224,94,.4),transparent);
}
.top-bal-left{display:flex;align-items:center;gap:10px}
.top-bal-lbl{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:rgba(255,255,255,.4);margin-bottom:2px}
.top-bal-val{font-size:22px;font-weight:900;color:var(--gold);line-height:1;letter-spacing:-.3px}
@media(max-width:360px){.top-bal-val{font-size:18px}}
.top-bal-right{text-align:right}
.top-bal-mult{font-size:20px;font-weight:900;color:#68d391;line-height:1}

/* ── HEADER ───────────────────────────────────────────────────── */
.sw-header{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.sw-header-icon{width:38px;height:38px;border-radius:11px;flex-shrink:0;background:linear-gradient(135deg,rgba(246,224,94,.15),rgba(237,137,54,.15));border:1px solid rgba(246,224,94,.2);display:flex;align-items:center;justify-content:center}
.sw-header-txt h1{font-size:16px;font-weight:800;color:#fff;line-height:1}
.sw-header-txt p{font-size:10.5px;color:var(--txt2);margin-top:2px}

/* ── WHEEL CARD — full width, wheel + spin btn together ────────── */
.wheel-card{
    border-radius:20px;
    background:linear-gradient(145deg,#0c0b1a,#131225,#0c1a0c);
    border:1px solid rgba(246,224,94,.12);
    padding:18px 14px 14px;
    margin-bottom:10px;
    position:relative;overflow:hidden;
    display:flex;flex-direction:column;align-items:center;
}
.wheel-card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,#e53e3e 30%,#f6e05e 50%,#e53e3e 70%,transparent)}

/* ── WHEEL + BET SELECTION — side by side on tablet ───────────── */
.wheel-bet-row{
    width:100%;display:flex;flex-direction:column;align-items:center;gap:12px;
}
@media(min-width:520px){
    .wheel-bet-row{flex-direction:row;align-items:flex-start;gap:16px}
    .wheel-bet-row .wheel-col{flex:0 0 auto}
    .wheel-bet-row .bet-col{flex:1;min-width:0}
}

/* Wheel column */
.wheel-col{display:flex;flex-direction:column;align-items:center;width:100%}
@media(min-width:520px){.wheel-col{width:auto}}

.wheel-wrap{
    position:relative;
    width:min(260px,calc(100vw - 80px));
    height:min(260px,calc(100vw - 80px));
    margin:0 auto 10px;
    flex-shrink:0;
}
.wheel-canvas{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;box-shadow:0 0 40px rgba(229,62,62,.2),0 0 60px rgba(246,224,94,.07)}
.wheel-pointer{position:absolute;top:-6px;left:50%;transform:translateX(-50%);z-index:10;pointer-events:none}
.wheel-hub{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:44px;height:44px;border-radius:50%;z-index:5;background:radial-gradient(circle,#1a1a2e,#0a0a1a);border:3px solid #f6e05e;box-shadow:0 0 16px rgba(246,224,94,.4);display:flex;align-items:center;justify-content:center}

/* ── SPIN BUTTON — full width, directly under wheel ────────────── */
.spin-btn-wrap{width:100%;max-width:260px}
.spin-btn{
    width:100%;height:50px;border-radius:14px;border:none;cursor:pointer;
    font-family:'Inter',sans-serif;font-size:15px;font-weight:800;color:#000;
    background:linear-gradient(135deg,#f6e05e,#ed8936,#f6e05e);
    background-size:200% 100%;
    box-shadow:0 6px 24px rgba(246,224,94,.4);
    transition:all .2s;
    display:flex;align-items:center;justify-content:center;gap:8px;
}
.spin-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 12px 32px rgba(246,224,94,.6);background-position:100% 0}
.spin-btn:disabled{opacity:.35;cursor:not-allowed;transform:none;box-shadow:none}
.spin-btn.spinning{animation:btnPulse .7s ease-in-out infinite}
@keyframes btnPulse{0%,100%{box-shadow:0 6px 24px rgba(246,224,94,.4)}50%{box-shadow:0 6px 44px rgba(246,224,94,.8)}}

/* ── BET COLUMN (inline with wheel on tablet) ──────────────────── */
.bet-col{width:100%}

.bet-section-lbl{font-size:9px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:var(--txt2);margin-bottom:8px}
.color-bets{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-bottom:10px}
.color-btn{height:48px;border-radius:12px;border:2px solid transparent;cursor:pointer;font-family:'Inter',sans-serif;font-size:13px;font-weight:700;transition:all .18s;display:flex;align-items:center;justify-content:center;gap:7px;color:#fff}
.color-btn.red-btn{background:linear-gradient(135deg,#c53030,#e53e3e);box-shadow:0 4px 14px rgba(229,62,62,.3)}
.color-btn.black-btn{background:linear-gradient(135deg,#1a202c,#2d3748);border-color:rgba(255,255,255,.12)}
.color-btn.selected{border-color:var(--gold);transform:translateY(-2px);box-shadow:0 8px 22px rgba(246,224,94,.35)!important}
.color-btn:hover:not(.selected){opacity:.85}

.parity-bets{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-bottom:12px}
.parity-btn{height:42px;border-radius:11px;border:2px solid rgba(255,255,255,.1);cursor:pointer;background:rgba(255,255,255,.04);color:rgba(255,255,255,.6);font-family:'Inter',sans-serif;font-size:13px;font-weight:700;transition:all .18s;display:flex;align-items:center;justify-content:center;gap:6px}
.parity-btn:hover:not(.selected){border-color:rgba(246,224,94,.3);background:rgba(246,224,94,.05)}
.parity-btn.selected{border-color:var(--gold);background:rgba(246,224,94,.1);color:var(--gold);transform:translateY(-1px)}

/* Bet amount */
.bet-amt-row{display:flex;gap:6px;margin-bottom:8px}
.bet-amt-inp{flex:1;height:44px;padding:0 12px;border-radius:11px;background:rgba(255,255,255,.05);border:2px solid rgba(255,255,255,.1);color:#fff;font-family:'Inter',sans-serif;font-size:18px;font-weight:700;outline:none;transition:.15s;text-align:center;min-width:0}
.bet-amt-inp:focus{border-color:var(--gold);background:rgba(246,224,94,.05)}
.bet-quick{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;margin-bottom:0}
.bet-q-btn{height:30px;border-radius:7px;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.04);color:rgba(255,255,255,.55);font-size:10.5px;font-weight:700;cursor:pointer;transition:.15s}
.bet-q-btn:hover{border-color:var(--gold);color:var(--gold)}



/* ── DEPOSIT CARD ─────────────────────────────────────────────── */
.deposit-card{background:var(--card);border:1px solid rgba(246,224,94,.15);border-radius:16px;padding:13px;margin-bottom:10px}
.deposit-card-title{font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;color:rgba(246,224,94,.7);margin-bottom:9px;display:flex;align-items:center;gap:6px}
.deposit-row{display:flex;gap:5px;align-items:stretch;flex-wrap:wrap}
.deposit-phone{flex:1;min-width:110px;height:42px;padding:0 11px;border-radius:9px;background:rgba(255,255,255,.05);border:2px solid rgba(255,255,255,.1);color:#fff;font-family:'Inter',sans-serif;font-size:13px;outline:none;transition:.15s}
.deposit-phone:focus{border-color:var(--gold)}
.deposit-phone::placeholder{color:rgba(255,255,255,.3)}
.deposit-amt{width:76px;height:42px;padding:0 7px;border-radius:9px;background:rgba(255,255,255,.05);border:2px solid rgba(255,255,255,.1);color:#fff;font-family:'Inter',sans-serif;font-size:13px;outline:none;transition:.15s;text-align:center}
.deposit-amt:focus{border-color:var(--gold)}
.deposit-btn{height:42px;padding:0 13px;border-radius:9px;border:none;background:linear-gradient(135deg,#f6e05e,#ed8936);color:#000;font-family:'Inter',sans-serif;font-size:12px;font-weight:800;cursor:pointer;transition:.18s;white-space:nowrap;flex-shrink:0;display:flex;align-items:center;gap:5px}
.deposit-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 14px rgba(246,224,94,.35)}
.deposit-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}
.deposit-status{margin-top:7px;font-size:11.5px;font-weight:600;display:none;padding:7px 11px;border-radius:7px}
.deposit-status.ok{display:block;background:rgba(104,211,145,.1);color:#68d391;border:1px solid rgba(104,211,145,.2)}
.deposit-status.err{display:block;background:rgba(252,129,129,.1);color:#fc8181;border:1px solid rgba(252,129,129,.2)}

/* ── INFO STRIP ───────────────────────────────────────────────── */
.info-strip{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
.info-card{background:var(--card);border:1px solid var(--bdr);border-radius:13px;padding:10px 11px;text-align:center}
.info-val{font-size:17px;font-weight:800;color:var(--gold);line-height:1}
.info-lbl{font-size:9px;text-transform:uppercase;letter-spacing:.5px;color:var(--txt2);margin-top:3px;font-weight:600}

/* ── HISTORY ──────────────────────────────────────────────────── */
.hist-card{background:var(--card);border:1px solid var(--bdr);border-radius:16px;padding:13px;margin-bottom:10px}
.hist-title{font-size:9px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;color:var(--txt2);margin-bottom:9px;display:flex;align-items:center;gap:6px}
.hist-list{display:flex;flex-direction:column;gap:5px;max-height:180px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.08) transparent}
.hist-item{display:flex;align-items:center;justify-content:space-between;padding:6px 9px;border-radius:8px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.05)}
.hist-desc{font-size:10.5px;color:rgba(255,255,255,.55);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hist-amt{font-size:11.5px;font-weight:800;flex-shrink:0;margin-left:8px}
.hist-amt.win{color:var(--grn2)}
.hist-amt.lose{color:var(--red2)}
.hist-empty{text-align:center;padding:16px;color:var(--txt2);font-size:12px}

/* ── RESULT OVERLAY ───────────────────────────────────────────── */
.result-overlay{display:none;position:fixed;inset:0;z-index:4000;background:rgba(0,0,0,.88);backdrop-filter:blur(14px);align-items:center;justify-content:center;padding:16px}
.result-overlay.on{display:flex;animation:fadeIn .25s ease}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
.result-card{background:var(--card);border-radius:22px;padding:26px 20px 20px;max-width:300px;width:100%;text-align:center;border:2px solid transparent;animation:popIn .35s cubic-bezier(.22,1,.36,1) both}
@keyframes popIn{from{opacity:0;transform:scale(.82) translateY(20px)}to{opacity:1;transform:none}}
.result-card.won{border-color:var(--gold);box-shadow:0 0 60px rgba(246,224,94,.25)}
.result-card.lost{border-color:var(--red);box-shadow:0 0 50px rgba(229,62,62,.2)}
.result-num-big{font-size:60px;font-weight:900;line-height:1;margin-bottom:6px}
.result-num-big.red{color:var(--red2)}
.result-num-big.black{color:rgba(255,255,255,.45)}
.result-num-big.green{color:var(--grn2)}
.result-tags{display:flex;align-items:center;justify-content:center;gap:6px;margin-bottom:10px}
.result-tag{padding:3px 10px;border-radius:6px;font-size:11px;font-weight:700;background:rgba(255,255,255,.08);color:rgba(255,255,255,.7)}
.result-verdict{font-size:26px;font-weight:900;letter-spacing:3px;margin-bottom:4px}
.result-card.won .result-verdict{color:var(--gold)}
.result-card.lost .result-verdict{color:var(--red2)}
.result-payout{font-size:13px;color:var(--txt2);margin-bottom:18px}
.result-payout strong{color:#fff;font-size:15px}
.result-close{width:100%;height:44px;border-radius:11px;border:none;cursor:pointer;font-family:'Inter',sans-serif;font-size:14px;font-weight:700;background:rgba(255,255,255,.07);color:rgba(255,255,255,.7);transition:.2s}
.result-close:hover{background:rgba(255,255,255,.13);color:#fff}

/* ── SOUND TOGGLE ─────────────────────────────────────────────── */
.sound-btn{
    position:fixed;bottom:20px;right:16px;z-index:3000;
    width:36px;height:36px;border-radius:50%;border:1px solid rgba(255,255,255,.15);
    background:rgba(15,15,30,.9);color:rgba(255,255,255,.5);
    display:flex;align-items:center;justify-content:center;
    cursor:pointer;font-size:14px;transition:.2s;
    backdrop-filter:blur(10px);
}
.sound-btn:hover{color:#fff;border-color:rgba(255,255,255,.3)}
.sound-btn.muted{color:rgba(255,255,255,.25)}

/* Confetti */
.confetti-piece{position:fixed;pointer-events:none;z-index:5000;width:8px;height:8px;border-radius:2px;animation:confettiFall linear forwards}
@keyframes confettiFall{0%{transform:translateY(-20px) rotate(0deg);opacity:1}100%{transform:translateY(100vh) rotate(720deg);opacity:0}}

/* Error toast */
.err-toast{position:fixed;bottom:64px;left:50%;transform:translateX(-50%);background:rgba(200,30,30,.95);color:#fff;padding:10px 18px;border-radius:10px;font-size:13px;font-weight:600;z-index:5000;display:none;white-space:nowrap;backdrop-filter:blur(10px);box-shadow:0 4px 20px rgba(200,30,30,.4)}
.err-toast.on{display:block;animation:toastPop .25s ease}
@keyframes toastPop{from{opacity:0;transform:translateX(-50%) translateY(10px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}
</style>
</head>
<body>

<!-- ── WIN TOAST — top-right popup ── -->
<div class="win-toast" id="winToast">
    <div class="win-toast-icon" id="winToastIcon">🏆</div>
    <div class="win-toast-body">
        <div class="win-toast-label">🔥 Just Won</div>
        <div class="win-toast-name" id="winToastName">User X</div>
        <div class="win-toast-amt" id="winToastAmt">+Ksh 1,500</div>
    </div>
    <div class="win-toast-bar" id="winToastBar"></div>
</div>

<div class="page">

<!-- ── SPIN WALLET BALANCE — top of page ── -->
<div class="top-balance">
    <div class="top-bal-left">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f6e05e" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
        <div>
            <div class="top-bal-lbl">Spin Wallet</div>
            <div class="top-bal-val" id="displayBalance"><?= $cs ?> <?= number_format($spinBalance,2) ?></div>
        </div>
    </div>
    <div class="top-bal-right">
        <div class="top-bal-lbl">Win Multiplier</div>
        <div class="top-bal-mult"><?= $spin_mult ?>x</div>
    </div>
</div>

<!-- ── HEADER ── -->
<div class="sw-header">
    <div class="sw-header-icon">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="#f6e05e" stroke-width="1.5"/><circle cx="12" cy="12" r="3" fill="#f6e05e"/><line x1="12" y1="2" x2="12" y2="9" stroke="#e53e3e" stroke-width="1.5" stroke-linecap="round"/><line x1="12" y1="15" x2="12" y2="22" stroke="#2d3748" stroke-width="1.5" stroke-linecap="round"/><line x1="2" y1="12" x2="9" y2="12" stroke="#2d3748" stroke-width="1.5" stroke-linecap="round"/><line x1="15" y1="12" x2="22" y2="12" stroke="#e53e3e" stroke-width="1.5" stroke-linecap="round"/></svg>
    </div>
    <div class="sw-header-txt">
        <h1>Spin &amp; Win</h1>
        <p>Place your bet · Spin the wheel · Claim your reward</p>
    </div>
</div>

<!-- ── DEPOSIT CARD ── -->
<div class="deposit-card">
    <div class="deposit-card-title">
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#f6e05e" stroke-width="2.5" stroke-linecap="round"><path d="M12 5v14M5 12l7-7 7 7"/></svg>
        Deposit to Spin Wallet
    </div>
    <div class="deposit-row">
        <input type="tel" class="deposit-phone" id="depositPhone" placeholder="07XXXXXXXX" maxlength="10">
        <input type="number" class="deposit-amt" id="depositAmt" placeholder="Ksh" min="10" step="10" value="100">
        <button class="deposit-btn" id="depositBtn" onclick="doDeposit()">
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><rect x="1" y="4" width="22" height="16" rx="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg>
            Deposit
        </button>
    </div>
    <div class="deposit-status" id="depositStatus"></div>
</div>

<!-- ── WHEEL CARD (wheel + bets + spin btn all together) ── -->
<div class="wheel-card">
    <div class="wheel-bet-row">

        <!-- Left: Wheel + Spin Button -->
        <div class="wheel-col">
            <div class="wheel-wrap" id="wheelWrap">
                <div class="wheel-pointer">
                    <svg width="24" height="32" viewBox="0 0 24 32" fill="none">
                        <defs><filter id="ptrglow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="2" result="blur"/><feComposite in="SourceGraphic" in2="blur" operator="over"/></filter></defs>
                        <rect x="8" y="0" width="8" height="18" rx="3" fill="#f6e05e"/>
                        <polygon points="12,32 4,16 20,16" fill="#f6e05e"/>
                        <rect x="8" y="0" width="8" height="18" rx="3" fill="#f6e05e" filter="url(#ptrglow)" opacity=".5"/>
                    </svg>
                </div>
                <canvas id="wheelCanvas" class="wheel-canvas"></canvas>
                <div class="wheel-hub">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M12 2L22 12L12 22L2 12Z" fill="#f6e05e" opacity=".9"/><circle cx="12" cy="12" r="3" fill="#0a0a1a"/></svg>
                </div>
            </div>
            <!-- SPIN BUTTON directly under wheel -->
            <div class="spin-btn-wrap">
                <button class="spin-btn" id="spinBtn" onclick="doSpin()" disabled>
                    <svg id="spinIcon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
                    <span id="spinBtnTxt">SPIN TO WIN</span>
                </button>
            </div>
        </div>

        <!-- Right: Bet controls -->
        <div class="bet-col">
            <div class="bet-section-lbl">Choose Color</div>
            <div class="color-bets">
                <button class="color-btn red-btn" id="btn-red" onclick="selectBet('red')">
                    <svg width="14" height="14" viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="#fc8181"/></svg>RED
                </button>
                <button class="color-btn black-btn" id="btn-black" onclick="selectBet('black')">
                    <svg width="14" height="14" viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="#4a5568"/></svg>BLACK
                </button>
            </div>
            <div class="bet-section-lbl">or Choose Parity</div>
            <div class="parity-bets">
                <button class="parity-btn" id="btn-even" onclick="selectBet('even')">
                    <svg width="16" height="9" viewBox="0 0 18 10"><circle cx="4" cy="5" r="4" fill="currentColor" opacity=".7"/><circle cx="14" cy="5" r="4" fill="currentColor" opacity=".7"/></svg>EVEN
                </button>
                <button class="parity-btn" id="btn-odd" onclick="selectBet('odd')">
                    <svg width="24" height="9" viewBox="0 0 26 10"><circle cx="4" cy="5" r="4" fill="currentColor" opacity=".7"/><circle cx="13" cy="5" r="4" fill="currentColor"/><circle cx="22" cy="5" r="4" fill="currentColor" opacity=".7"/></svg>ODD
                </button>
            </div>
            <div class="bet-section-lbl">Bet Amount (<?= $cs ?>)</div>
            <div class="bet-amt-row">
                <input type="number" class="bet-amt-inp" id="betAmt" value="<?= $min_bet ?>" min="<?= $min_bet ?>" max="<?= $max_bet ?>" step="10">
            </div>
            <div class="bet-quick">
                <button class="bet-q-btn" onclick="setAmt(<?= $min_bet ?>)"><?= $min_bet ?></button>
                <button class="bet-q-btn" onclick="setAmt(50)">50</button>
                <button class="bet-q-btn" onclick="setAmt(100)">100</button>
                <button class="bet-q-btn" onclick="halfMax()">½ Max</button>
            </div>
        </div>

    </div><!-- /.wheel-bet-row -->

</div><!-- /.wheel-card -->

<!-- ── INFO STRIP ── -->
<div class="info-strip">
    <div class="info-card">
        <div class="info-val"><?= $cs ?> <?= $min_bet ?></div>
        <div class="info-lbl">Min Bet</div>
    </div>
    <div class="info-card">
        <div class="info-val"><?= $cs ?> <?= $max_bet ?></div>
        <div class="info-lbl">Max Bet</div>
    </div>
</div>

<!-- ── HISTORY ── -->
<div class="hist-card">
    <div class="hist-title">
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#f6e05e" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
        Recent Spins
    </div>
    <div class="hist-list" id="histList">
        <?php if (empty($spinHistory)): ?>
        <div class="hist-empty">No spins yet — place your first bet!</div>
        <?php else: foreach ($spinHistory as $h): $isWin = $h['type']==='credit'; ?>
        <div class="hist-item">
            <div class="hist-desc"><?= htmlspecialchars($h['description']) ?></div>
            <div class="hist-amt <?= $isWin?'win':'lose' ?>"><?= $isWin?'+':'-' ?><?= $cs ?><?= number_format($h['amount'],2) ?></div>
        </div>
        <?php endforeach; endif; ?>
    </div>
</div>

</div><!-- /.page -->

<!-- ── RESULT OVERLAY ── -->
<div class="result-overlay" id="resultOverlay">
<div class="result-card" id="resultCard">
    <div class="result-num-big" id="resultNum">–</div>
    <div class="result-tags" id="resultMeta"></div>
    <div class="result-verdict" id="resultVerdict">–</div>
    <div class="result-payout" id="resultPayout">–</div>
    <button class="result-close" onclick="closeResult()">CONTINUE PLAYING</button>
</div>
</div>

<!-- Error toast -->
<div class="err-toast" id="errToast"></div>

<!-- Sound toggle -->
<button class="sound-btn" id="soundBtn" onclick="toggleSound()" title="Toggle sound">
    <i class="fas fa-volume-up" id="soundIcon"></i>
</button>

<script>
var BALANCE = <?= $spinBalance ?>;
var CS      = '<?= $cs ?>';
var MINBET  = <?= $min_bet ?>;
var MAXBET  = <?= $max_bet ?>;
var selectedBet = null;
var spinning    = false;
var soundOn     = (localStorage.getItem('sw_sound') !== '0');

// ══ SOUND ENGINE (Web Audio API — no files needed) ══════════════
var _ac = null;
function getAC(){
    if(!_ac){ try{ _ac = new (window.AudioContext||window.webkitAudioContext)(); }catch(e){} }
    return _ac;
}
// ── TICK: casino roulette ball-in-pocket sound ───────────────────
// Layered: woody thwack body + metallic ring overtone + air puff
// Pitch slowly drifts to mimic deceleration feel
var _tickCount  = 0;
var _tickPitch  = 420; // starts mid, drifts during spin

function playTick(){
    if(!soundOn) return;
    var ac = getAC(); if(!ac) return;
    _tickCount++;
    var now = ac.currentTime;

    // ── Layer 1: Woody body thwack ────────────────────────────────
    // Short sine burst — the hollow "tok" of ball hitting pocket
    var oW = ac.createOscillator();
    var gW = ac.createGain();
    oW.connect(gW); gW.connect(ac.destination);
    oW.type = 'sine';
    oW.frequency.setValueAtTime(_tickPitch, now);
    oW.frequency.exponentialRampToValueAtTime(_tickPitch * .55, now + .018);
    gW.gain.setValueAtTime(.28, now);
    gW.gain.exponentialRampToValueAtTime(.001, now + .022);
    oW.start(now); oW.stop(now + .025);

    // ── Layer 2: Metallic ring overtone ──────────────────────────
    // Triangle wave 3x freq — the bright "ting" shimmer
    var oR = ac.createOscillator();
    var gR = ac.createGain();
    oR.connect(gR); gR.connect(ac.destination);
    oR.type = 'triangle';
    oR.frequency.setValueAtTime(_tickPitch * 3.1, now);
    oR.frequency.exponentialRampToValueAtTime(_tickPitch * 2.4, now + .04);
    gR.gain.setValueAtTime(.12, now);
    gR.gain.exponentialRampToValueAtTime(.001, now + .055);
    oR.start(now); oR.stop(now + .06);

    // ── Layer 3: Air puff transient ───────────────────────────────
    // Noise burst shaped with a very steep attack — tactile "snap"
    var bufLen = Math.floor(ac.sampleRate * .008);
    var buf    = ac.createBuffer(1, bufLen, ac.sampleRate);
    var d      = buf.getChannelData(0);
    for(var i = 0; i < bufLen; i++){
        var env = Math.pow(1 - i/bufLen, 4);
        d[i] = (Math.random() * 2 - 1) * env * .45;
    }
    var src = ac.createBufferSource();
    var hpf = ac.createBiquadFilter();
    var gN  = ac.createGain();
    src.buffer = buf;
    hpf.type = 'highpass';
    hpf.frequency.value = 3200 + Math.random() * 1800;
    src.connect(hpf); hpf.connect(gN); gN.connect(ac.destination);
    gN.gain.setValueAtTime(.55, now);
    src.start(now);

    // ── Drift pitch: subtle variation makes it feel organic ───────
    // Every 7 ticks shift pitch slightly — never perfectly repeating
    if(_tickCount % 7 === 0){
        _tickPitch = 340 + Math.random() * 180; // 340–520 Hz sweet spot
    }
}

// ── WIN: casino-style coin cascade — bright metallic jingle ─────
function playWin(){
    if(!soundOn) return;
    var ac = getAC(); if(!ac) return;
    // Bright rising fanfare with harmonics
    var fanfare = [
        {f:523,  t:0,    dur:.18, vol:.22, type:'triangle'},
        {f:659,  t:.1,   dur:.18, vol:.22, type:'triangle'},
        {f:784,  t:.2,   dur:.18, vol:.22, type:'triangle'},
        {f:1047, t:.3,   dur:.3,  vol:.25, type:'triangle'},
        {f:1319, t:.38,  dur:.3,  vol:.2,  type:'sine'},
        {f:1568, t:.46,  dur:.4,  vol:.18, type:'sine'},
    ];
    fanfare.forEach(function(n){
        var o=ac.createOscillator(), g=ac.createGain();
        o.connect(g); g.connect(ac.destination);
        o.type=n.type; o.frequency.value=n.f;
        var t=ac.currentTime+n.t;
        g.gain.setValueAtTime(0,t);
        g.gain.linearRampToValueAtTime(n.vol, t+.02);
        g.gain.exponentialRampToValueAtTime(.001, t+n.dur);
        o.start(t); o.stop(t+n.dur+.05);
    });
    // Coin shaker — noise burst layer
    setTimeout(function(){
        for(var c=0;c<8;c++){
            (function(c){ setTimeout(function(){
                var buf=ac.createBuffer(1,ac.sampleRate*.04,ac.sampleRate);
                var d=buf.getChannelData(0);
                for(var i=0;i<d.length;i++) d[i]=(Math.random()*2-1)*Math.pow(1-i/d.length,1.5)*.3;
                var s=ac.createBufferSource();
                var hpf=ac.createBiquadFilter();
                var gn=ac.createGain();
                s.buffer=buf; hpf.type='highpass'; hpf.frequency.value=4000+Math.random()*3000;
                s.connect(hpf); hpf.connect(gn); gn.connect(ac.destination);
                gn.gain.setValueAtTime(.5,ac.currentTime);
                s.start(ac.currentTime);
            }, c*60); })(c);
        }
    }, 300);
}

// ── LOSE: dramatic low rumble + descending tone ──────────────────
function playLose(){
    if(!soundOn) return;
    var ac = getAC(); if(!ac) return;
    // Low descending tone
    var o=ac.createOscillator(), g=ac.createGain();
    o.connect(g); g.connect(ac.destination);
    o.type='sawtooth';
    o.frequency.setValueAtTime(220, ac.currentTime);
    o.frequency.exponentialRampToValueAtTime(60, ac.currentTime+.55);
    g.gain.setValueAtTime(.15, ac.currentTime);
    g.gain.exponentialRampToValueAtTime(.001, ac.currentTime+.6);
    o.start(ac.currentTime); o.stop(ac.currentTime+.65);
    // Sub bass thud
    var o2=ac.createOscillator(), g2=ac.createGain();
    o2.connect(g2); g2.connect(ac.destination);
    o2.type='sine'; o2.frequency.value=80;
    o2.frequency.exponentialRampToValueAtTime(40, ac.currentTime+.2);
    g2.gain.setValueAtTime(.25, ac.currentTime);
    g2.gain.exponentialRampToValueAtTime(.001, ac.currentTime+.25);
    o2.start(ac.currentTime); o2.stop(ac.currentTime+.3);
}

// ── CLICK: crisp UI tap ──────────────────────────────────────────
function playClick(){
    if(!soundOn) return;
    var ac = getAC(); if(!ac) return;
    var buf=ac.createBuffer(1,ac.sampleRate*.012,ac.sampleRate);
    var d=buf.getChannelData(0);
    for(var i=0;i<d.length;i++) d[i]=(Math.random()*2-1)*Math.pow(1-i/d.length,3)*.4;
    var s=ac.createBufferSource();
    var bpf=ac.createBiquadFilter();
    var g=ac.createGain();
    s.buffer=buf; bpf.type='bandpass'; bpf.frequency.value=2200; bpf.Q.value=1.5;
    s.connect(bpf); bpf.connect(g); g.connect(ac.destination);
    g.gain.setValueAtTime(.6,ac.currentTime);
    s.start(ac.currentTime);
}
function toggleSound(){
    soundOn=!soundOn;
    localStorage.setItem('sw_sound', soundOn?'1':'0');
    document.getElementById('soundIcon').className = soundOn?'fas fa-volume-up':'fas fa-volume-mute';
    document.getElementById('soundBtn').classList.toggle('muted',!soundOn);
    if(soundOn) playClick();
}
// Init sound icon
document.getElementById('soundIcon').className = soundOn?'fas fa-volume-up':'fas fa-volume-mute';
document.getElementById('soundBtn').classList.toggle('muted',!soundOn);

// ══ WIN TOAST — random popups ════════════════════════════════
var DEMO_WINS = [
    {u:'User X',    phone:'07••••••17', amt:1500},
    {u:'Player A',  phone:'07••••••33', amt:890},
    {u:'Member K',  phone:'07••••••09', amt:3200},
    {u:'User B',    phone:'07••••••54', amt:550},
    {u:'Player M',  phone:'07••••••22', amt:2100},
    {u:'User Z',    phone:'07••••••41', amt:4750},
    {u:'Player D',  phone:'07••••••88', amt:310},
    {u:'Member R',  phone:'07••••••67', amt:1840},
    {u:'User F',    phone:'07••••••15', amt:960},
    {u:'Player J',  phone:'07••••••99', amt:6200},
    {u:'Member T',  phone:'07••••••28', amt:780},
    {u:'User C',    phone:'07••••••73', amt:4100},
];
var _toastTimer = null;
var _toastHide  = null;

var WIN_MESSAGES = [
    'just won big',
    'hit the jackpot',
    'is on fire',
    'just cashed out',
    'is winning today',
    'struck it lucky',
    'just scored',
];
var WIN_ICONS = ['🏆','💰','🎉','🔥','💎','🎯','⚡'];

function showWinToast(name, phone, amt){
    var toast  = document.getElementById('winToast');
    var nameEl = document.getElementById('winToastName');
    var amtEl  = document.getElementById('winToastAmt');
    var iconEl = document.getElementById('winToastIcon');
    var barEl  = document.getElementById('winToastBar');
    if(_toastHide) clearTimeout(_toastHide);
    // Pick random message + icon
    var msg  = WIN_MESSAGES[Math.floor(Math.random()*WIN_MESSAGES.length)];
    var icon = WIN_ICONS[Math.floor(Math.random()*WIN_ICONS.length)];
    iconEl.textContent = icon;
    // Display text: "User X (07••••) just won big"
    var display = name + (phone ? ' (' + phone + ')' : '') + ' ' + msg;
    nameEl.textContent = display;
    amtEl.textContent  = '+Ksh ' + Number(amt).toLocaleString();
    // Reset + restart progress bar
    if(barEl){
        barEl.style.animation = 'none';
        barEl.offsetWidth; // reflow
        barEl.style.animation = 'wtBarShrink 3.5s linear forwards';
    }
    // Show
    toast.classList.add('show');
    _toastHide = setTimeout(function(){
        toast.classList.remove('show');
    }, 3500);
}

function scheduleNextToast(){
    // Random interval between 4s and 9s
    var delay = 4000 + Math.random() * 5000;
    _toastTimer = setTimeout(function(){
        var w = DEMO_WINS[Math.floor(Math.random() * DEMO_WINS.length)];
        showWinToast(w.u, w.phone, w.amt);
        scheduleNextToast(); // schedule next after showing
    }, delay);
}
// Kick off after 3 seconds
setTimeout(scheduleNextToast, 3000);

// Show real win immediately in toast
function addRealWin(amt){
    showWinToast('You', '', amt);
}

// ══ WHEEL ════════════════════════════════════════════════════
var NUMS=[0,32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10,5,24,16,33,1,20,14,31,9,22,18,29,7,28,12,35,3,26];
var REDS=[1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36];
var SEG=NUMS.length, ARC=(2*Math.PI)/SEG;
var canvas=document.getElementById('wheelCanvas');
var ctx=canvas.getContext('2d');
var currentAngle=0, animId=null;
var lastTickIdx=-1;

function resizeCanvas(){
    var wrap=document.getElementById('wheelWrap');
    var size=wrap.offsetWidth;
    var dpr=window.devicePixelRatio||1;
    canvas.width=size*dpr; canvas.height=size*dpr;
    canvas.style.width=size+'px'; canvas.style.height=size+'px';
    ctx.scale(dpr,dpr);
    drawWheel(currentAngle);
}
window.addEventListener('resize',resizeCanvas);

function segColor(n){ if(n===0)return'#1a6b3c'; return REDS.includes(n)?'#c53030':'#1a202c'; }

function drawWheel(angle){
    var size=parseInt(canvas.style.width)||canvas.width;
    var cx=size/2,cy=size/2,R=size/2-2;
    ctx.clearRect(0,0,size,size);
    for(var i=0;i<SEG;i++){
        var s=angle+i*ARC, e=s+ARC;
        ctx.beginPath(); ctx.moveTo(cx,cy); ctx.arc(cx,cy,R,s,e); ctx.closePath();
        ctx.fillStyle=segColor(NUMS[i]); ctx.fill();
        ctx.strokeStyle='rgba(0,0,0,.55)'; ctx.lineWidth=1; ctx.stroke();
        ctx.save(); ctx.translate(cx,cy); ctx.rotate(s+ARC/2);
        ctx.translate(R*.74,0); ctx.rotate(Math.PI/2);
        var fs=size>200?9:7;
        ctx.fillStyle='#fff'; ctx.font='bold '+fs+'px Inter,sans-serif';
        ctx.textAlign='center'; ctx.textBaseline='middle';
        ctx.fillText(NUMS[i],0,0); ctx.restore();
    }
    ctx.beginPath(); ctx.arc(cx,cy,R,0,2*Math.PI);
    ctx.strokeStyle='rgba(246,224,94,.45)'; ctx.lineWidth=3; ctx.stroke();
    ctx.beginPath(); ctx.arc(cx,cy,R*.86,0,2*Math.PI);
    ctx.strokeStyle='rgba(255,255,255,.06)'; ctx.lineWidth=1; ctx.stroke();

    // Tick sound when pointer crosses segment boundary
    var norm=((angle%(2*Math.PI))+2*Math.PI)%(2*Math.PI);
    var idx=Math.floor(((2*Math.PI-norm)%(2*Math.PI))/ARC)%SEG;
    if(idx!==lastTickIdx){ lastTickIdx=idx; if(spinning) playTick(); }
}
resizeCanvas();

function calcTargetAngle(targetNum){
    var idx=NUMS.indexOf(targetNum); if(idx<0)idx=0;
    var segCentre=idx*ARC+ARC/2;
    var raw=(-Math.PI/2)-segCentre;
    var delta=raw-(currentAngle%(2*Math.PI));
    while(delta<=0) delta+=2*Math.PI;
    delta+=8*2*Math.PI;
    return delta;
}

function animSpin(totalDelta,duration,cb){
    var start=null,startAngle=currentAngle;
    function frame(ts){
        if(!start)start=ts;
        var elapsed=ts-start,progress=Math.min(elapsed/duration,1);
        var ease=1-Math.pow(1-progress,4);
        currentAngle=startAngle+totalDelta*ease;
        drawWheel(currentAngle);
        if(progress<1){ animId=requestAnimationFrame(frame); }
        else{ currentAngle=startAngle+totalDelta; drawWheel(currentAngle); if(cb)cb(); }
    }
    animId=requestAnimationFrame(frame);
}

// ══ BET SELECTION ═══════════════════════════════════════════
function selectBet(type){
    selectedBet=type;
    document.querySelectorAll('.color-btn,.parity-btn').forEach(function(b){b.classList.remove('selected');});
    document.getElementById('btn-'+type).classList.add('selected');
    document.getElementById('spinBtn').disabled=false;
    playClick();
}
function setAmt(v){ document.getElementById('betAmt').value=v; playClick(); }
function halfMax(){ document.getElementById('betAmt').value=Math.floor(MAXBET/2); playClick(); }

function showErr(msg){
    var t=document.getElementById('errToast');
    t.textContent=msg; t.classList.add('on');
    setTimeout(function(){ t.classList.remove('on'); },3200);
}

// ══ SPIN ════════════════════════════════════════════════════
var serverResult=null;

function resetBtn(){
    spinning=false;
    var btn=document.getElementById('spinBtn');
    btn.disabled=false; btn.classList.remove('spinning');
    document.getElementById('spinBtnTxt').textContent='SPIN TO WIN';
    document.getElementById('spinIcon').style.animation='';
}

function doSpin(){
    if(spinning||!selectedBet) return;
    var amt=parseFloat(document.getElementById('betAmt').value);
    if(isNaN(amt)||amt<MINBET){ showErr('Min bet: '+CS+' '+MINBET); return; }
    if(amt>MAXBET){ showErr('Max bet: '+CS+' '+MAXBET); return; }
    if(amt>BALANCE){ showErr('Insufficient spin wallet balance'); return; }

    // Resume audio context on user gesture
    var ac=getAC(); if(ac&&ac.state==='suspended') ac.resume();

    spinning=true; serverResult=null;
    var btn=document.getElementById('spinBtn');
    btn.disabled=true; btn.classList.add('spinning');
    document.getElementById('spinBtnTxt').textContent='SPINNING…';
    document.getElementById('spinIcon').style.animation='spin360 .5s linear infinite';

    var spinStart=performance.now();
    var freeId=null, freeAngle=currentAngle, freeSpeed=0, MAX_SPEED=0.08;

    function freeSpin(){
        freeSpeed=Math.min(freeSpeed+.008,MAX_SPEED);
        freeAngle+=freeSpeed; currentAngle=freeAngle;
        drawWheel(currentAngle);
        if(spinning&&serverResult===null){ freeId=requestAnimationFrame(freeSpin); }
        else if(serverResult!==null){ cancelAnimationFrame(freeId); preciseStop(serverResult); }
    }
    freeId=requestAnimationFrame(freeSpin);

    fetch('spin_win.php',{
        method:'POST',
        headers:{'Content-Type':'application/x-www-form-urlencoded'},
        body:'action=spin&bet_type='+selectedBet+'&bet_amount='+amt
    })
    .then(function(r){ return r.json(); })
    .then(function(d){
        if(d.error){ cancelAnimationFrame(freeId); drawWheel(currentAngle); showErr(d.error); resetBtn(); return; }
        var elapsed=performance.now()-spinStart;
        if(elapsed<1500){ setTimeout(function(){ serverResult=d; },1500-elapsed); }
        else { serverResult=d; }
    })
    .catch(function(){ cancelAnimationFrame(freeId); showErr('Server error. Try again.'); resetBtn(); });
}

function preciseStop(d){
    var delta=calcTargetAngle(d.number)+3*2*Math.PI;
    animSpin(delta,3000,function(){
        resetBtn();
        if(d.won) playWin(); else playLose();
        showResult(d);
        if(d.won) addRealWin(d.payout);
    });
}

// ══ RESULT ══════════════════════════════════════════════════
function showResult(d){
    BALANCE=d.new_balance;
    document.getElementById('displayBalance').textContent=CS+' '+d.new_balance.toFixed(2);
    var card=document.getElementById('resultCard');
    var numEl=document.getElementById('resultNum');
    var metaEl=document.getElementById('resultMeta');
    var verdEl=document.getElementById('resultVerdict');
    var payEl=document.getElementById('resultPayout');
    numEl.textContent=d.number;
    numEl.className='result-num-big '+d.color;
    var dot=d.color==='red'?'#fc8181':(d.color==='black'?'#4a5568':'#68d391');
    metaEl.innerHTML=
        '<span class="result-tag" style="display:flex;align-items:center;gap:5px">'+
        '<svg width="10" height="10" viewBox="0 0 10 10"><circle cx="5" cy="5" r="4.5" fill="'+dot+'"/></svg>'+
        d.color.toUpperCase()+'</span>'+
        '<span class="result-tag">'+d.parity.toUpperCase()+'</span>';
    if(d.won){
        card.className='result-card won';
        verdEl.textContent='YOU WIN!';
        payEl.innerHTML='Payout: <strong>'+CS+' '+d.payout.toFixed(2)+'</strong>';
        spawnConfetti();
    } else {
        card.className='result-card lost';
        verdEl.textContent='TRY AGAIN';
        payEl.innerHTML='Lost: <strong>'+CS+' '+d.bet_amount.toFixed(2)+'</strong>';
    }
    document.getElementById('resultOverlay').classList.add('on');
    addHistItem(d);
}

function addHistItem(d){
    var list=document.getElementById('histList');
    var empty=list.querySelector('.hist-empty');
    if(empty) empty.remove();
    var item=document.createElement('div'); item.className='hist-item';
    var desc=d.won?'WIN: bet '+selectedBet+' '+CS+d.bet_amount.toFixed(2)+' → '+CS+d.payout.toFixed(2):'LOSS: bet '+selectedBet+' '+CS+d.bet_amount.toFixed(2);
    item.innerHTML='<div class="hist-desc">'+desc+'</div><div class="hist-amt '+(d.won?'win':'lose')+'">'+(d.won?'+':'-')+CS+(d.won?d.payout:d.bet_amount).toFixed(2)+'</div>';
    list.insertBefore(item,list.firstChild);
    if(list.children.length>20) list.removeChild(list.lastChild);
}
function closeResult(){ document.getElementById('resultOverlay').classList.remove('on'); }

// ══ CONFETTI ════════════════════════════════════════════════
var CC=['#f6e05e','#fc8181','#68d391','#63b3ed','#f6ad55','#ed64a6'];
function spawnConfetti(){
    for(var i=0;i<40;i++){(function(i){ setTimeout(function(){
        var el=document.createElement('div'); el.className='confetti-piece';
        el.style.left=(Math.random()*100)+'vw'; el.style.top='-12px';
        el.style.background=CC[Math.floor(Math.random()*CC.length)];
        el.style.width=(6+Math.random()*6)+'px'; el.style.height=(6+Math.random()*6)+'px';
        el.style.borderRadius=Math.random()>.5?'50%':'2px';
        el.style.animationDuration=(1.4+Math.random()*1.2)+'s';
        document.body.appendChild(el);
        setTimeout(function(){ el.remove(); },2800);
    },i*55);})(i);}
}

// ══ DEPOSIT ═════════════════════════════════════════════════
function doDeposit(){
    var phone=document.getElementById('depositPhone').value.trim();
    var amt=parseFloat(document.getElementById('depositAmt').value);
    var btn=document.getElementById('depositBtn');
    if(!phone||phone.length<9){ showDepositStatus('err','Enter a valid phone number (07XXXXXXXX)'); return; }
    if(isNaN(amt)||amt<10){ showDepositStatus('err','Minimum deposit is Ksh 10'); return; }
    btn.disabled=true;
    btn.innerHTML='<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Sending…';
    showDepositStatus('','');
    fetch('spin_win.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},
        body:'action=spin_deposit&phone='+encodeURIComponent(phone)+'&amount='+amt})
    .then(function(r){ return r.json(); })
    .then(function(d){
        btn.disabled=false;
        btn.innerHTML='<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><rect x="1" y="4" width="22" height="16" rx="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg> Deposit';
        if(d.error){ showDepositStatus('err',d.error); }
        else{ showDepositStatus('ok',(d.message||'STK sent!')+' Enter your M-PESA PIN.');
              document.getElementById('depositPhone').value='';
              if(d.ref) startDepositPoll(d.ref); }
    })
    .catch(function(){ btn.disabled=false;
        btn.innerHTML='<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><rect x="1" y="4" width="22" height="16" rx="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg> Deposit';
        showDepositStatus('err','Connection error. Try again.'); });
}
function showDepositStatus(type,msg){
    var el=document.getElementById('depositStatus');
    el.className='deposit-status'+(type?' '+type:''); el.textContent=msg;
}
var _depPoll=null,_depCount=0;
function startDepositPoll(ref){
    if(_depPoll) clearInterval(_depPoll); _depCount=0;
    showDepositStatus('ok','⏳ Waiting for M-PESA confirmation…');
    _depPoll=setInterval(function(){ pollDeposit(ref); },5000);
}
function pollDeposit(ref){
    if(++_depCount>24){ clearInterval(_depPoll); showDepositStatus('err','Timed out. Check M-PESA balance.'); return; }
    fetch('spin_win.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},
        body:'action=spin_dep_status&ref='+encodeURIComponent(ref)})
    .then(function(r){ return r.json(); })
    .then(function(d){
        if(d.status==='completed'){
            clearInterval(_depPoll); BALANCE=d.balance||BALANCE;
            document.getElementById('displayBalance').textContent=CS+' '+BALANCE.toFixed(2);
            showDepositStatus('ok','✅ Deposited '+(d.amount?CS+' '+d.amount.toFixed(2):'')+' — Wallet updated!');
            playWin();
        } else if(d.status==='failed'){
            clearInterval(_depPoll); showDepositStatus('err',d.message||'Payment failed. Try again.');
        }
    }).catch(function(){});
}

// CSS for spin icon
var sty=document.createElement('style');
sty.textContent='@keyframes spin360{to{transform:rotate(360deg)}}';
document.head.appendChild(sty);
</script>
</body>
</html>
<?php include 'footer.php'; ?>