from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List

from ..database import get_db
from ..models import User, UserPermission
from ..schemas import UserCreate, UserUpdate, UserFull, UserPasswordReset, UserPermissionSet, UserPermissionOut
from ..dependencies import require_super_admin, get_current_user
from ..auth import hash_password

router = APIRouter()


@router.get("/users", response_model=List[UserFull])
def list_users(
    db: Session = Depends(get_db),
    _=Depends(require_super_admin),
):
    return db.query(User).order_by(User.id).all()


@router.post("/users", response_model=UserFull)
def create_user(
    body: UserCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    # SUPER_ADMIN can create any role; OWNER can only create MANAGER users
    if current_user.role == 'SUPER_ADMIN':
        pass
    elif current_user.role == 'OWNER':
        if body.role != 'MANAGER':
            raise HTTPException(403, "Owners can only create Manager accounts")
    else:
        raise HTTPException(403, "Not authorised")

    if db.query(User).filter(User.username == body.username).first():
        raise HTTPException(400, "Username already taken")
    u = User(
        username=body.username,
        password_hash=hash_password(body.password),
        role=body.role,
        full_name=body.full_name,
        contact=body.contact,
    )
    db.add(u)
    db.flush()
    from .audit import log_audit
    log_audit(db, current_user.id, 'CREATE', 'users', u.id,
              f"Created user: {body.username} ({body.role})")
    db.commit()
    db.refresh(u)
    return u


@router.put("/users/{user_id}", response_model=UserFull)
def update_user(
    user_id: int,
    body: UserUpdate,
    db: Session = Depends(get_db),
    current_user=Depends(require_super_admin),
):
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(404, "User not found")
    for k, v in body.model_dump(exclude_none=True).items():
        setattr(u, k, v)
    from .audit import log_audit
    log_audit(db, current_user.id, 'UPDATE', 'users', user_id,
              f"Updated user: {u.username}")
    db.commit()
    db.refresh(u)
    return u


@router.put("/users/{user_id}/password")
def reset_password(
    user_id: int,
    body: UserPasswordReset,
    db: Session = Depends(get_db),
    current_user=Depends(require_super_admin),
):
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(404, "User not found")
    u.password_hash = hash_password(body.new_password)
    from .audit import log_audit
    log_audit(db, current_user.id, 'UPDATE', 'users', user_id,
              f"Password reset for user: {u.username}")
    db.commit()
    return {"ok": True}


@router.get("/users/{user_id}/permissions", response_model=List[UserPermissionOut])
def get_permissions(
    user_id: int,
    db: Session = Depends(get_db),
    _=Depends(require_super_admin),
):
    return db.query(UserPermission).filter(UserPermission.user_id == user_id).all()


@router.put("/users/{user_id}/permissions", response_model=List[UserPermissionOut])
def set_permissions(
    user_id: int,
    body: List[UserPermissionSet],
    db: Session = Depends(get_db),
    current_user=Depends(require_super_admin),
):
    if not db.query(User).filter(User.id == user_id).first():
        raise HTTPException(404, "User not found")
    # Replace all existing permissions
    db.query(UserPermission).filter(UserPermission.user_id == user_id).delete()
    perms = []
    for p in body:
        perm = UserPermission(
            user_id=user_id,
            module=p.module,
            can_view=p.can_view,
            can_create=p.can_create,
            can_edit=p.can_edit,
            can_delete=p.can_delete,
            granted_by=current_user.id,
        )
        db.add(perm)
        perms.append(perm)
    db.commit()
    for p in perms:
        db.refresh(p)
    return perms


@router.delete("/users/{user_id}", status_code=204)
def delete_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_super_admin),
):
    if user_id == current_user.id:
        raise HTTPException(400, "Cannot delete your own account")
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(404, "User not found")
    from .audit import log_audit
    log_audit(db, current_user.id, 'DELETE', 'users', user_id,
              f"Deleted user: {u.username} ({u.role})")
    db.query(UserPermission).filter(UserPermission.user_id == user_id).delete()
    db.delete(u)
    db.commit()
