# api/views.py  — SwiftPOS REST API  (Django REST Framework)
from decimal import Decimal

from django.contrib.auth import authenticate, get_user_model
from django.db.models import Sum, Count, Avg, Q
from django.utils import timezone
from django.http import HttpResponse
from datetime import date, timedelta

from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework.authtoken.models import Token

from inventory.models import (
    Product, ProductCategory, InventoryTransaction,
    Supplier, PurchaseOrder, StockAdjustment
)
from sales.models import POSOrder, POSOrderItem, Customer
from accounts.models import AuditLog
from accounts.audit import log_action
from core.models import Branch, SystemSettings
from core.utils import check_limit_or_block, is_feature_enabled

from .serializers import (
    LoginSerializer, UserSerializer, UserCreateSerializer,
    BranchSerializer,
    CategorySerializer, ProductSerializer, StockAdjustSerializer,
    InventoryTransactionSerializer,
    SupplierSerializer, PurchaseOrderSerializer,
    OrderSerializer, OrderCreateSerializer,
    CustomerSerializer, AuditLogSerializer,
    DashboardSerializer, PnLSerializer,
)

User = get_user_model()


# ─────────────────────────────────────────────────────────────────
# AUTH
# ─────────────────────────────────────────────────────────────────

@api_view(['POST'])
@permission_classes([AllowAny])
def api_login(request):
    """
    POST /api/auth/login/
    Body: { "username": "…", "password": "…" }
    Returns: { "token": "…", "user": {…} }
    """
    ser = LoginSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)

    user = authenticate(
        request,
        username=ser.validated_data['username'],
        password=ser.validated_data['password']
    )
    if not user:
        return Response({'detail': 'Invalid credentials.'}, status=401)
    if not user.is_active:
        return Response({'detail': 'Account inactive.'}, status=403)

    token, _ = Token.objects.get_or_create(user=user)
    log_action(request, 'login', user.username)
    return Response({'token': token.key, 'user': UserSerializer(user).data})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_logout(request):
    """POST /api/auth/logout/  — deletes the token."""
    request.auth.delete()
    log_action(request, 'logout', request.user.username)
    return Response({'detail': 'Logged out.'})


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_me(request):
    """GET /api/auth/me/  — current user profile."""
    return Response(UserSerializer(request.user).data)


# ─────────────────────────────────────────────────────────────────
# USERS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_users(request):
    """
    GET  /api/users/  — list all users (admin only)
    POST /api/users/  — create a user (admin only)
    """
    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    if request.method == 'GET':
        role   = request.query_params.get('role')
        branch = request.query_params.get('branch')
        qs = User.objects.all().order_by('username')
        if role:
            qs = qs.filter(role=role)
        if branch:
            qs = qs.filter(branch_id=branch)
        return Response(UserSerializer(qs, many=True).data)

    # POST
    ser = UserCreateSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    user = ser.save()
    log_action(request, 'user_create', user.username)
    return Response(UserSerializer(user).data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_user_detail(request, pk):
    """GET/PUT/PATCH/DELETE /api/users/<pk>/"""
    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)
    try:
        user = User.objects.get(pk=pk)
    except User.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)

    if request.method == 'GET':
        return Response(UserSerializer(user).data)

    if request.method in ('PUT', 'PATCH'):
        ser = UserSerializer(user, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        log_action(request, 'user_edit', user.username)
        return Response(ser.data)

    # DELETE
    username = user.username
    user.delete()
    log_action(request, 'user_delete', username)
    return Response(status=204)


# ─────────────────────────────────────────────────────────────────
# BRANCHES
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_branches(request):
    """GET /api/branches/  POST /api/branches/"""
    if request.method == 'GET':
        branches = Branch.objects.all().order_by('name')
        return Response(BranchSerializer(branches, many=True).data)

    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)
    ser = BranchSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    branch = ser.save()
    log_action(request, 'branch_create', branch.name)
    return Response(ser.data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_branch_detail(request, pk):
    """GET/PUT/DELETE /api/branches/<pk>/"""
    try:
        branch = Branch.objects.get(pk=pk)
    except Branch.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)

    if request.method == 'GET':
        return Response(BranchSerializer(branch).data)

    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    if request.method in ('PUT', 'PATCH'):
        ser = BranchSerializer(branch, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        return Response(ser.data)

    branch.delete()
    return Response(status=204)


# ─────────────────────────────────────────────────────────────────
# CATEGORIES
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_categories(request):
    if request.method == 'GET':
        return Response(CategorySerializer(ProductCategory.objects.all(), many=True).data)
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    ser = CategorySerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    cat = ser.save()
    log_action(request, 'category_create', cat.name)
    return Response(ser.data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_category_detail(request, pk):
    try:
        cat = ProductCategory.objects.get(pk=pk)
    except ProductCategory.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    if request.method == 'GET':
        return Response(CategorySerializer(cat).data)
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    if request.method in ('PUT', 'PATCH'):
        ser = CategorySerializer(cat, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        return Response(ser.data)
    name = cat.name
    cat.delete()
    log_action(request, 'category_delete', name)
    return Response(status=204)


# ─────────────────────────────────────────────────────────────────
# PRODUCTS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_products(request):
    """
    GET  /api/products/?search=&category=&branch=&status=low_stock
    POST /api/products/
    """
    if request.method == 'GET':
        qs = Product.objects.select_related('category').order_by('name')
        q        = request.query_params.get('search', '')
        category = request.query_params.get('category')
        st       = request.query_params.get('status')
        if q:
            qs = qs.filter(Q(name__icontains=q) | Q(sku__icontains=q) | Q(barcode__icontains=q))
        if category:
            qs = qs.filter(category_id=category)
        if st:
            qs = qs.filter(stock_status=st)
        return Response(ProductSerializer(qs, many=True).data)

    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    try:
        check_limit_or_block('products')
    except Exception as e:
        return Response({'detail': str(e)}, status=403)
    ser = ProductSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    product = ser.save()
    log_action(request, 'product_create', product.name)
    return Response(ser.data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_product_detail(request, pk):
    try:
        product = Product.objects.select_related('category', 'branch').get(pk=pk)
    except Product.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)

    if request.method == 'GET':
        return Response(ProductSerializer(product).data)

    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)

    if request.method in ('PUT', 'PATCH'):
        ser = ProductSerializer(product, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        log_action(request, 'product_edit', product.name)
        return Response(ser.data)

    name = product.name
    product.delete()
    log_action(request, 'product_delete', name)
    return Response(status=204)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_product_stock(request, pk):
    """
    POST /api/products/<pk>/stock/
    Body: { "action": "restock"|"reduce"|"adjust", "quantity": N, "note": "…" }
    """
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)

    ser = StockAdjustSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)

    action   = ser.validated_data['action']
    quantity = ser.validated_data['quantity']
    note     = ser.validated_data.get('note', '')

    if action == 'restock':
        product.stock_quantity += quantity
    elif action == 'reduce':
        if quantity > product.stock_quantity:
            return Response({'detail': 'Cannot reduce below 0.'}, status=400)
        product.stock_quantity -= quantity
    elif action == 'adjust':
        product.stock_quantity = ser.validated_data.get('new_stock', quantity)

    product.save()
    InventoryTransaction.objects.create(
        product=product,
        transaction_type=action,
        quantity=quantity,
        notes=note or f'API {action}',
    )
    log_action(request, f'stock_{action}', product.name)
    return Response(ProductSerializer(product).data)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_stock_history(request):
    """GET /api/stock-history/?product=&type="""
    qs = InventoryTransaction.objects.select_related('product').order_by('-created_at')
    product = request.query_params.get('product')
    ttype   = request.query_params.get('type')
    if product:
        qs = qs.filter(product_id=product)
    if ttype:
        qs = qs.filter(transaction_type=ttype)
    return Response(InventoryTransactionSerializer(qs[:200], many=True).data)


# ─────────────────────────────────────────────────────────────────
# SUPPLIERS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_suppliers(request):
    if request.method == 'GET':
        return Response(SupplierSerializer(Supplier.objects.all(), many=True).data)
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    ser = SupplierSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    ser.save()
    return Response(ser.data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_supplier_detail(request, pk):
    try:
        supplier = Supplier.objects.get(pk=pk)
    except Supplier.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    if request.method == 'GET':
        return Response(SupplierSerializer(supplier).data)
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    if request.method in ('PUT', 'PATCH'):
        ser = SupplierSerializer(supplier, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        return Response(ser.data)
    supplier.delete()
    return Response(status=204)


# ─────────────────────────────────────────────────────────────────
# PURCHASE ORDERS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_purchase_orders(request):
    if request.method == 'GET':
        qs = PurchaseOrder.objects.select_related('supplier').order_by('-created_at')
        return Response(PurchaseOrderSerializer(qs, many=True).data)
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    ser = PurchaseOrderSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    ser.save()
    return Response(ser.data, status=201)


@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_purchase_order_detail(request, pk):
    try:
        po = PurchaseOrder.objects.get(pk=pk)
    except PurchaseOrder.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    if request.method == 'GET':
        return Response(PurchaseOrderSerializer(po).data)
    # POST = mark received
    if request.user.role not in ('admin', 'manager'):
        return Response({'detail': 'Forbidden.'}, status=403)
    po.status      = 'received'
    po.received_at = timezone.now()
    po.save()
    return Response(PurchaseOrderSerializer(po).data)


# ─────────────────────────────────────────────────────────────────
# ORDERS (POS Sales)
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_orders(request):
    """
    GET /api/orders/?date=YYYY-MM-DD&status=&payment_method=&branch=&page=1
    """
    qs = POSOrder.objects.select_related('branch').order_by('-created_at')

    d      = request.query_params.get('date')
    st     = request.query_params.get('status')
    pm     = request.query_params.get('payment_method')
    branch = request.query_params.get('branch')
    q      = request.query_params.get('search')

    if d:
        qs = qs.filter(created_at__date=d)
    if st:
        qs = qs.filter(status=st)
    if pm:
        qs = qs.filter(payment_method=pm)
    if branch:
        qs = qs.filter(branch_id=branch)
    if q:
        qs = qs.filter(
            Q(order_number__icontains=q) |
            Q(customer_name__icontains=q) |
            Q(customer_phone__icontains=q)
        )

    # Role-based filtering
    user = request.user
    if user.role in ('manager', 'cashier') and user.branch_id:
        qs = qs.filter(branch_id=user.branch_id)

    return Response(OrderSerializer(qs[:500], many=True).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_order_create(request):
    """
    POST /api/orders/create/
    Creates a full POS order with items in one request.
    """
    ser = OrderCreateSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)

    data = ser.validated_data
    items_data = data.pop('items')

    # Calculate total
    subtotal = Decimal('0')
    resolved_items = []
    for item in items_data:
        try:
            product = Product.objects.get(pk=item['product_id'], status='active')
        except Product.DoesNotExist:
            return Response({'detail': f"Product {item['product_id']} not found."}, status=400)
        if product.stock_quantity < item['quantity']:
            return Response({'detail': f"Insufficient stock for {product.name}."}, status=400)
        line   = product.price * item['quantity']
        disc   = (line * item.get('discount', Decimal('0'))) / 100
        resolved_items.append({'product': product, 'quantity': item['quantity'],
                                'discount': item.get('discount', 0), 'line': line - disc})
        subtotal += (line - disc)

    discount_amt = (subtotal * data.get('discount', Decimal('0'))) / 100
    final        = subtotal - discount_amt
    change       = max(Decimal('0'), data.get('amount_paid', Decimal('0')) - final)

    import random, string
    order_number = 'ORD-' + ''.join(random.choices(string.digits, k=8))

    order = POSOrder.objects.create(
        order_number   = order_number,
        cashier        = request.user,
        customer_name  = data.get('customer_name', ''),
        customer_phone = data.get('customer_phone', ''),
        payment_method = data.get('payment_method', 'cash'),
        amount_paid    = data.get('amount_paid', 0),
        discount_amount = discount_amt,
        final_amount   = final,
        total_amount   = subtotal,    # Required by POSOrder model
        status         = 'completed',
        branch_id      = data.get('branch') or getattr(request.user, 'branch_id', None),
    )

    for item in resolved_items:
        POSOrderItem.objects.create(
            order      = order,
            product    = item['product'],
            quantity   = item['quantity'],
            unit_price = item['product'].price,
            total_price = item['line'],
        )
        item['product'].stock_quantity -= item['quantity']
        item['product'].save()

    log_action(request, 'order_complete', order.order_number)
    return Response(OrderSerializer(order).data, status=201)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_order_detail(request, pk):
    """GET /api/orders/<pk>/"""
    try:
        order = POSOrder.objects.prefetch_related('posorderitem_set__product').get(pk=pk)
    except POSOrder.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    return Response(OrderSerializer(order).data)


# ─────────────────────────────────────────────────────────────────
# CREDIT ORDERS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_credit_orders(request):
    """GET /api/orders/credit/ — all unpaid credit orders"""
    qs = POSOrder.objects.filter(
        payment_method='credit', status='completed'
    ).exclude(amount_paid__gte=models.F('final_amount')).order_by('-created_at')
    return Response(OrderSerializer(qs, many=True).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_clear_credit(request, pk):
    """POST /api/orders/<pk>/clear-credit/"""
    try:
        order = POSOrder.objects.get(pk=pk, payment_method='credit')
    except POSOrder.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    order.amount_paid = order.final_amount
    order.save()
    log_action(request, 'credit_cleared', order.order_number)
    return Response({'detail': 'Credit cleared.'})


# ─────────────────────────────────────────────────────────────────
# CUSTOMERS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_customers(request):
    if request.method == 'GET':
        q = request.query_params.get('search', '')
        qs = Customer.objects.all().order_by('name')
        if q:
            qs = qs.filter(Q(name__icontains=q) | Q(phone__icontains=q) | Q(email__icontains=q))
        return Response(CustomerSerializer(qs, many=True).data)

    try:
        check_limit_or_block('customers')
    except Exception as e:
        return Response({'detail': str(e)}, status=403)
    ser = CustomerSerializer(data=request.data)
    if not ser.is_valid():
        return Response(ser.errors, status=400)
    customer = ser.save()
    log_action(request, 'customer_create', customer.name)
    return Response(ser.data, status=201)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
@permission_classes([IsAuthenticated])
def api_customer_detail(request, pk):
    try:
        customer = Customer.objects.get(pk=pk)
    except Customer.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    if request.method == 'GET':
        return Response(CustomerSerializer(customer).data)
    if request.method in ('PUT', 'PATCH'):
        ser = CustomerSerializer(customer, data=request.data, partial=(request.method == 'PATCH'))
        if not ser.is_valid():
            return Response(ser.errors, status=400)
        ser.save()
        return Response(ser.data)
    name = customer.name
    customer.delete()
    log_action(request, 'customer_delete', name)
    return Response(status=204)


# ─────────────────────────────────────────────────────────────────
# DASHBOARD
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_dashboard(request):
    """GET /api/dashboard/?date=YYYY-MM-DD"""
    d = request.query_params.get('date')
    target = date.fromisoformat(d) if d else timezone.now().date()

    # To prevent dashboard showing 0s for previous days, fetch all-time data 
    # instead of just today's (or filter properly if your POS relies on all-time)
    qs = POSOrder.objects.filter(status='completed')
    if request.user.role in ('manager', 'cashier') and getattr(request.user, 'branch_id', None):
        qs = qs.filter(branch_id=request.user.branch_id)

    agg = qs.aggregate(
        total_sales=Sum('final_amount'),
        cnt=Count('id'),
    )

    return Response({
        'date':               str(target),
        'today_sales':        agg['total_sales'] or 0,
        'today_transactions': agg['cnt'] or 0,
        'today_customers':    qs.values('customer_phone').distinct().count(),
        'avg_order_value':    float(agg['total_sales'] or 0) / max(agg['cnt'] or 1, 1),
        'low_stock_products': Product.objects.filter(stock_status='low_stock').count(),
        'out_of_stock':       Product.objects.filter(stock_status='out_of_stock').count(),
        'total_users':        User.objects.count(),
        'active_users':       User.objects.filter(is_active=True).count(),
        'payment_breakdown':  list(
            qs.values('payment_method').annotate(
                count=Count('id'), total=Sum('final_amount')
            )
        ),
    })


# ─────────────────────────────────────────────────────────────────
# P&L REPORT
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_pnl(request):
    """
    GET /api/pnl/?date_from=YYYY-MM-DD&date_to=YYYY-MM-DD
    """
    if request.user.role not in ('admin', 'manager', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    today     = timezone.now().date()
    date_from = date.fromisoformat(request.query_params.get('date_from', str(today)))
    date_to   = date.fromisoformat(request.query_params.get('date_to',   str(today)))

    qs = POSOrder.objects.filter(
        created_at__date__gte=date_from,
        created_at__date__lte=date_to,
        status='completed'
    )

    total_revenue = qs.aggregate(total=Sum('final_amount'))['total'] or 0
    credit_outstanding = qs.filter(payment_method='credit').aggregate(
        owed=Sum('final_amount')
    )['owed'] or 0

    # Cost = sum(cost_price * quantity)
    items = POSOrderItem.objects.filter(
        order__in=qs
    ).select_related('product')
    total_cost = sum(
        (i.product.cost_price or 0) * i.quantity for i in items
    )
    total_profit = float(total_revenue) - float(total_cost)

    daily = list(
        qs.extra(select={'day': 'DATE(created_at)'})
          .values('day')
          .annotate(cnt=Count('id'), rev=Sum('final_amount'))
          .order_by('day')
    )

    return Response({
        'date_from':          str(date_from),
        'date_to':            str(date_to),
        'total_revenue':      total_revenue,
        'total_cost':         total_cost,
        'total_profit':       total_profit,
        'credit_outstanding': credit_outstanding,
        'total_orders_count': qs.count(),
        'daily_data':         daily,
        'payment_breakdown':  list(
            qs.values('payment_method').annotate(
                count=Count('id'), revenue=Sum('final_amount')
            )
        ),
    })


# ─────────────────────────────────────────────────────────────────
# STAFF PERFORMANCE
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_staff_performance(request):
    """GET /api/staff-performance/?date=YYYY-MM-DD"""
    if request.user.role not in ('admin', 'manager', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)
    d      = request.query_params.get('date')
    target = date.fromisoformat(d) if d else timezone.now().date()
    data = (
        POSOrder.objects.filter(created_at__date=target, status='completed')
        .values('cashier__username')
        .annotate(
            orders=Count('id'),
            total_sales=Sum('final_amount'),
        )
        .order_by('-total_sales')
    )
    return Response(list(data))


# ─────────────────────────────────────────────────────────────────
# AUDIT LOG
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_audit_log(request):
    """
    GET /api/audit-log/?action=&user=&date_from=&date_to=
    Admin only.
    """
    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    qs = AuditLog.objects.select_related('user').order_by('-timestamp')
    action    = request.query_params.get('action')
    user_q    = request.query_params.get('user')
    date_from = request.query_params.get('date_from')
    date_to   = request.query_params.get('date_to')

    if action:
        qs = qs.filter(action=action)
    if user_q:
        qs = qs.filter(user__username__icontains=user_q)
    if date_from:
        qs = qs.filter(timestamp__date__gte=date_from)
    if date_to:
        qs = qs.filter(timestamp__date__lte=date_to)

    return Response(AuditLogSerializer(qs[:500], many=True).data)


# ─────────────────────────────────────────────────────────────────
# SUSPICIOUS ACTIVITY
# ─────────────────────────────────────────────────────────────────

@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def api_suspicious(request):
    """
    GET  /api/suspicious/?resolved=yes|no
    POST /api/suspicious/<pk>/resolve/  (in detail view)
    """
    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    from sales.models import UnusualTransaction
    qs = UnusualTransaction.objects.select_related('order').order_by('-flagged_at')
    resolved = request.query_params.get('resolved')
    if resolved == 'yes':
        qs = qs.filter(resolved=True)
    elif resolved == 'no':
        qs = qs.filter(resolved=False)

    data = [{
        'id':          flag.id,
        'order_number': flag.order.order_number,
        'reason':       flag.reason,
        'flagged_at':   flag.flagged_at,
        'resolved':     flag.resolved,
        'resolved_by':  str(flag.resolved_by) if flag.resolved_by else None,
    } for flag in qs[:200]]
    return Response(data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_suspicious_resolve(request, pk):
    """POST /api/suspicious/<pk>/resolve/"""
    if request.user.role not in ('admin', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)
    from sales.models import UnusualTransaction
    try:
        flag = UnusualTransaction.objects.get(pk=pk)
    except UnusualTransaction.DoesNotExist:
        return Response({'detail': 'Not found.'}, status=404)
    flag.resolved    = True
    flag.resolved_by = request.user
    flag.save()
    log_action(request, 'suspicious_resolved', flag.order.order_number)
    return Response({'detail': 'Resolved.'})


# ─────────────────────────────────────────────────────────────────
# EXPORTS
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_export_orders(request):
    """
    GET /api/exports/orders/?format=json|csv&date_from=&date_to=
    Returns JSON by default; add ?format=csv for CSV download.
    """
    if request.user.role not in ('admin', 'manager', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)

    qs = POSOrder.objects.select_related('cashier').order_by('-created_at')
    date_from = request.query_params.get('date_from')
    date_to   = request.query_params.get('date_to')
    if date_from:
        qs = qs.filter(created_at__date__gte=date_from)
    if date_to:
        qs = qs.filter(created_at__date__lte=date_to)

    fmt = request.query_params.get('format', 'json')
    if fmt == 'csv':
        import csv, io
        buf = io.StringIO()
        w   = csv.writer(buf)
        w.writerow(['Order No', 'Cashier', 'Customer', 'Phone',
                    'Payment', 'Amount', 'Status', 'Date'])
        for o in qs:
            w.writerow([o.order_number, o.cashier.username if o.cashier else '',
                        o.customer_name, o.customer_phone,
                        o.payment_method, o.final_amount, o.status,
                        o.created_at.strftime('%Y-%m-%d %H:%M')])
        resp = HttpResponse(buf.getvalue(), content_type='text/csv')
        resp['Content-Disposition'] = 'attachment; filename="orders.csv"'
        return resp

    return Response(OrderSerializer(qs[:2000], many=True).data)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_export_products(request):
    """GET /api/exports/products/?format=json|csv"""
    if request.user.role not in ('admin', 'manager', 'superadmin'):
        return Response({'detail': 'Forbidden.'}, status=403)
    qs  = Product.objects.select_related('category').all()
    fmt = request.query_params.get('format', 'json')
    if fmt == 'csv':
        import csv, io
        buf = io.StringIO()
        w   = csv.writer(buf)
        w.writerow(['Name', 'SKU', 'Barcode', 'Category',
                    'Selling Price', 'Cost Price', 'Stock', 'Status'])
        for p in qs:
            w.writerow([p.name, p.sku, p.barcode,
                        p.category.name if p.category else '',
                        p.selling_price, p.cost_price,
                        p.current_stock, p.stock_status])
        resp = HttpResponse(buf.getvalue(), content_type='text/csv')
        resp['Content-Disposition'] = 'attachment; filename="products.csv"'
        return resp
    return Response(ProductSerializer(qs, many=True).data)


# ─────────────────────────────────────────────────────────────────
# BARCODE SCAN
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_barcode_lookup(request):
    """
    GET /api/barcode/?code=<barcode_or_sku>
    Returns the product matching that barcode or SKU.
    """
    code = request.query_params.get('code', '').strip()
    if not code:
        return Response({'detail': 'code parameter required.'}, status=400)
    try:
        product = Product.objects.get(Q(barcode=code) | Q(sku=code), is_active=True)
    except Product.DoesNotExist:
        return Response({'detail': f'No product found for code: {code}'}, status=404)
    except Product.MultipleObjectsReturned:
        product = Product.objects.filter(Q(barcode=code) | Q(sku=code), is_active=True).first()
    return Response(ProductSerializer(product).data)


# ─────────────────────────────────────────────────────────────────
# SYSTEM SETTINGS (read-only for API consumers)
# ─────────────────────────────────────────────────────────────────

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_system_info(request):
    """GET /api/system/  — returns business name, timezone, WhatsApp, etc."""
    settings_obj = SystemSettings.objects.first()
    if not settings_obj:
        return Response({'detail': 'System settings not configured.'}, status=404)
    return Response({
        'business_name':  settings_obj.business_name,
        'business_email': settings_obj.business_email,
        'business_phone': settings_obj.business_phone,
        'address':        settings_obj.business_address,
        'currency':       getattr(settings_obj, 'currency', 'NGN'),
    })


# ─────────────────────────────────────────────────────────────────
# PROMO CODE VALIDATION
# ─────────────────────────────────────────────────────────────────

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_promo_validate(request):
    """
    POST /api/promo/validate/
    Body: { "code": "SAVE10", "order_total": 5000 }
    Returns: { "valid": true/false, "discount_amount": 500, "message": "..." }
    """
    import json as _json
    from core.models import PromoCode

    code        = (request.data.get('code') or '').strip().upper()
    order_total = request.data.get('order_total', 0)

    if not code:
        return Response({'valid': False, 'message': 'No code provided.'})

    try:
        promo = PromoCode.objects.get(code=code)
    except PromoCode.DoesNotExist:
        return Response({'valid': False, 'message': 'Invalid promo code.'})

    if not promo.is_valid:
        msg = 'Promo code is expired or exhausted.' if (promo.is_expired or promo.is_exhausted) else 'Promo code is inactive.'
        return Response({'valid': False, 'message': msg})

    from decimal import Decimal
    total = Decimal(str(order_total))
    if total < promo.minimum_order_amount:
        return Response({
            'valid':   False,
            'message': f'Order must be at least {promo.minimum_order_amount} to use this code.'
        })

    discount = promo.calculate_discount(order_total)

    return Response({
        'valid':           True,
        'discount_amount': float(discount),
        'discount_type':   promo.discount_type,
        'discount_value':  float(promo.discount_value),
        'message':         f'Promo applied! You save {discount}.',
    })
