from fastapi import HTTPException, Request
from passlib.context import CryptContext
from sqlalchemy.orm import Session

from .db import SessionLocal
from .repositories import UserRepository

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def hash_password(password: str) -> str:
    return pwd_context.hash(password)


def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


def authenticate_user(db: Session, username: str, password: str):
    repo = UserRepository(db)
    user = repo.get_by_username(username)
    if not user:
        return None
    if not verify_password(password, user.password_hash):
        return None
    return user


def get_current_user_optional(request: Request, db: Session):
    user_id = request.session.get("user_id")
    if not user_id:
        return None
    repo = UserRepository(db)
    return repo.get_by_id(user_id)


def get_current_user(request: Request, db: Session):
    user = get_current_user_optional(request, db)
    if not user:
        raise HTTPException(status_code=401, detail="authentication required")
    return user


def require_admin(user):
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="admin only")
    return user