import secrets
from datetime import datetime, timedelta, timezone

import bcrypt
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession

from app.config import settings


def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")


def verify_password(password: str, hashed: str) -> bool:
    try:
        return bcrypt.checkpw(password.encode("utf-8"), hashed.encode("utf-8"))
    except ValueError:
        return False


def new_session_token() -> str:
    return secrets.token_urlsafe(32)


async def create_session(session: AsyncSession, user_id: str) -> tuple[str, datetime]:
    token = new_session_token()
    expires = datetime.now(timezone.utc) + timedelta(seconds=settings.SESSION_LIFETIME_SECONDS)
    await session.execute(
        text(
            "INSERT INTO user_sessions (token, user_id, expires_at) VALUES (:t, :u, :e)"
        ),
        {"t": token, "u": user_id, "e": expires},
    )
    return token, expires


async def delete_session(session: AsyncSession, token: str) -> None:
    await session.execute(text("DELETE FROM user_sessions WHERE token = :t"), {"t": token})
