from typing import Annotated

from fastapi import Cookie, Depends, HTTPException, status
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession

from app.config import settings
from app.db import get_session


class CurrentUser:
    def __init__(self, id: str, email: str, role: str):
        self.id = id
        self.email = email
        self.role = role

    @property
    def is_admin(self) -> bool:
        return self.role == "admin"


async def current_user(
    session: Annotated[AsyncSession, Depends(get_session)],
    session_token: Annotated[str | None, Cookie(alias=settings.SESSION_COOKIE_NAME)] = None,
) -> CurrentUser:
    if not session_token:
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "not authenticated")
    row = (
        await session.execute(
            text(
                """
                SELECT u.id::text, u.email, u.role
                FROM user_sessions s
                JOIN users u ON u.id = s.user_id
                WHERE s.token = :t AND s.expires_at > now() AND u.is_active
                """
            ),
            {"t": session_token},
        )
    ).first()
    if not row:
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "session invalid or expired")
    return CurrentUser(id=row[0], email=row[1], role=row[2])


async def require_admin(user: Annotated[CurrentUser, Depends(current_user)]) -> CurrentUser:
    if not user.is_admin:
        raise HTTPException(status.HTTP_403_FORBIDDEN, "admin required")
    return user
