# dashboard/api_views.py
from decimal import Decimal, ROUND_HALF_UP
from datetime import date
from django.utils.timezone import now
from django.db.models import Sum, Q
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from django.db.models.functions import TruncMonth

from .models import PromoBanner, QuickAction, ExploreItem, Voucher, ThinBanner
from payments.models import ExternalWallet, ViralPeWallet, ViralPeWalletUsage
from notifications.models import Notification
from commissions.models import CommissionSplit  # adjust path if CommissionSplit lives elsewhere

def round2(val):
    return (Decimal(val or 0).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))

def abs_url(request, f):
    """
    Returns absolute URL for a File/ImageField or an absolute path string.
    Handles None safely.
    """
    if not f:
        return None
    # If it's a File/ImageField-like object with .url
    if hasattr(f, "url"):
        return request.build_absolute_uri(f.url)
    # If we stored a relative path string in DB
    url = str(f)
    if url.startswith("http://") or url.startswith("https://"):
        return url
    return request.build_absolute_uri(url)



class DashboardAPI(APIView):
    """
    GET /api/dashboard/
    Header: Authorization: Token <key>
    """
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        user = request.user
        user_name = user.first_name
        # 1) Notifications
        unread_count = Notification.objects.filter(user=user, is_read=False).count()

        # 2) Sections
        promo_banners = PromoBanner.objects.filter(
            active=True, start_date__lte=now(), end_date__gte=now()
        )

        quick_actions = QuickAction.objects.filter(active=True).order_by('order')[:4]
        explore_items = ExploreItem.objects.filter(active=True).order_by('order')[:8]
        vouchers = Voucher.objects.filter(active=True)#.select_related('brand')
        thin_banners = ThinBanner.objects.filter(active=True)

        # Build absolute URL for ExploreItem path (deeplink/route)
        def serialize_promo(b):
            return {
                "id": b.id,
                "title": getattr(b, "title", "") or "",
                "image_url": abs_url(request, getattr(b, "image", None)),
                "link_url": getattr(b, "link_url", None) or abs_url(request, getattr(b, "path", None)),
            }

        def serialize_quick(q):
            return {
                "id": q.id,
                "label": getattr(q, "label", "") or getattr(q, "title", "") or "",
                "icon_url": abs_url(request, getattr(q, "icon", None)),
                "path": getattr(q, "path", None),
                "order": getattr(q, "order", 0),
            }

        def serialize_explore(e):
            # Ensure absolute URL for navigation target
            raw_path = getattr(e, "path", None)
            abs_path = request.build_absolute_uri(raw_path) if raw_path else None
            return {
                "id": e.id,
                "title": getattr(e, "title", "") or "",
                "subtitle": getattr(e, "subtitle", "") or "",
                "icon_class": e.icon_class,
                "image_url": abs_url(request, getattr(e, "icon_class", None)),
                "url": abs_path,
                "order": getattr(e, "order", 0),
            }

        def serialize_voucher(v):
            return {
                "id": v.id,
                # "brand": getattr(v.brand, "name", "") if getattr(v, "brand", None) else "",
                "brand": getattr(v, "brand", ""),
                "voucher_name": getattr(v, "voucher_name", "") or "",
                "value": getattr(v, "value", 0),
                "expiry_date": getattr(v, "expiry_date", None),
                # Optional: image if present in your model
                "image_url": abs_url(request, getattr(v, "image", None)),
                "status": getattr(v, "status", "unused"),
            }

        def serialize_thin(t):
            return {
                "id": t.id,
                "image_url": abs_url(request, getattr(t, "image", None)),
                "link_url": getattr(t, "link_url", None) or abs_url(request, getattr(t, "path", None)),
            }

        # 3) Wallet balances
        external_wallet_obj = ExternalWallet.objects.filter(user=user).only("balance").first()
        viralpe_wallet_obj = ViralPeWallet.objects.filter(user=user).only("balance").first()

        external_wallet = round2(external_wallet_obj.balance) if external_wallet_obj else Decimal('0.00')
        viralpe_wallet  = round2(viralpe_wallet_obj.balance)  if viralpe_wallet_obj  else Decimal('0.00')
        total_wallet    = round2(external_wallet + viralpe_wallet)

        # 4) Cashback metrics (credits with "Commission:" prefix)
        commission_qs = ViralPeWalletUsage.objects.filter(
            user=user, transaction_type="credit", purpose__startswith="Commission:"
        )

        today = date.today()
        todays_cashback = round2(commission_qs.filter(used_on__date=today).aggregate(total=Sum('amount_used'))['total'])
        lifetime_cashback = round2(commission_qs.aggregate(total=Sum('amount_used'))['total'])
        user_share = round2(
            commission_qs.filter(purpose="Commission: User share").aggregate(total=Sum('amount_used'))['total']
        )
        referral_earnings = round2(
            commission_qs.filter(
                Q(purpose="Commission: Referral share") |
                Q(purpose="Commission: Vendor Referral share")
            ).aggregate(total=Sum('amount_used'))['total']
        )

        # ---- Pincode cashback (current month) ----
        user_pincode = getattr(user, "pincode", None)
        pincode_cashback = Decimal("0.00")
        if user_pincode:
            today = now().date()
            first_day = today.replace(day=1)
            # calculate first day of next month
            next_month = date(today.year + (today.month // 12), (today.month % 12) + 1, 1)

            # filter CommissionSplit for this pincode & month
            pincode_qs = CommissionSplit.objects.filter(
                pincode=user_pincode,
                credited_on__gte=first_day,    # ✅ removed __date — works for DateField or DateTimeField
                credited_on__lt=next_month,
            )

            # sum the pincode_amount
            total_pincode_amount = pincode_qs.aggregate(s=Sum("pincode_amount"))["s"]
            pincode_cashback = round2(total_pincode_amount or Decimal("0.00"))

            # optional debug log (safe)
            print(f"Pincode {user_pincode} cashback for {today.strftime('%B %Y')}: INR{pincode_cashback}")



        # 5) Response payload (decimals as strings to preserve cents)
        data = {
            "username":user_name,
            "pincode":user_pincode,
            "unread_notifications": unread_count,
            "wallets": {
                "external": str(external_wallet),
                "viralpe": str(viralpe_wallet),
                "total": str(total_wallet),
            },
            "cashback": {
                "pincode": str(pincode_cashback),
                "today": str(todays_cashback),
                "lifetime": str(lifetime_cashback),
                "user_share": str(user_share),
                "referral_earnings": str(referral_earnings),
            },
            "sections": {
                "promo_banners": [serialize_promo(b) for b in promo_banners],
                "quick_actions": [serialize_quick(q) for q in quick_actions],
                "explore_items": [serialize_explore(e) for e in explore_items],
                "vouchers": [serialize_voucher(v) for v in vouchers],
                "thin_banners": [serialize_thin(t) for t in thin_banners],
            },
        }
        # print(data)
        # print("=============================")
        return Response(data)
