"""
Authentication routes: register, login, profile — with permissions and registration toggle.
"""

from datetime import datetime

from pydantic import BaseModel
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from backend.database import get_db
from backend.models import User, AppSettings
from backend.auth import (
    hash_password, verify_password, create_token, get_current_user,
    get_user_permissions, ensure_user_permissions,
)
from backend import config

router = APIRouter()


class RegisterBody(BaseModel):
    username: str
    email: str
    password: str


class LoginBody(BaseModel):
    username: str
    password: str


@router.get("/registration-status")
def registration_status(db: Session = Depends(get_db)):
    """Public endpoint — no auth required. Frontend checks this to show/hide register form."""
    settings = db.query(AppSettings).first()
    enabled = settings.registration_enabled if settings else config.REGISTRATION_ENABLED_DEFAULT
    return {"registration_enabled": enabled}


@router.post("/register")
def register(body: RegisterBody, db: Session = Depends(get_db)):
    # Check if registration is enabled
    settings = db.query(AppSettings).first()
    enabled = settings.registration_enabled if settings else config.REGISTRATION_ENABLED_DEFAULT
    if not enabled:
        raise HTTPException(
            status.HTTP_403_FORBIDDEN,
            "Registration is currently disabled. Contact your administrator.",
        )

    if db.query(User).filter(
        (User.username == body.username) | (User.email == body.email)
    ).first():
        raise HTTPException(status.HTTP_409_CONFLICT, "Username or email already taken")

    user = User(
        username=body.username,
        email=body.email,
        password_hash=hash_password(body.password),
        role="user",
        quota_tokens_monthly=config.DEFAULT_QUOTA,
    )
    db.add(user)
    db.commit()
    db.refresh(user)

    ensure_user_permissions(user.id, db)

    token = create_token(user.id, user.role)
    perms = get_user_permissions(user.id, db)
    return {"token": token, "user": _user_dict(user, perms)}


@router.post("/login")
def login(body: LoginBody, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.username == body.username).first()
    if not user or not verify_password(body.password, user.password_hash):
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Invalid credentials")
    if not user.is_active:
        raise HTTPException(status.HTTP_403_FORBIDDEN, "Account disabled")
    token = create_token(user.id, user.role)
    perms = get_user_permissions(user.id, db)
    return {"token": token, "user": _user_dict(user, perms)}


@router.get("/me")
def me(user: User = Depends(get_current_user), db: Session = Depends(get_db)):
    now = datetime.utcnow()
    if user.quota_reset_date and now >= user.quota_reset_date:
        user.tokens_used_this_month = 0
        user.quota_reset_date = datetime(now.year + 1, 1, 1) if now.month == 12 else datetime(now.year, now.month + 1, 1)
        db.commit()
    perms = get_user_permissions(user.id, db)
    return _user_dict(user, perms)


def _user_dict(u: User, perms: dict = None) -> dict:
    d = {
        "id": u.id,
        "username": u.username,
        "email": u.email,
        "role": u.role,
        "is_active": u.is_active,
        "quota_tokens_monthly": u.quota_tokens_monthly,
        "tokens_used_this_month": u.tokens_used_this_month,
        "created_at": str(u.created_at),
    }
    if perms is not None:
        d["permissions"] = perms
    return d