import json
import logging
from django.conf import settings
from django.db import transaction
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import get_user_model

from apps.core.utils.send_user_email import send_new_user_email
from apps.core.serializers import (
    CreateUserSerializer,
    UpdateUserSerializer,
)
from apps.permissions.permissions import AnyPermission
from apps.companies.models import CompanyHistory


User = get_user_model()
email = settings.EMAIL_HOST_USER
react_domain = settings.REACT_DOMAIN
logger = logging.getLogger(__name__)
NOT_BELONGING_RESPONSE = 'You can only assign users to companies you belong to.'


def _get_company_ids(payload):
    return {r["company_id"] for r in payload.get("company_roles", [])}


def _get_payload(request):
    raw = request.data.get("data") or {}

    if hasattr(raw, "read"):
        raw = raw.read().decode("utf-8")

    payload = json.loads(raw) if isinstance(raw, str) else raw
    if not isinstance(payload, dict):
        payload = {}

    profile_image = request.FILES.get("profile_image")
    if profile_image:
        payload.setdefault("profile", {})
        payload["profile"]["image"] = profile_image

    return payload


class RegistrationView(APIView):
    permission_classes = []
    serializer_class = CreateUserSerializer

    def get_permissions(self):
        return [
            AnyPermission(
                "create_users",
                "create_dealerships_admins"
            )
        ]

    @transaction.atomic
    def post(self, request, *args, **kwargs):

        payload = _get_payload(request)

        logger.info(payload)

        company_ids = _get_company_ids(payload)

        if not request.user.is_superuser:
            user_company_ids = set(request.user.companies.values_list("id", flat=True))
            if not company_ids.issubset(user_company_ids):
                return Response(
                    {"detail": NOT_BELONGING_RESPONSE},
                    status=403
                )

        serializer = self.serializer_class(
            data=payload,
            context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        subject = "Welcome to the Dealership System"
        generated_password = getattr(
            user,
            "_generated_password",
            "Use Your Current Password"
        )

        send_new_user_email(
            user=user,
            company_ids=list(company_ids),
            generated_password=generated_password,
            subject=subject,
        )

        return Response(
            {"message": "User Created Successfully! Ask user to check email for Verification and Password."},
            status=201,
        )

class UserUpdateView(APIView):
    permission_classes = []
    serializer_class = UpdateUserSerializer

    def get_permissions(self):
        return [
            AnyPermission(
                "manage_users",
                "edit_dealerships_admins"
            )

        ]

    @transaction.atomic
    def patch(self, request, user_id, *args, **kwargs):
        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            print(args)
            print(kwargs)
            return Response({"detail": "User not found."}, status=404)

        payload = _get_payload(request)

        company_ids = _get_company_ids(payload)

        if not request.user.is_superuser:
            user_company_ids = set(request.user.companies.values_list("id", flat=True))
            if not company_ids.issubset(user_company_ids):
                return Response(
                    {"detail": NOT_BELONGING_RESPONSE},
                    status=403
                )

        old_phone = getattr(user.profile, "phone_number", None)
        new_phone = payload.get("profile", {}).get("phone_number")
        first = getattr(user.profile, "first_name", "") or ""
        last = getattr(user.profile, "last_name", "") or ""
        full_name = f"{first} {last}".strip()

        serializer = self.serializer_class(
            user,
            data=payload,
            partial=True,
            context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()

        company = (
            request.user.active_company or
            user.active_company or
            user.companies.order_by("id").first()
        )

        if new_phone is not None and old_phone != new_phone and company:
            CompanyHistory.objects.create(
                company=company,
                updated_by=request.user,
                action='updated',
                model_name='UserProfile',
                object_id=user.id,
                details=f"{full_name} Phone number changed from {old_phone} to {new_phone}"
            )

        return Response({"message": "User updated successfully."}, status=200)
