"""组队 API：/zudui/*"""
from __future__ import annotations

import logging

from rest_framework.parsers import JSONParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from jituan.services.club_context import resolve_club_id_from_request
from orders.models import Order, TeamRecruit, TeamMember
from orders.services import team_recruit as team_svc

logger = logging.getLogger(__name__)


def _club(request):
    return (resolve_club_id_from_request(request) or '').strip()


def _uid(request):
    return getattr(request.user, 'UserUID', None) or ''


def _require_club(request):
    club = _club(request)
    if not club:
        return None, Response({'code': 400, 'msg': '缺少俱乐部'})
    return club, None


def _assert_recruit_same_club(rec, club):
    """组队永不走跨店互通：帖/订单/当前俱乐部必须一致。"""
    if not rec:
        return Response({'code': 404, 'msg': '组队不存在'})
    if (rec.club_id or '') != club:
        return Response({'code': 403, 'msg': '仅本俱乐部可操作组队'})
    order = Order.query.filter(OrderID=rec.order_id).first()
    if not order:
        return Response({'code': 404, 'msg': '订单不存在'})
    if (order.ClubID or '') != club:
        return Response({'code': 403, 'msg': '订单不属于本俱乐部'})
    return None


class ZuduiKaqiView(APIView):
    """开启组队 POST /zudui/kaqi（仅本俱乐部订单，与跨店抢单无关）"""
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        oid = str(request.data.get('dingdan_id') or request.data.get('order_id') or '').strip()
        if not oid:
            return Response({'code': 400, 'msg': '缺少订单ID'})
        order = Order.query.filter(OrderID=oid).first()
        if not order:
            return Response({'code': 404, 'msg': '订单不存在'})
        if (order.ClubID or '') != club:
            return Response({'code': 403, 'msg': '仅本俱乐部订单可开启组队'})
        try:
            rec = team_svc.open_recruit(
                order=order,
                leader_uid=uid,
                need_count=int(request.data.get('need_count') or 1),
                share_mode=request.data.get('share_mode') or 'fixed',
                per_person_amount=request.data.get('per_person_amount'),
                remark=request.data.get('remark') or '',
                leader_game_id=request.data.get('leader_game_id') or request.data.get('game_id') or '',
                min_deal_rate=request.data.get('min_deal_rate'),
                max_fine_rate=request.data.get('max_fine_rate'),
            )
            return Response({
                'code': 0,
                'msg': '已开启组队',
                'data': team_svc.serialize_recruit_public(rec, order, include_game_ids=True),
            })
        except ValueError as e:
            return Response({'code': 400, 'msg': str(e)})
        except Exception as e:
            logger.exception('开启组队失败')
            return Response({'code': 500, 'msg': '服务器错误'})


class ZuduiGaiyaoqiuView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        rid = request.data.get('recruit_id')
        try:
            rid = int(rid)
        except (TypeError, ValueError):
            return Response({'code': 400, 'msg': '缺少 recruit_id'})
        rec = TeamRecruit.query.filter(id=rid).first()
        deny = _assert_recruit_same_club(rec, club)
        if deny:
            return deny
        try:
            kw = {'recruit_id': rid, 'leader_uid': uid}
            if 'need_count' in request.data:
                kw['need_count'] = request.data.get('need_count')
            if 'remark' in request.data:
                kw['remark'] = request.data.get('remark')
            if 'min_deal_rate' in request.data:
                kw['min_deal_rate'] = request.data.get('min_deal_rate')
            if 'max_fine_rate' in request.data:
                kw['max_fine_rate'] = request.data.get('max_fine_rate')
            rec = team_svc.update_recruit(**kw)
            order = Order.query.filter(OrderID=rec.order_id).first()
            return Response({
                'code': 0,
                'msg': '已更新',
                'data': team_svc.serialize_recruit_public(rec, order, include_game_ids=True),
            })
        except ValueError as e:
            return Response({'code': 400, 'msg': str(e)})


class ZuduiGuantingView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        rid = request.data.get('recruit_id')
        try:
            rid = int(rid)
        except (TypeError, ValueError):
            return Response({'code': 400, 'msg': '缺少 recruit_id'})
        rec = TeamRecruit.query.filter(id=rid).first()
        deny = _assert_recruit_same_club(rec, club)
        if deny:
            return deny
        if rec.leader_uid != uid:
            return Response({'code': 403, 'msg': '仅队长可关停'})
        try:
            rec = team_svc.lock_recruit(rid, actor_uid=uid, reason='manual')
            order = Order.query.filter(OrderID=rec.order_id).first()
            return Response({
                'code': 0,
                'msg': '已关停招募',
                'data': team_svc.serialize_recruit_public(rec, order, include_game_ids=True),
            })
        except ValueError as e:
            return Response({'code': 400, 'msg': str(e)})


class ZuduiDatingView(APIView):
    """组队大厅：仅本俱乐部招募中（不读跨店互通）。"""
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        club, err = _require_club(request)
        if err:
            return err
        page = max(1, int(request.data.get('page') or 1))
        page_size = min(50, max(1, int(request.data.get('page_size') or 10)))
        leixing = request.data.get('leixing_id')
        pingtai = request.data.get('fadanpingtai')

        qs = TeamRecruit.query.filter(
            club_id=club,
            status=TeamRecruit.STATUS_RECRUITING,
        ).order_by('-opened_at')

        # 商品类型必选过滤（与前端大厅一致）
        if leixing not in (None, ''):
            try:
                lid = int(leixing)
            except (TypeError, ValueError):
                return Response({'code': 400, 'msg': '商品类型无效'})
            oq = Order.query.filter(ClubID=club, Status=2, ProductTypeID=lid)
            if pingtai not in (None, ''):
                try:
                    oq = oq.filter(Platform=int(pingtai))
                except (TypeError, ValueError):
                    pass
            order_ids = list(oq.values_list('OrderID', flat=True)[:800])
            qs = qs.filter(order_id__in=order_ids or ['__none__'])
        elif pingtai not in (None, ''):
            try:
                oq = Order.query.filter(ClubID=club, Status=2, Platform=int(pingtai))
                order_ids = list(oq.values_list('OrderID', flat=True)[:800])
                qs = qs.filter(order_id__in=order_ids or ['__none__'])
            except (TypeError, ValueError):
                pass

        total = qs.count()
        start = (page - 1) * page_size
        rows = list(qs[start:start + page_size])
        oids = [r.order_id for r in rows]
        orders = {o.OrderID: o for o in Order.query.filter(OrderID__in=oids)} if oids else {}
        data_list = [
            team_svc.serialize_recruit_public(r, orders.get(r.order_id), include_game_ids=False)
            for r in rows
        ]
        badge = {}
        try:
            from orders.services.dashou_badges import dashou_badge_fields
            badge = dashou_badge_fields(club)
        except Exception:
            badge = {}
        return Response({
            'code': 0,
            'msg': 'ok',
            'data': {
                'list': data_list,
                'total': total,
                'page': page,
                'page_size': page_size,
                'has_more': start + len(rows) < total,
                **badge,
            },
        })


class ZuduiXiangqingView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        rid = request.data.get('recruit_id')
        oid = str(request.data.get('dingdan_id') or request.data.get('order_id') or '').strip()
        rec = None
        if rid:
            try:
                rec = TeamRecruit.query.filter(id=int(rid)).first()
            except (TypeError, ValueError):
                pass
        if not rec and oid:
            rec = TeamRecruit.query.filter(order_id=oid, club_id=club).order_by('-id').first()
        if not rec:
            return Response({'code': 404, 'msg': '组队不存在'})
        deny = _assert_recruit_same_club(rec, club)
        if deny:
            return deny

        is_member = TeamMember.query.filter(
            recruit_id=rec.id, user_uid=uid, join_status=TeamMember.JOIN_ACTIVE,
        ).exists()
        include_game = is_member or rec.leader_uid == uid
        order = Order.query.filter(OrderID=rec.order_id).first()
        return Response({
            'code': 0,
            'msg': 'ok',
            'data': team_svc.serialize_recruit_public(rec, order, include_game_ids=include_game),
        })


class ZuduiRuiduiView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        try:
            rid = int(request.data.get('recruit_id'))
        except (TypeError, ValueError):
            return Response({'code': 400, 'msg': '缺少 recruit_id'})
        rec0 = TeamRecruit.query.filter(id=rid).first()
        deny = _assert_recruit_same_club(rec0, club)
        if deny:
            return deny
        try:
            rec = team_svc.join_recruit(
                recruit_id=rid,
                user_uid=uid,
                game_id=request.data.get('game_id') or '',
                request=request,
                require_club_id=club,
            )
            order = Order.query.filter(OrderID=rec.order_id).first()
            return Response({
                'code': 0,
                'msg': '加入成功',
                'data': team_svc.serialize_recruit_public(rec, order, include_game_ids=True),
            })
        except ValueError as e:
            return Response({'code': 400, 'msg': str(e)})
        except Exception:
            logger.exception('加入组队失败')
            return Response({'code': 500, 'msg': '服务器错误'})


class ZuduiWodeView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        uid = _uid(request)
        club, err = _require_club(request)
        if err:
            return err
        as_leader = TeamRecruit.query.filter(
            club_id=club,
            leader_uid=uid,
            status__in=[TeamRecruit.STATUS_RECRUITING, TeamRecruit.STATUS_LOCKED],
        ).order_by('-opened_at')[:50]
        member_rids = list(
            TeamMember.query.filter(
                user_uid=uid, join_status=TeamMember.JOIN_ACTIVE, role=TeamMember.ROLE_MEMBER,
            ).values_list('recruit_id', flat=True)[:50]
        )
        as_member_qs = TeamRecruit.query.filter(
            id__in=member_rids or [0],
            club_id=club,
            status__in=[TeamRecruit.STATUS_RECRUITING, TeamRecruit.STATUS_LOCKED],
        ) if member_rids else []
        as_member = list(as_member_qs) if as_member_qs else []
        as_leader_list = list(as_leader)
        oids = [r.order_id for r in as_leader_list + as_member]
        orders = {o.OrderID: o for o in Order.query.filter(OrderID__in=oids)} if oids else {}
        return Response({
            'code': 0,
            'msg': 'ok',
            'data': {
                'as_leader': [
                    team_svc.serialize_recruit_public(r, orders.get(r.order_id), include_game_ids=True)
                    for r in as_leader_list
                ],
                'as_member': [
                    team_svc.serialize_recruit_public(r, orders.get(r.order_id), include_game_ids=True)
                    for r in as_member
                ],
            },
        })
