import random
import sqlite3
import logging

import config

logger = logging.getLogger(__name__)

# Символы слотов и их веса (чем выше вес — тем чаще выпадает)
SLOT_SYMBOLS = ["🍒", "🍋", "🔔", "💎", "7️⃣", "🍀"]
SLOT_WEIGHTS = [30, 25, 20, 12, 8, 5]  # 🍒 чаще всего, 🍀 реже всего

# Множители для выигрышей: {кол-во совпадений: (мин, макс)}
MULTIPLIERS = {
    2: (1.2, 1.8),   # две одинаковых
    3: (2.0, 3.0),   # три одинаковых (джекпот, редко)
}

CASINO_WIN_CHANCE = 0.35


def spin_slots() -> tuple[list[str], int]:
    reels = random.choices(SLOT_SYMBOLS, weights=SLOT_WEIGHTS, k=3)

    if random.random() > CASINO_WIN_CHANCE:
        while len(set(reels)) < 3:
            reels = random.choices(SLOT_SYMBOLS, weights=SLOT_WEIGHTS, k=3)
        return reels, 0

    counts = {}
    for s in reels:
        counts[s] = counts.get(s, 0) + 1
    max_match = max(counts.values())
    return reels, max_match


def get_user_length(user_id: int) -> float | None:
    try:
        with sqlite3.connect(config.PENIS_DB_PATH) as conn:
            row = conn.execute(
                "SELECT length FROM penis_stats WHERE user_id = ?",
                (user_id,),
            ).fetchone()
        return float(row[0]) if row else None
    except sqlite3.Error:
        logger.exception("casino: failed to get length")
        return None


def update_user_length(user_id: int, delta: float) -> float | None:
    try:
        with sqlite3.connect(config.PENIS_DB_PATH) as conn:
            row = conn.execute(
                "SELECT length FROM penis_stats WHERE user_id = ?",
                (user_id,),
            ).fetchone()
            if row is None:
                return None
            new_length = round(float(row[0]) + delta, 1)
            conn.execute(
                "UPDATE penis_stats SET length = ? WHERE user_id = ?",
                (new_length, user_id),
            )
            conn.commit()
            return new_length
    except sqlite3.Error:
        logger.exception("casino: failed to update length")
        return None


def play_casino(user_id: int, bet: float) -> str:
    current = get_user_length(user_id)
    if current is None:
        return "Ты ещё ни разу не крутил /penis, братуха. Сначала заведи счёт."

    # Проверяем отрицательный баланс
    if current <= 0:
        return "🚫 С кредитом в казино не впускают, братуха. Иди наращивай через /penis."

    # Проверяем максимум ставки
    if bet > config.CASINO_MAX_BET:
        return f"Максимальная ставка — {config.CASINO_MAX_BET} см, не жадничай."

    if bet <= 0:
        return "Ставка должна быть больше нуля, фраер."

    # Проверяем хватает ли
    if bet > current:
        return f"У тебя {current:.1f} см, а ставишь {bet:.1f}. Столько нет, фраер."

    # Крутим
    reels, matches = spin_slots()
    slots_display = " | ".join(reels)

    if matches >= 2:
        min_mult, max_mult = MULTIPLIERS[matches]
        multiplier = round(random.uniform(min_mult, max_mult), 1)
        winnings = round(bet * multiplier, 1)
        new_length = update_user_length(user_id, winnings)
        if new_length is None:
            return "Ошибка БД. Попробуй позже."

        if matches == 3:
            return (
                f"🎰 {slots_display}\n\n"
                f"🎉 ДЖЕКПОТ!!! Три одинаковых!\n"
                f"Множитель: x{multiplier}\n"
                f"Выигрыш: +{winnings:.1f} см\n"
                f"📏 Текущий размер: {new_length:.1f} см"
            )
        return (
            f"🎰 {slots_display}\n\n"
            f"✅ Выигрыш! Две совпали.\n"
            f"Множитель: x{multiplier}\n"
            f"Выигрыш: +{winnings:.1f} см\n"
            f"📏 Текущий размер: {new_length:.1f} см"
        )
    else:
        new_length = update_user_length(user_id, -bet)
        if new_length is None:
            return "Ошибка БД. Попробуй позже."
        return (
            f"🎰 {slots_display}\n\n"
            f"❌ Мимо, братуха.\n"
            f"Проигрыш: -{bet:.1f} см\n"
            f"📏 Текущий размер: {new_length:.1f} см"
        )
