from fastapi import FastAPI, Depends, HTTPException, status, APIRouter
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app.core import security
from app.db import models
from jose import JWTError, jwt

# бд
def get_db():
    db = models.SessionLocal()
    try:
        yield db
    finally:
        db.close()
        

authRouter = APIRouter(
    prefix="/auth",
    tags=[],
)

# регистрация
@authRouter.post("/register")
async def register(username: str, password: str, db: Session = Depends(get_db)):
    if len(password.encode('utf-8')) > 72:
        raise HTTPException(status_code=400, detail="Пароль слишком длинный (макс. 72 байта)")
    
    db_user = db.query(models.User).filter(models.User.username == username).first()
    if db_user:
        raise HTTPException(status_code=400, detail="Пользователь уже существует")
    
    hashed_pwd = security.get_password_hash(password)
    new_user = models.User(username=username, hashed_password=hashed_pwd)
    db.add(new_user)
    db.commit()
    return {"status": "ok", "message": "User created"}

# вход
@authRouter.post("/login")
async def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
    user = db.query(models.User).filter(models.User.username == form_data.username).first()
    
    if not user or not security.verify_password(form_data.password, user.hashed_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Неверный логин или пароль",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    access_token = security.create_access_token(data={"sub": str(user.id)})
    refresh_token = security.create_refresh_token(data={"sub": str(user.id)})
    return {
        "access_token": access_token, 
        "refresh_token": refresh_token, 
        "token_type": "bearer",
        "user_id": user.id
    }
    
@authRouter.post("/refresh")
async def refresh_token(data: models.RefreshRequest, db: Session = Depends(get_db)):
    try:
        payload = jwt.decode(data.refresh_token, security.SECRET_KEY, algorithms=[security.ALGORITHM])
        user_id = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=401)
        
        
        new_access_token = security.create_access_token(data={"sub": user_id})
        new_refresh_token = security.create_refresh_token(data={"sub": user_id})
        return {"refresh_token": new_refresh_token, "access_token": new_access_token, "token_type": "bearer"}
    except JWTError:
        raise HTTPException(status_code=401, detail="Refresh token expired")