from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy.orm import Session

from app.database import get_db
from app.models.user import User, UserAffiliation
from app.schemas import UserCreate, UserLogin, UserOut, AffiliationCreate, AffiliationOut
from app.services.auth import hash_password, verify_password, create_access_token, require_user, get_current_user
from app.config import settings

router = APIRouter(prefix="/api/auth", tags=["auth"])


@router.post("/register", response_model=UserOut)
def register(data: UserCreate, response: Response, db: Session = Depends(get_db)):
    if db.query(User).filter((User.email == data.email) | (User.username == data.username)).first():
        raise HTTPException(status_code=400, detail="Email or username already registered")
    is_verified = settings.is_email_academic(data.email)
    user = User(
        email=data.email,
        username=data.username,
        full_name=data.full_name,
        hashed_password=hash_password(data.password),
        is_verified=is_verified,
    )
    db.add(user)
    db.commit()
    db.refresh(user)
    token = create_access_token({"sub": str(user.id)})
    response.set_cookie("access_token", token, httponly=True, samesite="lax", max_age=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60)
    return user


@router.post("/login")
def login(data: UserLogin, response: Response, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.email == data.email).first()
    if not user or not verify_password(data.password, user.hashed_password):
        raise HTTPException(status_code=401, detail="Invalid credentials")
    token = create_access_token({"sub": str(user.id)})
    response.set_cookie("access_token", token, httponly=True, samesite="lax", max_age=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60)
    return {"access_token": token, "token_type": "bearer", "user_id": user.id}


@router.post("/logout")
def logout(response: Response):
    response.delete_cookie("access_token")
    return {"message": "Logged out"}


@router.get("/me", response_model=UserOut)
def get_me(user: User = Depends(require_user)):
    return user


@router.put("/me", response_model=UserOut)
def update_me(bio: str | None = None, full_name: str | None = None, field_id: int | None = None, user: User = Depends(require_user), db: Session = Depends(get_db)):
    if bio is not None:
        user.bio = bio
    if full_name is not None:
        user.full_name = full_name
    if field_id is not None:
        user.field_id = field_id
    db.commit()
    db.refresh(user)
    return user


@router.post("/me/affiliations", response_model=AffiliationOut)
def add_affiliation(data: AffiliationCreate, user: User = Depends(require_user), db: Session = Depends(get_db)):
    aff = UserAffiliation(user_id=user.id, **data.model_dump())
    db.add(aff)
    db.commit()
    db.refresh(aff)
    return aff


@router.delete("/me/affiliations/{aff_id}")
def delete_affiliation(aff_id: int, user: User = Depends(require_user), db: Session = Depends(get_db)):
    aff = db.query(UserAffiliation).filter(UserAffiliation.id == aff_id, UserAffiliation.user_id == user.id).first()
    if not aff:
        raise HTTPException(status_code=404, detail="Affiliation not found")
    db.delete(aff)
    db.commit()
    return {"message": "Deleted"}
