from django.utils.dateparse import parse_date
from rest_framework import status
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.common.permissions import IsAdmin

from . import services
from .models import Order
from .serializers import (
    BatchOrderSerializer,
    OrderDetailSerializer,
    OrderSerializer,
)


def _scoped_qs(request):
    """Admins see all orders; sellers see only their own."""
    qs = Order.objects.select_related('user', 'product').all()
    if request.user.role != 'admin':
        qs = qs.filter(user=request.user)
    return qs


class SalesListView(ListAPIView):
    """GET /sales (paginated, filtered) · POST /sales (single order)."""

    serializer_class = OrderSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        qs = _scoped_qs(self.request)
        params = self.request.query_params

        statuses = params.get('status')
        if statuses:
            qs = qs.filter(status__in=[s.strip() for s in statuses.split(',') if s.strip()])

        search = params.get('search')
        if search:
            qs = qs.filter(product_name__icontains=search) | qs.filter(
                order_number__icontains=search) | qs.filter(
                customer_name__icontains=search)

        date_from = parse_date(params.get('date_from') or '')
        date_to = parse_date(params.get('date_to') or '')
        if date_from:
            qs = qs.filter(created_at__date__gte=date_from)
        if date_to:
            qs = qs.filter(created_at__date__lte=date_to)

        return qs.order_by('-created_at')

    def post(self, request):
        # Single-item convenience wrapper over the batch service.
        item = {
            'product_id': request.data.get('product_id'),
            'quantity': request.data.get('quantity') or 1,
            'selected_size': request.data.get('selected_size') or '',
            'selected_color': request.data.get('selected_color') or '',
            'notes': request.data.get('notes') or '',
        }
        seller = self._resolve_seller(request)
        result = services.place_order(
            seller=seller, items=[item],
            customer_name=request.data.get('customer_name') or '',
            customer_phone=request.data.get('customer_phone') or '')
        first = result['items'][0]
        return Response(
            {'id': first['id'], 'commission': first['commission'],
             'status': result['status'], 'order_number': result['order_number'],
             'message': 'Order recorded'},
            status=status.HTTP_201_CREATED)

    @staticmethod
    def _resolve_seller(request):
        # Admins may place an order on behalf of another seller via user_id.
        if request.user.role == 'admin' and request.data.get('user_id'):
            from apps.accounts.models import User
            return User.objects.filter(pk=request.data['user_id']).first() or request.user
        return request.user


class SalesBatchView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        serializer = BatchOrderSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        seller = SalesListView._resolve_seller(request)
        result = services.place_order(
            seller=seller, items=data['items'],
            customer_name=data.get('customer_name', ''),
            customer_phone=data.get('customer_phone', ''))
        return Response({**result, 'message': 'Order placed'}, status=status.HTTP_201_CREATED)


class SalesDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def _get(self, request, pk):
        return _scoped_qs(request).filter(pk=pk).first()

    def get(self, request, pk):
        order = self._get(request, pk)
        if not order:
            return Response({'error': 'Order not found'}, status=status.HTTP_404_NOT_FOUND)
        return Response(OrderDetailSerializer(order).data)

    def delete(self, request, pk):
        if request.user.role != 'admin':
            return Response({'error': 'Admin only'}, status=status.HTTP_403_FORBIDDEN)
        order = Order.objects.filter(pk=pk).first()
        if not order:
            return Response({'error': 'Order not found'}, status=status.HTTP_404_NOT_FOUND)
        order.delete()
        return Response({'message': 'Order deleted'})


class SalesStatusView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request, pk):
        order = _scoped_qs(request).filter(pk=pk).first()
        if not order:
            return Response({'error': 'Order not found'}, status=status.HTTP_404_NOT_FOUND)
        new_status = request.data.get('status')
        if not new_status:
            return Response({'error': 'status is required'}, status=status.HTTP_400_BAD_REQUEST)
        services.transition_status(
            order=order, new_status=new_status, actor=request.user,
            note=request.data.get('note') or '',
            is_admin=request.user.role == 'admin')
        return Response({'message': 'Status updated'})


class SalesLogisticsView(APIView):
    permission_classes = [IsAdmin]

    def put(self, request, pk):
        order = Order.objects.filter(pk=pk).first()
        if not order:
            return Response({'error': 'Order not found'}, status=status.HTTP_404_NOT_FOUND)
        value = request.data.get('logistics_status')
        if value not in dict(Order.Logistics.choices):
            return Response({'error': 'Invalid logistics_status'}, status=status.HTTP_400_BAD_REQUEST)
        order.logistics_status = value
        order.save(update_fields=['logistics_status', 'updated_at'])
        return Response({'message': 'Logistics updated'})


class SalesPaymentProofView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request, pk):
        order = _scoped_qs(request).filter(pk=pk).first()
        if not order:
            return Response({'error': 'Order not found'}, status=status.HTTP_404_NOT_FOUND)
        if order.status not in (Order.Status.APPROVED, Order.Status.PAYMENT_REJECTED):
            return Response({'error': 'Payment proof not accepted at this stage'},
                            status=status.HTTP_400_BAD_REQUEST)
        files = request.data.get('files') or []
        order.payment_proof = list(files)
        order.status = Order.Status.PAYMENT_UPLOADED
        order.save(update_fields=['payment_proof', 'status', 'updated_at'])
        return Response({'message': 'Payment proof uploaded'})
