from django.db.models import Count, Sum
from django.utils.dateparse import parse_date
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from account.permissions import get_user_data_filter, user_can_see_all_shop_data
from shop_management.models.data.daily_diary import DailyDiaryLog

# Matches frontend diaryConstants.js sections
DIARY_SECTION_ACTIVITIES = {
    "sale": [DailyDiaryLog.ActivityType.SALE],
    "purchase": [DailyDiaryLog.ActivityType.PURCHASE],
    "quotation": [DailyDiaryLog.ActivityType.QUOTATION],
    "receivable": [
        DailyDiaryLog.ActivityType.SALE_PAYMENT,
        DailyDiaryLog.ActivityType.CUSTOMER_PAYMENT,
        DailyDiaryLog.ActivityType.PASSIVE_INCOME,
    ],
    "payable": [
        DailyDiaryLog.ActivityType.PURCHASE_PAYMENT,
        DailyDiaryLog.ActivityType.SUPPLIER_PAYMENT,
        DailyDiaryLog.ActivityType.CUSTOMER_DEBTOR,
        DailyDiaryLog.ActivityType.PAYROLL,
        DailyDiaryLog.ActivityType.ADVANCE,
        DailyDiaryLog.ActivityType.ACCOUNT_TRANSFER,
    ],
    "expense": [DailyDiaryLog.ActivityType.EXPENSE],
    "stock": [DailyDiaryLog.ActivityType.STOCK_TRANSFER],
}


class DailyDiarySummaryView(APIView):
    """Grouped totals for روزنامچه — sales, purchases, receivable, payable, etc."""

    permission_classes = [IsAuthenticated]
    required_tab = "daily_diary"

    @staticmethod
    def _totals_list(qs, category):
        rows = (
            qs.filter(category=category)
            .values("currency__title")
            .annotate(total=Sum("amount"), count=Count("id"))
        )
        return [
            {
                "currency": (r["currency__title"] or "Unknown"),
                "amount": str(r["total"] or 0),
                "count": r["count"],
            }
            for r in rows
        ]

    @staticmethod
    def _section_totals(section_qs):
        rows = (
            section_qs.values("currency__title")
            .annotate(total=Sum("amount"))
            .order_by("currency__title")
        )
        return [
            {
                "currency": (r["currency__title"] or "Unknown"),
                "amount": str(r["total"] or 0),
            }
            for r in rows
        ]

    def get(self, request):
        user = request.user
        start = parse_date(request.query_params.get("start_date") or "")
        end = parse_date(request.query_params.get("end_date") or "")
        shop_id = request.query_params.get("shop")

        qs = DailyDiaryLog.objects.filter(is_deleted=False)
        if user_can_see_all_shop_data(user, self.required_tab):
            pass
        else:
            qs = qs.filter(get_user_data_filter(user, "shop")).distinct()

        if shop_id:
            qs = qs.filter(shop_id=shop_id)
        if start:
            qs = qs.filter(entry_date__gte=start)
        if end:
            qs = qs.filter(entry_date__lte=end)

        categories = [c.value for c in DailyDiaryLog.Category]
        summary = {}
        for cat in categories:
            cat_qs = qs.filter(category=cat)
            summary[cat] = {
                "count": cat_qs.count(),
                "totals": self._totals_list(qs, cat),
            }

        receivable_qs = qs.filter(category=DailyDiaryLog.Category.RECEIVABLE)
        payable_qs = qs.filter(category=DailyDiaryLog.Category.PAYABLE)

        sections = {}
        for section_id, activity_types in DIARY_SECTION_ACTIVITIES.items():
            section_qs = qs.filter(activity_type__in=activity_types)
            sections[section_id] = {
                "count": section_qs.count(),
                "totals": self._section_totals(section_qs),
            }

        return Response({
            "start_date": start.isoformat() if start else None,
            "end_date": end.isoformat() if end else None,
            "summary": summary,
            "sections": sections,
            "totals": {
                "entries": qs.count(),
                "receivable_count": receivable_qs.count(),
                "payable_count": payable_qs.count(),
                "sale_count": qs.filter(category=DailyDiaryLog.Category.SALE).count(),
                "purchase_count": qs.filter(category=DailyDiaryLog.Category.PURCHASE).count(),
            },
        })
