from django.db.models import Count
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from account.permissions import HasTabPermission, get_user_data_filter, get_user_shop_filter, user_can_see_all_shop_data
from shop_management.models.data.accounting import LedgerAccount
from shop_management.models.data.shop import Shop
from shop_management.serializers.data.accounting import LedgerAccountSerializer
from shop_management.services.chart_of_accounts import initialize_standard_chart
from shop_management.views.data.base import DataRootViewSet
from shop_management.views.data.pagination import CustomPagination


class LedgerAccountViewSet(DataRootViewSet):
    serializer_class = LedgerAccountSerializer
    permission_classes = [IsAuthenticated, HasTabPermission]
    required_tab = "accounts"
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend, SearchFilter]
    filterset_fields = ["shop", "account_type", "parent", "is_active", "allow_posting"]
    search_fields = ["code", "name", "description"]

    def get_queryset(self):
        queryset = LedgerAccount.objects.select_related("shop", "parent").annotate(child_count=Count("children"))
        if not user_can_see_all_shop_data(self.request.user, self.required_tab):
            queryset = queryset.filter(get_user_data_filter(self.request.user, "shop"))
        return queryset.order_by("shop_id", "code")

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

    def destroy(self, request, *args, **kwargs):
        account = self.get_object()
        if account.is_system:
            return Response({"detail": "Standard system accounts cannot be deleted; deactivate them instead."}, status=status.HTTP_400_BAD_REQUEST)
        if account.children.exists():
            return Response({"detail": "Move or remove child accounts before deleting this account."}, status=status.HTTP_400_BAD_REQUEST)
        return super().destroy(request, *args, **kwargs)

    @action(detail=False, methods=["post"], url_path="initialize-standard")
    def initialize_standard(self, request):
        shop_id = request.data.get("shop")
        if not shop_id:
            raise ValidationError({"shop": "Branch is required."})
        try:
            shop = Shop.objects.get(get_user_shop_filter(request.user), pk=shop_id)
        except Shop.DoesNotExist:
            raise PermissionDenied("You do not have access to this branch.")
        created = initialize_standard_chart(shop, user=request.user)
        return Response({"created": created, "total": LedgerAccount.objects.filter(shop=shop).count()})
