"""Dashboard API endpoints for Users management.

Exposes user CRUD, git sync, and default user assignment via REST.
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

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

from proxym.dashboard.users import User, UserManager

logger = structlog.get_logger()
router = APIRouter(prefix="/users", tags=["users"])


# ── Request models ────────────────────────────────────────

class CreateUserRequest(BaseModel):
    name: str = Field(..., description="User display name")
    email: str = Field(..., description="User email address")
    username: str = Field("", description="Username/login")
    role: str = Field("developer", description="User role: admin, developer, viewer")
    is_default: bool = Field(False, description="Set as default/delegated user")


class UpdateUserRequest(BaseModel):
    name: str | None = Field(None, description="User display name")
    email: str | None = Field(None, description="User email address")
    username: str | None = Field(None, description="Username/login")
    role: str | None = Field(None, description="User role")
    is_default: bool | None = Field(None, description="Set as default user")
    is_active: bool | None = Field(None, description="Active status")


# ── Singleton helper ─────────────────────────────────────

def _users() -> UserManager:
    """Get the UserManager singleton with default persistence path."""
    from proxym.storage import DEFAULT_SQLITE_PATH
    return UserManager.get(DEFAULT_SQLITE_PATH)


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

@router.get("")
async def list_users(active_only: bool = False) -> dict[str, Any]:
    """List all users."""
    mgr = _users()
    users = mgr.list_users(active_only=active_only)
    return {
        "users": [u.summary() for u in users],
        "count": len(users),
        "default_user": mgr.get_default_user(),
    }


@router.post("")
async def create_user(req: CreateUserRequest) -> dict[str, Any]:
    """Create a new user."""
    mgr = _users()

    # Check for duplicate email
    if mgr.find_by_email(req.email):
        raise HTTPException(400, f"User with email '{req.email}' already exists")

    user = User(
        name=req.name,
        email=req.email,
        username=req.username or req.email.split("@")[0],
        role=req.role,
        is_default=req.is_default,
        git_configured=False,
    )
    created = mgr.create_user(user)
    logger.info("user_created", user_id=created.id, email=created.email)
    return created.summary()


@router.get("/sync-git")
async def sync_git_users(repo_path: str | None = None) -> dict[str, Any]:
    """Sync users from git commit history."""
    mgr = _users()
    path = Path(repo_path) if repo_path else None
    discovered = mgr.sync_from_git_log(path)
    return {
        "discovered": len(discovered),
        "users": [u.summary() for u in discovered],
        "total_users": len(mgr.list_users()),
    }


@router.get("/default")
async def get_default_user() -> dict[str, Any]:
    """Get the default/delegated user."""
    mgr = _users()
    default = mgr.get_default_user()
    if not default:
        raise HTTPException(404, "No default user configured")
    return default


@router.post("/{user_id}/set-default")
async def set_default_user(user_id: str) -> dict[str, Any]:
    """Set a user as the default/delegated user."""
    mgr = _users()
    user = mgr.get_user(user_id)
    if not user:
        raise HTTPException(404, f"User '{user_id}' not found")

    updated = mgr.update_user(user_id, {"is_default": True})
    logger.info("default_user_set", user_id=user_id)
    return updated.summary()


@router.get("/{user_id}")
async def get_user(user_id: str) -> dict[str, Any]:
    """Get a specific user."""
    mgr = _users()
    user = mgr.get_user(user_id)
    if not user:
        raise HTTPException(404, f"User '{user_id}' not found")
    return user.summary()


@router.put("/{user_id}")
async def update_user(user_id: str, req: UpdateUserRequest) -> dict[str, Any]:
    """Update a user."""
    mgr = _users()
    user = mgr.get_user(user_id)
    if not user:
        raise HTTPException(404, f"User '{user_id}' not found")

    updates = req.model_dump(exclude_unset=True)
    if not updates:
        return user.summary()

    updated = mgr.update_user(user_id, updates)
    logger.info("user_updated", user_id=user_id, updates=list(updates.keys()))
    return updated.summary()


@router.delete("/{user_id}")
async def delete_user(user_id: str) -> dict[str, Any]:
    """Delete a user."""
    mgr = _users()
    user = mgr.get_user(user_id)
    if not user:
        raise HTTPException(404, f"User '{user_id}' not found")

    # Don't delete the last default user without setting a new one
    if user.is_default:
        other_default_candidates = [
            u for u in mgr.list_users() if u.id != user_id and u.is_active
        ]
        if other_default_candidates:
            # Set first other user as default
            mgr.update_user(other_default_candidates[0].id, {"is_default": True})

    if mgr.delete_user(user_id):
        logger.info("user_deleted", user_id=user_id)
        return {"ok": True, "deleted": user_id}

    raise HTTPException(500, "Failed to delete user")
