from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
from apps.core.utils import error_response
from .models import CompanyProfile, DispatchAddress, PlaceOfSupply, InvoiceTerm
from .serializers import (
    CompanyProfileSerializer,
    DispatchAddressSerializer,
    PlaceOfSupplySerializer,
    InvoiceTermSerializer,
    UserShippingAddressSerializer,
)
from apps.accounts.models import UserShippingAddress


# ---------------------------------------------------------------------------
# Public / User-facing
# ---------------------------------------------------------------------------

class InvoicePublicSettingsView(APIView):
    """Return company profile, places of supply, and T&C lines for invoice rendering.
    Public read endpoint — no auth required (used by invoice print page)."""
    permission_classes = [permissions.AllowAny]

    def get(self, request):
        company = CompanyProfile.objects.first()
        supplies = PlaceOfSupply.objects.all()
        terms = InvoiceTerm.objects.all()
        return Response({
            'company': CompanyProfileSerializer(company).data if company else None,
            'places_of_supply': PlaceOfSupplySerializer(supplies, many=True).data,
            'terms': InvoiceTermSerializer(terms, many=True).data,
        })


class UserShippingAddressListCreateView(APIView):
    """List / create shipping addresses for the authenticated user."""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        qs = UserShippingAddress.objects.filter(user=request.user)
        return Response(UserShippingAddressSerializer(qs, many=True).data)

    def post(self, request):
        serializer = UserShippingAddressSerializer(data=request.data)
        if serializer.is_valid():
            if request.data.get('is_default'):
                UserShippingAddress.objects.filter(user=request.user, is_default=True).update(is_default=False)
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserShippingAddressDetailView(APIView):
    """Retrieve / update / delete a single shipping address belonging to the user."""
    permission_classes = [permissions.IsAuthenticated]

    def _get_object(self, request, pk):
        try:
            return UserShippingAddress.objects.get(id=pk, user=request.user)
        except UserShippingAddress.DoesNotExist:
            return None

    def get(self, request, pk):
        obj = self._get_object(request, pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        return Response(UserShippingAddressSerializer(obj).data)

    def put(self, request, pk):
        obj = self._get_object(request, pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        serializer = UserShippingAddressSerializer(obj, data=request.data, partial=True)
        if serializer.is_valid():
            if request.data.get('is_default'):
                UserShippingAddress.objects.filter(user=request.user, is_default=True).exclude(id=pk).update(is_default=False)
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        obj = self._get_object(request, pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class UserSetDefaultShippingAddressView(APIView):
    """Set an address as the default."""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, pk):
        try:
            addr = UserShippingAddress.objects.get(id=pk, user=request.user)
        except UserShippingAddress.DoesNotExist:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        UserShippingAddress.objects.filter(user=request.user, is_default=True).update(is_default=False)
        addr.is_default = True
        addr.save(update_fields=['is_default'])
        return Response({'success': True})


# ---------------------------------------------------------------------------
# Admin-only
# ---------------------------------------------------------------------------

class IsAdminUser(permissions.BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.is_staff)


class AdminCompanyProfileView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        company = CompanyProfile.objects.first()
        return Response(CompanyProfileSerializer(company).data if company else {})

    def put(self, request):
        company = CompanyProfile.objects.first()
        if company:
            serializer = CompanyProfileSerializer(company, data=request.data, partial=True)
        else:
            serializer = CompanyProfileSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AdminDispatchAddressListCreateView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        qs = DispatchAddress.objects.all()
        return Response(DispatchAddressSerializer(qs, many=True).data)

    def post(self, request):
        serializer = DispatchAddressSerializer(data=request.data)
        if serializer.is_valid():
            if request.data.get('is_default'):
                DispatchAddress.objects.filter(is_default=True).update(is_default=False)
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AdminDispatchAddressDetailView(APIView):
    permission_classes = [IsAdminUser]

    def _get(self, pk):
        try:
            return DispatchAddress.objects.get(id=pk)
        except DispatchAddress.DoesNotExist:
            return None

    def get(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        return Response(DispatchAddressSerializer(obj).data)

    def put(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        serializer = DispatchAddressSerializer(obj, data=request.data, partial=True)
        if serializer.is_valid():
            if request.data.get('is_default'):
                DispatchAddress.objects.filter(is_default=True).exclude(id=pk).update(is_default=False)
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class AdminPlaceOfSupplyListCreateView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        qs = PlaceOfSupply.objects.all()
        return Response(PlaceOfSupplySerializer(qs, many=True).data)

    def post(self, request):
        serializer = PlaceOfSupplySerializer(data=request.data)
        if serializer.is_valid():
            if request.data.get('is_default'):
                PlaceOfSupply.objects.filter(is_default=True).update(is_default=False)
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AdminPlaceOfSupplyDetailView(APIView):
    permission_classes = [IsAdminUser]

    def _get(self, pk):
        try:
            return PlaceOfSupply.objects.get(id=pk)
        except PlaceOfSupply.DoesNotExist:
            return None

    def put(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        serializer = PlaceOfSupplySerializer(obj, data=request.data, partial=True)
        if serializer.is_valid():
            if request.data.get('is_default'):
                PlaceOfSupply.objects.filter(is_default=True).exclude(id=pk).update(is_default=False)
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class AdminInvoiceTermListCreateView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        qs = InvoiceTerm.objects.all()
        return Response(InvoiceTermSerializer(qs, many=True).data)

    def post(self, request):
        serializer = InvoiceTermSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AdminInvoiceTermDetailView(APIView):
    permission_classes = [IsAdminUser]

    def _get(self, pk):
        try:
            return InvoiceTerm.objects.get(id=pk)
        except InvoiceTerm.DoesNotExist:
            return None

    def put(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        serializer = InvoiceTermSerializer(obj, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        obj = self._get(pk)
        if not obj:
            return error_response("Not found", "NOT_FOUND", status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
