"""YakPanel - Auth API"""
from datetime import timedelta
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from pydantic import BaseModel

from app.core.database import get_db
from app.core.security import verify_password, get_password_hash, create_access_token, decode_token
from app.core.config import get_settings
from app.models.user import User

router = APIRouter(prefix="/auth", tags=["auth"])
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/v1/auth/login")


async def get_current_user(
    token: str = Depends(oauth2_scheme),
    db: AsyncSession = Depends(get_db),
) -> User:
    """Get current authenticated user from JWT"""
    credentials_exception = HTTPException(status_code=401, detail="Invalid credentials")
    payload = decode_token(token)
    if not payload:
        raise credentials_exception
    sub = payload.get("sub")
    user_id = int(sub) if isinstance(sub, str) else sub
    if not user_id:
        raise credentials_exception
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        raise credentials_exception
    if not user.is_active:
        raise HTTPException(status_code=400, detail="User inactive")
    return user


@router.post("/login")
async def login(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: AsyncSession = Depends(get_db),
):
    """Login and return JWT token"""
    from sqlalchemy import select
    result = await db.execute(select(User).where(User.username == form_data.username))
    user = result.scalar_one_or_none()
    if not user or not verify_password(form_data.password, user.password):
        raise HTTPException(status_code=401, detail="Incorrect username or password")
    if not user.is_active:
        raise HTTPException(status_code=400, detail="User inactive")
    access_token = create_access_token(
        data={"sub": str(user.id)},
        expires_delta=timedelta(minutes=get_settings().access_token_expire_minutes),
    )
    return {"access_token": access_token, "token_type": "bearer", "user": {"id": user.id, "username": user.username}}


@router.post("/logout")
async def logout():
    """Logout (client should discard token)"""
    return {"message": "Logged out"}


@router.get("/me")
async def get_me(current_user: User = Depends(get_current_user)):
    """Get current user info"""
    return {"id": current_user.id, "username": current_user.username, "email": current_user.email, "is_superuser": current_user.is_superuser}


class ChangePasswordRequest(BaseModel):
    old_password: str
    new_password: str


@router.post("/change-password")
async def change_password(
    body: ChangePasswordRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Change password"""
    if not verify_password(body.old_password, current_user.password):
        raise HTTPException(status_code=400, detail="Incorrect current password")
    result = await db.execute(select(User).where(User.id == current_user.id))
    user = result.scalar_one()
    user.password = get_password_hash(body.new_password)
    await db.commit()
    return {"message": "Password changed"}
