"""
Auth middleware — FastAPI dependency for protected routes (PostgreSQL).
"""
import psycopg
from fastapi import Request, HTTPException
from auth import decode_access_token
from auth.models import get_conn, DASHBOARD_SCHEMA
from common.db_pool import db_pool


async def get_current_user(request: Request) -> dict:
    """
    FastAPI dependency — extracts JWT from Authorization header,
    decodes it, and returns the user dict from PostgreSQL.
    """
    auth_header = request.headers.get("Authorization", "")
    if not auth_header.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing or invalid token")

    token = auth_header[7:]
    try:
        claims = decode_access_token(token)
    except Exception:
        raise HTTPException(status_code=401, detail="Token expired or invalid")

    user_id = int(claims["sub"])
    
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(
            f"SELECT id, username, role, settings FROM {DASHBOARD_SCHEMA}.admin_users WHERE id = %s",
            (user_id,)
        )
        row = cur.fetchone()
        cur.close()
    finally:
        conn.close()

    if not row:
        raise HTTPException(status_code=401, detail="User not found")

    return {"id": row[0], "username": row[1], "role": row[2], "settings": row[3] or {}}


def require_admin(user: dict):
    """Check that user has admin role."""
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Chỉ admin mới có quyền thực hiện thao tác này")
    return user


def require_editor_or_admin(user: dict):
    """Check that user has editor or admin role."""
    if user.get("role") not in ("admin", "editor"):
        raise HTTPException(status_code=403, detail="Bạn không có quyền chỉnh sửa")
    return user
