from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from apps.companies.repositories import ServicePriceRepository
from apps.companies.serializers.service_price_serializer import ServicePriceSerializer
from apps.companies.services import ServicePriceDomainService
from utils.paginations import LimitOffsetPagination


class ServicePriceViewSet(ModelViewSet):
    serializer_class = ServicePriceSerializer
    permission_classes = (IsAuthenticated,)
    pagination_class = LimitOffsetPagination

    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ["service", "is_active"]
    search_fields = ["service__name", "service__code"]
    ordering_fields = ["base_price", "effective_from", "effective_to"]
    ordering = ["-effective_from"]

    def get_queryset(self):
        """
        Only prices belonging to the active company.
        """
        return ServicePriceRepository.get_prices(
            self.request.user.active_company
        )

    def perform_create(self, serializer):
        data = serializer.validated_data.copy()

        service = data.pop("service")
        data.pop("company", None)      # important
        data.pop("is_active", None)

        price = ServicePriceDomainService.create_price(
            service=service,
            company=self.request.user.active_company,
            **data
        )
        serializer.instance = price

    def perform_update(self, serializer):
        data = serializer.validated_data.copy()

        service = data.pop("service", serializer.instance.service)
        data.pop("company", None)
        data.pop("is_active", None)

        price = ServicePriceDomainService.update_price(
            pk=serializer.instance.pk,
            service=service,
            company=self.request.user.active_company,
            **data
        )
        serializer.instance = price
