"""
routers/users.py
────────────────────────────────────────────────────────────────
Admin user management.  All writes go to data/users.json via user_store.
Learners can only read their own profile (/api/users/me is in auth router).
"""
from __future__ import annotations
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field

from services import auth, user_store

router = APIRouter(prefix="/api/users", tags=["users"])


# ── Request schemas ────────────────────────────────────────────────────────────

class UserCreate(BaseModel):
    username:  str  = Field(..., min_length=2, max_length=40)
    password:  str  = Field(..., min_length=6)
    email:     str  = ""
    full_name: str  = ""
    role:      str  = "learner"   # "admin" | "learner"

class UserUpdate(BaseModel):
    email:     Optional[str]  = None
    full_name: Optional[str]  = None
    role:      Optional[str]  = None
    active:    Optional[bool] = None
    password:  Optional[str]  = None   # if present, password is rehashed


# ── Endpoints ─────────────────────────────────────────────────────────────────

@router.get("")
async def list_users(
    role: Optional[str] = None,
    _admin: dict = Depends(auth.require_admin),
):
    """Admin: list all users, optionally filtered by role."""
    return await user_store.list_users(role=role)


@router.post("", status_code=201)
async def create_user(
    body: UserCreate,
    _admin: dict = Depends(auth.require_admin),
):
    """Admin: create a new user (learner or admin)."""
    try:
        record = await user_store.create_user(
            username=body.username,
            password=body.password,
            role=body.role,
            email=body.email,
            full_name=body.full_name,
        )
        return record
    except ValueError as e:
        raise HTTPException(status_code=409, detail=str(e))


@router.get("/{uid}")
async def get_user(
    uid: str,
    _admin: dict = Depends(auth.require_admin),
):
    user = await user_store.get_by_id(uid)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user_store._safe(user)


@router.patch("/{uid}")
async def update_user(
    uid: str,
    body: UserUpdate,
    _admin: dict = Depends(auth.require_admin),
):
    """Admin: update email, full_name, role, active status, or password."""
    patch = {k: v for k, v in body.model_dump().items() if v is not None}
    updated = await user_store.update_user(uid, patch)
    if not updated:
        raise HTTPException(status_code=404, detail="User not found")
    return updated


@router.delete("/{uid}")
async def delete_user(
    uid: str,
    current_admin: dict = Depends(auth.require_admin),
):
    """Admin: delete a user.  Cannot delete yourself."""
    if uid == current_admin.get("id"):
        raise HTTPException(status_code=400, detail="Cannot delete your own account")
    ok = await user_store.delete_user(uid)
    if not ok:
        raise HTTPException(status_code=404, detail="User not found")
    return {"success": True, "id": uid}
