from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from django.conf import settings as django_settings
from django.db import models
from .models import Product, ProductVariant

@login_required
def product_list_json(request):
    """
    Returns all products as JSON for offline sync / Grid POS.
    Includes image URL and category name.
    """
    from django.db.models import Subquery, OuterRef, IntegerField
    from django.db.models.functions import Coalesce
    from .models import BranchStock
    
    # ── FILTER BY COMPANY ───────────────────────────────────────────
    company = getattr(request, 'company', None)
    if not company:
        return JsonResponse([], safe=False)

    user_branch = getattr(request.user, 'branch', None)
    products_qs = Product.objects.filter(company=company, status="active", is_hidden=False).select_related('category')

    if user_branch:
        branch_stock_sq = BranchStock.objects.filter(
            product=OuterRef('pk'),
            branch=user_branch
        ).values('quantity')[:1]
        products_qs = products_qs.annotate(
            local_stock=Coalesce(Subquery(branch_stock_sq, output_field=IntegerField()), 0)
        )
    else:
        # Fallback for admin with no branch (uses global stock)
        products_qs = products_qs.annotate(local_stock=models.F('stock_quantity'))

    products = products_qs.values(
        "id",
        "name",
        "price",
        "wholesale_price",
        "wholesale_min_quantity",
        "barcode",
        "local_stock",
        "image",
        "category__name",
    )

    media_url = request.build_absolute_uri(django_settings.MEDIA_URL)

    # Check if variants feature is enabled for this company's plan
    plan = getattr(company, 'plan', None)
    variants_enabled = bool(plan and getattr(plan, 'feature_product_variants', False))

    # Pre-fetch all active variants for this company in one query
    if variants_enabled:
        all_variant_ids = []
        variants_map = {}
        qs = ProductVariant.objects.filter(
            company=company, product_id__in=[p['id'] for p in products], is_active=True
        ).order_by('sku')
        for v in qs:
            variants_map.setdefault(v.product_id, []).append(v)
            all_variant_ids.append(v.id)

        # If user has a branch, also pre-fetch VariantBranchStock for that branch
        vbs_map = {}  # variant_id → quantity
        if user_branch and all_variant_ids:
            from .models import VariantBranchStock
            for vbs in VariantBranchStock.objects.filter(
                company=company, branch=user_branch, variant_id__in=all_variant_ids
            ).values('variant_id', 'quantity'):
                vbs_map[vbs['variant_id']] = vbs['quantity']

    result = []
    for p in products:
        img = p.get('image') or ''
        row = {
            'id':                    p['id'],
            'name':                  p['name'],
            'price':                 str(p['price']),
            'wholesale_price':       str(p['wholesale_price'] or 0),
            'wholesale_min_quantity':p['wholesale_min_quantity'] or 0,
            'barcode':               p['barcode'] or '',
            'stock_quantity':        p['local_stock'],
            'image':                 (media_url.rstrip('/') + '/' + img.lstrip('/')) if img else '',
            'category':              p['category__name'] or '',
            'has_variants':          False,
            'variants':              [],
        }
        if variants_enabled:
            pvs = variants_map.get(p['id'], [])
            if pvs:
                row['has_variants'] = True
                variant_rows = []
                variant_stock_sum = 0  # total stock shown at product level for variant products

                for v in pvs:
                    # Use branch stock if user has a branch, else global stock
                    if user_branch:
                        v_stock = vbs_map.get(v.id, 0)
                    else:
                        v_stock = v.stock_quantity

                    variant_stock_sum += v_stock

                    # Compute stock_status based on whichever stock we're showing
                    if v_stock <= 0:
                        v_status = 'out_of_stock'
                    elif v_stock <= v.minimum_stock:
                        v_status = 'low_stock'
                    else:
                        v_status = 'in_stock'

                    variant_rows.append({
                        'id':            v.id,
                        'display_label': v.display_label,
                        'sku':           v.sku,
                        'barcode':       v.barcode,
                        'price':         str(v.effective_price),
                        'stock_quantity': v_stock,
                        'stock_status':  v_status,
                    })

                row['variants'] = variant_rows
                # ── CRITICAL FIX: override product-level stock with variant total ──
                # BranchStock for the product itself is stale/irrelevant when using variants.
                row['stock_quantity'] = variant_stock_sum

        result.append(row)

    return JsonResponse(result, safe=False)