from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.models import User
from database.database import get_session

async def get_user_by_telegram_id(session: AsyncSession, telegram_id: int) -> User | None:
    stmt = select(User).where(User.telegram_id == telegram_id)
    result = await session.execute(stmt)
    return result.scalar_one_or_none()

from sqlalchemy.exc import IntegrityError

async def create_user(session: AsyncSession, telegram_id: int, username: str = None, full_name: str = None) -> User:
    new_user = User(
        telegram_id=telegram_id,
        username=username,
        full_name=full_name
    )
    session.add(new_user)
    try:
        await session.commit()
        await session.refresh(new_user)
        return new_user
    except IntegrityError:
        await session.rollback()
        return await get_user_by_telegram_id(session, telegram_id)


async def update_user_verification(session: AsyncSession, telegram_id: int, is_verified: bool):
    user = await get_user_by_telegram_id(session, telegram_id)
    if user:
        user.is_verified = is_verified
        await session.commit()

async def update_user_balance(session: AsyncSession, telegram_id: int, amount: float):
    user = await get_user_by_telegram_id(session, telegram_id)
    if user:
        user.wallet_balance += amount
        await session.commit()

from database.models import Setting

async def get_setting(session: AsyncSession, key: str, default: str = "") -> str:
    stmt = select(Setting).where(Setting.key == key)
    result = await session.execute(stmt)
    setting = result.scalar_one_or_none()
    return setting.value if setting else default

async def set_setting(session: AsyncSession, key: str, value: str):
    stmt = select(Setting).where(Setting.key == key)
    result = await session.execute(stmt)
    setting = result.scalar_one_or_none()
    if setting:
        setting.value = value
    else:
        setting = Setting(key=key, value=value)
        session.add(setting)
    await session.commit()

async def get_group_id(session: AsyncSession, group_type: str, default: int) -> int:
    """
    دریافت آیدی عددی گروه تنظیم‌شده در دیتابیس
    group_type: 'kyc', 'orders', 'receipts'
    """
    val = await get_setting(session, f"group_{group_type}")
    if val and val.strip():
        try:
            return int(val.strip())
        except ValueError:
            pass
    return default


# ─── مدیریت ادمین‌ها ────────────────────────────────────────

async def is_admin_user(session: AsyncSession, telegram_id: int) -> bool:
    """بررسی ادمین بودن کاربر (هم DB هم config)"""
    from core.config import config
    if telegram_id in config.admin_ids:
        return True
    user = await get_user_by_telegram_id(session, telegram_id)
    return bool(user and user.is_admin)


async def ensure_runtime_admin(session: AsyncSession, telegram_id: int) -> bool:
    """ادمین‌های دیتابیس را به لیست runtime اضافه می‌کند تا guardهای قدیمی هم کار کنند."""
    from core.config import config
    if await is_admin_user(session, telegram_id):
        if telegram_id not in config.admin_ids:
            config.admin_ids.append(telegram_id)
        return True
    return False


async def get_all_admin_ids(session: AsyncSession) -> list[int]:
    """دریافت لیست همه ادمین‌ها (هاردکد + دیتابیس)"""
    from core.config import config
    admin_set = set(config.admin_ids)
    stmt = select(User).where(User.is_admin == True)
    result = await session.execute(stmt)
    db_admins = result.scalars().all()
    for u in db_admins:
        admin_set.add(u.telegram_id)
    return list(admin_set)


async def get_database_admin_users(session: AsyncSession) -> list[User]:
    """دریافت ادمین‌هایی که از پنل/دیتابیس اضافه شده‌اند."""
    stmt = select(User).where(User.is_admin == True).order_by(User.id.asc())
    result = await session.execute(stmt)
    return result.scalars().all()


async def set_user_admin(session: AsyncSession, telegram_id: int) -> bool:
    """تبدیل کاربر به ادمین"""
    user = await get_user_by_telegram_id(session, telegram_id)
    if not user:
        user = User(telegram_id=telegram_id, is_admin=True, is_verified=True)
        session.add(user)
    else:
        user.is_admin = True
        user.is_verified = True
    await session.commit()
    from core.config import config
    if telegram_id not in config.admin_ids:
        config.admin_ids.append(telegram_id)
    return True


async def remove_user_admin(session: AsyncSession, telegram_id: int) -> bool:
    """حذف دسترسی ادمین کاربر"""
    from core.config import config
    if telegram_id in getattr(config, "primary_admin_ids", config.admin_ids):
        return False  # ادمین‌های اصلی قابل حذف نیستند
    user = await get_user_by_telegram_id(session, telegram_id)
    if user and user.is_admin:
        user.is_admin = False
        await session.commit()
        if telegram_id in config.admin_ids:
            config.admin_ids.remove(telegram_id)
        return True
    return False
