"""子客服专用订单接口（不修改商家原接口）。"""
import logging

from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from backend.utils import pick_order_id
from merchant_ops.helpers import proxy_merchant_order_view
from merchant_ops.services.authz import (
    StaffAuthError, require_active_staff_member, member_has_perm, staff_order_read_perm,
)
from merchant_ops.services.order_query import (
    staff_apply_order_filters,
    staff_can_view_all_orders,
    staff_order_ext_qs,
)
from merchant_ops.services.audit import audit_staff
from merchant_ops.services.dispatch import staff_dispatch_order
from merchant_ops.services.stats import bump_cancel_count, bump_penalty_count
from merchant_ops.models import MerchantOrderDispatch
from orders.models import MerchantOrderExt
from orders.views import (
    ShangjiaDingdanXiangqingView, ShangjiaJiesuanView, ShangjiaChexiaoView,
    ShangjiaTuikuanShenqingView, ShangjiaFakuanApplyView, ShangjiaFakuaiXiugaiView,
    ZxsjghdsView, ShangpinLeixingView,
)

logger = logging.getLogger(__name__)


def _require_staff(request):
    return require_active_staff_member(request.user)


def _err(e):
    if isinstance(e, StaffAuthError):
        return Response({'code': e.code, 'msg': e.msg, 'data': None})
    logger.exception(e)
    return Response({'code': 500, 'msg': '服务器错误', 'data': None})


class StaffOrderListView(APIView):
    """
    POST /yonghu/merchant-staff/order/list
    - 有 order_view_all：该商家全部订单
    - 否则：仅 merchant_order_dispatch 中 staff_member_id=本人的订单
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            if not member_has_perm(member, 'order_view_all') and not member_has_perm(member, 'order_view_self'):
                raise StaffAuthError(403, '无订单查看权限')

            data = request.data
            zhuangtai_list = data.get('zhuangtai_list', [])
            page = max(1, int(data.get('page', 1)))
            page_size = min(100, max(1, int(data.get('page_size', 10))))

            if not isinstance(zhuangtai_list, list) or not zhuangtai_list:
                return Response({'code': 3, 'msg': '状态列表不能为空', 'data': None})

            base_qs = staff_apply_order_filters(
                staff_order_ext_qs(member, zhuangtai_list),
                data,
            )

            pending_qs = staff_order_ext_qs(member, [8])
            pending_count = pending_qs.count()
            from orders.services.merchant_order_stats import build_merchant_order_stats

            stats_qs = staff_order_ext_qs(member, None)
            stats_qs = staff_apply_order_filters(stats_qs, data)
            order_stats = build_merchant_order_stats(stats_qs)

            can_finance = member_has_perm(member, 'finance_view')
            if not can_finance:
                for k in list(order_stats.keys()):
                    if k.endswith('_amount'):
                        order_stats[k] = '0.00'

            total_count = base_qs.count()
            start = (page - 1) * page_size
            page_qs = list(base_qs.order_by('-Order__CreateTime')[start:start + page_size])

            from jituan.services.club_context import resolve_club_id_from_request
            from orders.services.merchant_order_list_enrich import enrich_merchant_order_list_items

            club_id = resolve_club_id_from_request(request)
            order_list = enrich_merchant_order_list_items(page_qs, club_id=club_id)

            return Response({
                'code': 0,
                'msg': '成功',
                'data': {
                    'list': order_list,
                    'has_more': start + len(page_qs) < total_count,
                    'total': total_count,
                    'pending_count': order_stats['pending_count'],
                    'pending_amount': order_stats['pending_amount'] if can_finance else '0.00',
                    'order_stats': order_stats,
                    'can_view_finance': can_finance,
                    'view_scope': 'all' if staff_can_view_all_orders(member) else 'self',
                },
            })
        except Exception as e:
            return _err(e)


class StaffOrderStatsView(APIView):
    """子客服/老板视角订单统计 POST /yonghu/merchant-staff/order/stats"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            if not member_has_perm(member, 'order_view_all') and not member_has_perm(member, 'order_view_self'):
                raise StaffAuthError(403, '无订单查看权限')

            data = request.data or {}
            from orders.services.merchant_order_stats import build_merchant_order_stats, filter_by_staff_member
            from orders.models import MerchantOrderExt

            filter_payload = dict(data)
            filter_payload['_merchant_id_filter'] = member.merchant_id

            qs = MerchantOrderExt.query.filter(
                MerchantID=member.merchant_id,
            ).select_related('Order')

            if not staff_can_view_all_orders(member):
                own_ids = list(
                    MerchantOrderDispatch.query.filter(staff_member_id=member.id).values_list('order_id', flat=True)
                )
                qs = qs.filter(Order__OrderID__in=own_ids)
            elif data.get('staff_member_id'):
                qs = filter_by_staff_member(qs, member.merchant_id, data.get('staff_member_id'))

            qs = staff_apply_order_filters(qs, filter_payload)
            order_stats = build_merchant_order_stats(qs)

            can_finance = member_has_perm(member, 'finance_view')
            if not can_finance:
                for k in list(order_stats.keys()):
                    if k.endswith('_amount'):
                        order_stats[k] = '0.00'

            return Response({
                'code': 0,
                'msg': '成功',
                'data': {
                    'order': order_stats,
                    'can_view_finance': can_finance,
                },
            })
        except Exception as e:
            return _err(e)


class StaffOrderDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            if not member_has_perm(member, 'order_detail'):
                raise StaffAuthError(403, '无权限')
            resp = proxy_merchant_order_view(
                request, member, ShangjiaDingdanXiangqingView, 'order_detail',
            )
            if resp.status_code == 200 and resp.data.get('code') == 0 and resp.data.get('data'):
                from merchant_ops.services.order_enrich import enrich_order_detail_data
                enrich_order_detail_data(resp.data['data'], pick_order_id(request.data))
            return resp
        except Exception as e:
            return _err(e)


class StaffDispatchView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            if not member_has_perm(member, 'order_dispatch'):
                raise StaffAuthError(403, '无派单权限')
            ok, payload = staff_dispatch_order(member, request.user, request.data)
            if ok:
                audit_staff(member, 'DISPATCH', request,
                            resource_id=payload.get('data', {}).get('dingdan_id'),
                            amount=request.data.get('jiage'))
            code = payload.get('code', 500)
            return Response(payload, status=status.HTTP_200_OK if code in (0, 200) else status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return _err(e)


class StaffProductTypesView(APIView):
    """商品类型 — 代理 sjspleixing"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            perm = staff_order_read_perm(member)
            if not perm:
                raise StaffAuthError(403, '无权限查看商品类型')
            return proxy_merchant_order_view(request, member, ShangpinLeixingView, perm)
        except Exception as e:
            return _err(e)


class StaffSettleView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ShangjiaJiesuanView, 'order_settle')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'SETTLE', request, resource_id=pick_order_id(request.data))
            return resp
        except Exception as e:
            return _err(e)


class StaffCancelView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ShangjiaChexiaoView, 'order_cancel')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'CANCEL', request, resource_id=pick_order_id(request.data))
                bump_cancel_count(member.merchant_id, member)
            return resp
        except Exception as e:
            return _err(e)


class StaffRefundView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ShangjiaTuikuanShenqingView, 'order_refund_apply')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'REFUND_APPLY', request, resource_id=pick_order_id(request.data))
            return resp
        except Exception as e:
            return _err(e)


class StaffPenaltyApplyView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ShangjiaFakuanApplyView, 'penalty_apply')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'PENALTY_APPLY', request, resource_id=pick_order_id(request.data))
                bump_penalty_count(member.merchant_id, member)
            return resp
        except Exception as e:
            return _err(e)


class StaffPenaltyManageView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ShangjiaFakuaiXiugaiView, 'penalty_manage')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'PENALTY_MANAGE', request, resource_id=pick_order_id(request.data))
            return resp
        except Exception as e:
            return _err(e)


class StaffChangePlayerView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            member = _require_staff(request)
            resp = proxy_merchant_order_view(request, member, ZxsjghdsView, 'order_change_player')
            if resp.data.get('code') in (0, 200):
                audit_staff(member, 'CHANGE_PLAYER', request, resource_id=pick_order_id(request.data))
            return resp
        except Exception as e:
            return _err(e)
