"""
Admin-panel user management (master DB).

The school-admin frontend's "Create New User" dialog posts here. Users are
created in the master DB with a UserProfile bound to the requester's school
so SchoolContextMiddleware routes their requests to the right school DB.
"""
import logging

from django.contrib.auth import get_user_model
from django.db import transaction
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import UserProfile

logger = logging.getLogger(__name__)
User = get_user_model()


def _requester_school(request):
    profile = getattr(request.user, "profile", None) or getattr(
        request.user, "userprofile", None
    )
    return getattr(profile, "school", None)


def _user_payload(user):
    return {
        "id": user.id,
        "username": user.username,
        "email": user.email,
        "is_staff": user.is_staff,
        "is_superuser": user.is_superuser,
        "is_active": user.is_active,
    }


class CreateUserView(APIView):
    """POST /create-user/ — create an admin-panel user for this school."""

    permission_classes = [IsAuthenticated]

    def post(self, request):
        if not (request.user.is_staff or request.user.is_superuser):
            return Response(
                {"error": "Only staff/admin can create users."},
                status=status.HTTP_403_FORBIDDEN,
            )

        username = (request.data.get("username") or "").strip()
        password = request.data.get("password") or ""
        email = (request.data.get("email") or "").strip()

        if not username:
            return Response(
                {"error": "Username is required"}, status=status.HTTP_400_BAD_REQUEST
            )
        if not password:
            return Response(
                {"error": "Password is required"}, status=status.HTTP_400_BAD_REQUEST
            )
        if User.objects.filter(username=username).exists():
            return Response(
                {"error": "A user with this username already exists"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        school = _requester_school(request)
        if school is None:
            return Response(
                {"error": "Your account has no school assigned"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        with transaction.atomic():
            user = User.objects.create_user(
                username=username,
                email=email,
                password=password,
                is_staff=bool(request.data.get("is_staff")),
                is_superuser=bool(request.data.get("is_superuser")),
                is_active=bool(request.data.get("is_active", True)),
            )
            # Bind to the school so middleware routes their school DB
            UserProfile.objects.create(user=user, school=school)

        logger.info(f"User {username} (id={user.id}) created for school {school.name}")
        return Response(_user_payload(user), status=status.HTTP_201_CREATED)


class UpdateUserView(APIView):
    """PUT /update-user/<pk>/ — update an admin-panel user."""

    permission_classes = [IsAuthenticated]

    def put(self, request, pk):
        if not (request.user.is_staff or request.user.is_superuser):
            return Response(
                {"error": "Only staff/admin can update users."},
                status=status.HTTP_403_FORBIDDEN,
            )
        try:
            user = User.objects.get(pk=pk)
        except User.DoesNotExist:
            return Response(
                {"error": "User not found"}, status=status.HTTP_404_NOT_FOUND
            )

        # Keep edits inside the requester's school
        school = _requester_school(request)
        target_profile = getattr(user, "profile", None)
        if (
            not request.user.is_superuser
            and target_profile is not None
            and school is not None
            and target_profile.school_id != school.id
        ):
            return Response(
                {"error": "You can only edit users of your own school"},
                status=status.HTTP_403_FORBIDDEN,
            )

        username = (request.data.get("username") or "").strip()
        if username and username != user.username:
            if User.objects.filter(username=username).exclude(pk=user.pk).exists():
                return Response(
                    {"error": "A user with this username already exists"},
                    status=status.HTTP_400_BAD_REQUEST,
                )
            user.username = username

        if "email" in request.data:
            user.email = (request.data.get("email") or "").strip()
        if "is_staff" in request.data:
            user.is_staff = bool(request.data.get("is_staff"))
        if "is_superuser" in request.data:
            user.is_superuser = bool(request.data.get("is_superuser"))
        if "is_active" in request.data:
            user.is_active = bool(request.data.get("is_active"))
        if request.data.get("password"):
            user.set_password(request.data["password"])
        user.save()

        return Response(_user_payload(user))
