"""Operator account management — superadmin only. Temp passwords are returned in
the JSON response once (shown to the superadmin to hand off); only hashes persist."""
from fastapi import APIRouter, Request, Depends, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from sqlalchemy.orm import Session

from backend.database import get_db
from backend.templates_config import templates
from backend.models import OperatorUser
from backend.operator_auth import (
    require_role, create_operator, reset_operator_password,
    set_operator_active, set_operator_role,
)
import backend.operator_auth as operator_auth
from backend.utils.timezone import format_local_datetime


def _require_auth_enabled():
    """The operator-management surface does not exist while operator auth is
    disabled — otherwise these net-new endpoints would be world-open with the
    flag off (the default), letting anyone pre-seed a superadmin. Read the flag
    as a live module attribute so the test monkeypatch and a runtime flip both
    take effect."""
    if not operator_auth.OPERATOR_AUTH_ENABLED:
        raise HTTPException(status_code=404, detail="Not found")


router = APIRouter(tags=["operator-users"], dependencies=[Depends(_require_auth_enabled)])
_superadmin = require_role("superadmin")


class NewUser(BaseModel):
    email: str
    name: str
    role: str = "admin"


class RoleChange(BaseModel):
    role: str


def _serialize(u: OperatorUser) -> dict:
    from datetime import datetime
    return {
        "id": u.id, "email": u.email, "display_name": u.display_name, "role": u.role,
        "active": bool(u.active), "must_change_password": bool(u.must_change_password),
        "locked": bool(u.locked_until and u.locked_until > datetime.utcnow()),
        "last_login_at": format_local_datetime(u.last_login_at, "%Y-%m-%d %H:%M") if u.last_login_at else None,
    }


@router.get("/admin/users")
async def users_page(request: Request, _=Depends(_superadmin)):
    return templates.TemplateResponse("admin/users.html", {"request": request})


@router.get("/api/admin/users")
async def list_users(_=Depends(_superadmin), db: Session = Depends(get_db)):
    users = db.query(OperatorUser).order_by(OperatorUser.display_name).all()
    return {"users": [_serialize(u) for u in users]}


@router.post("/api/admin/users")
async def add_user(body: NewUser, _=Depends(_superadmin), db: Session = Depends(get_db)):
    if body.role not in ("admin", "superadmin"):
        return JSONResponse(status_code=400, content={"detail": "role must be admin or superadmin"})
    try:
        user, raw = create_operator(db, body.email, body.name, body.role)
    except ValueError as e:
        return JSONResponse(status_code=400, content={"detail": str(e)})
    return {"user": _serialize(user), "password": raw}


@router.post("/api/admin/users/{user_id}/reset-password")
async def reset_user_password(user_id: str, _=Depends(_superadmin), db: Session = Depends(get_db)):
    user = db.query(OperatorUser).filter_by(id=user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    raw = reset_operator_password(db, user)
    return {"password": raw}


@router.post("/api/admin/users/{user_id}/disable")
async def disable_user(user_id: str, acting=Depends(_superadmin), db: Session = Depends(get_db)):
    if acting and acting.id == user_id:
        return JSONResponse(status_code=400, content={"detail": "Cannot disable your own account"})
    user = db.query(OperatorUser).filter_by(id=user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    set_operator_active(db, user, False)
    return {"active": False}


@router.post("/api/admin/users/{user_id}/enable")
async def enable_user(user_id: str, _=Depends(_superadmin), db: Session = Depends(get_db)):
    user = db.query(OperatorUser).filter_by(id=user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    set_operator_active(db, user, True)
    return {"active": True}


@router.post("/api/admin/users/{user_id}/role")
async def change_user_role(user_id: str, body: RoleChange,
                           acting=Depends(_superadmin), db: Session = Depends(get_db)):
    if acting and acting.id == user_id:
        return JSONResponse(status_code=400, content={"detail": "Cannot change your own role"})
    if body.role not in ("admin", "superadmin"):
        return JSONResponse(status_code=400, content={"detail": "role must be admin or superadmin"})
    user = db.query(OperatorUser).filter_by(id=user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    set_operator_role(db, user, body.role)
    return {"role": user.role}
