"""
星之界小程序专用排行榜 — 与 /yonghu/phbhqsj 独立，旧接口零改动。

数据范围与 phbhqsj 相同：集团整体日统计，不按俱乐部拆分。

仅排序/展示规则不同：
- 管事/组长：按邀请人数排序；展示无效邀请、有效人数、收入金额
- 接单员：按成交金额排序
- 商家：按派单流水排序（非成交额）
"""
import logging
from datetime import date

from django.db.models import Sum
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from backend.models import (
    LeaderDailyStats,
    ManagerDailyStats,
    MerchantDailyStats,
    PlayerDailyStats,
)
from users.business_models import User
from users.models import UserDashou, UserGuanshi, UserShangjia, UserBoss, UserZuzhang
from users.paihang_views import (
    MAX_RANK,
    RIQI_OPTIONS,
    SHENFEN_OPTIONS,
    _fmt_value,
    _resolve_date_range,
)

logger = logging.getLogger(__name__)

XZJ_ROLE_CONFIG = {
    'dashou': {
        'model': PlayerDailyStats,
        'id_field': 'PlayerID',
        'sort_field': 'CompletedAmount',
        'fields': (
            'AcceptedOrderTotal', 'CompletedOrderTotal',
            'AcceptedAmount', 'CompletedAmount',
        ),
        'int_fields': frozenset({'AcceptedOrderTotal', 'CompletedOrderTotal'}),
        'response_field_map': {
            'AcceptedOrderTotal': 'jiedan_zongliang',
            'CompletedOrderTotal': 'chengjiao_zongliang',
            'AcceptedAmount': 'jiedan_zonge',
            'CompletedAmount': 'chengjiao_zonge',
        },
        'sort_response_key': 'chengjiao_zonge',
    },
    'guanshi': {
        'model': ManagerDailyStats,
        'id_field': 'ManagerID',
        'sort_field': 'RechargedPlayerCount',
        'fields': ('InvitedPlayerCount', 'RechargedPlayerCount', 'TotalIncome'),
        'int_fields': frozenset({'InvitedPlayerCount', 'RechargedPlayerCount'}),
        'response_field_map': {
            'InvitedPlayerCount': 'yaoqing_dashou_shu',
            'RechargedPlayerCount': 'chongzhi_dashou_shu',
            'TotalIncome': 'shouru_zonge',
        },
        'sort_response_key': 'chongzhi_dashou_shu',
        'wuxiao_field': 'wuxiao_yaoqing_dashou_shu',
        'youxiao_field': 'chongzhi_dashou_shu',
    },
    'zuzhang': {
        'model': LeaderDailyStats,
        'id_field': 'LeaderID',
        'sort_field': 'TotalIncome',
        'fields': ('InvitedManagerCount', 'CommissionAmount', 'TotalIncome'),
        'int_fields': frozenset({'InvitedManagerCount'}),
        'response_field_map': {
            'InvitedManagerCount': 'yaoqing_guanshi_shu',
            'CommissionAmount': 'fenyong_jine',
            'TotalIncome': 'shouru_zonge',
        },
        'sort_response_key': 'shouru_zonge',
        'wuxiao_field': 'wuxiao_yaoqing_guanshi_shu',
        'youxiao_field': 'youxiao_guanshi_shu',
    },
    'shangjia': {
        'model': MerchantDailyStats,
        'id_field': 'MerchantID',
        'sort_field': 'AssignedAmount',
        'fields': ('AssignedOrderCount', 'AssignedAmount'),
        'int_fields': frozenset({'AssignedOrderCount'}),
        'response_field_map': {
            'AssignedOrderCount': 'paifa_dingdan_shu',
            'AssignedAmount': 'paifa_jine',
        },
        'sort_response_key': 'paifa_jine',
    },
}

XZJ_TODAY_PROFILE = {
    'dashou': {
        'profile_model': UserDashou,
        'profile_sort_field': 'jinrishouyi',
        'field_map': {
            'AcceptedOrderTotal': 'jinrijiedan',
            'CompletedOrderTotal': 'jinrijiedan',
            'AcceptedAmount': 'jinrishouyi',
            'CompletedAmount': 'jinrishouyi',
        },
    },
    'guanshi': {
        'profile_model': UserGuanshi,
        'profile_sort_field': 'jinrichongzhi',
        'field_map': {
            'InvitedPlayerCount': 'yaogingshuliang',
            'RechargedPlayerCount': 'jinrichongzhi',
            'TotalIncome': 'chongzhifenrun',
        },
    },
    'zuzhang': {
        'profile_model': UserZuzhang,
        'profile_sort_field': 'fenyong_zonge',
        'field_map': {
            'InvitedManagerCount': 'yaoqing_zongshu',
            'CommissionAmount': 'jinri_fenyong',
            'TotalIncome': 'fenyong_zonge',
        },
    },
    'shangjia': {
        'profile_model': UserShangjia,
        'profile_sort_field': 'jinriliushui',
        'field_map': {
            'AssignedOrderCount': 'jinridingdan',
            'AssignedAmount': 'jinriliushui',
        },
    },
}

# UserZuzhang 用于今日组长 profile 回退


from rank.display_utils import (
    apply_guanshi_wuxiao_fields,
    apply_zuzhang_wuxiao_fields,
    load_rank_nicknames,
)

class XzjPhbHqsjView(APIView):
    """
    星之界排行榜
    POST /yonghu/xzjphbhqsj
    参数同 phbhqsj：shenfen, riqi
    """

    permission_classes = [IsAuthenticated]

    def post(self, request):
        shenfen = (request.data.get('shenfen') or '').strip()
        riqi = (request.data.get('riqi') or '').strip()

        if shenfen not in SHENFEN_OPTIONS:
            return Response({
                'code': 400,
                'msg': '参数错误：shenfen 必须为 dashou/guanshi/zuzhang/shangjia',
                'data': {'list': []},
            })
        if riqi not in RIQI_OPTIONS:
            return Response({
                'code': 400,
                'msg': '参数错误：riqi 必须为 今日/本周/本月/总榜/昨日/上周/上月',
                'data': {'list': []},
            })

        date_range = None
        if riqi != '总榜':
            date_range = _resolve_date_range(riqi)
            if date_range is None:
                return Response({
                    'code': 400,
                    'msg': '参数错误：无效的日期范围',
                    'data': {'list': []},
                })

        try:
            if riqi == '总榜' and shenfen in ('guanshi', 'zuzhang'):
                from rank.reward_services import (
                    TOTAL_RANK_INVITE_SORT_FIELDS,
                    TOTAL_RANK_INVITE_SORT_LABEL,
                    enrich_rank_stats,
                    query_total_rank_invite_rows,
                )
                rank_rows = query_total_rank_invite_rows(shenfen, club_id=None, limit=MAX_RANK)
                cfg = XZJ_ROLE_CONFIG[shenfen]
                id_field = cfg['id_field']
                sort_key = TOTAL_RANK_INVITE_SORT_FIELDS[shenfen]
                pseudo_rows = [{id_field: r['yonghuid']} for r in rank_rows]
                nick_map, avatar_map = self._load_user_display(pseudo_rows, shenfen)
                yonghuids = [r['yonghuid'] for r in rank_rows]
                stats_map = enrich_rank_stats(shenfen, yonghuids, riqi, '')
                result_list = []
                for idx, row in enumerate(rank_rows):
                    yonghuid = row['yonghuid']
                    metric = int(row.get('metric') or 0)
                    item = {
                        'mingci': idx + 1,
                        'yonghuid': yonghuid,
                        'nicheng': nick_map.get(yonghuid, '用户'),
                        'touxiang': avatar_map.get(yonghuid, '') or '',
                        sort_key: metric,
                        'sort_field': sort_key,
                        'metric_value': metric,
                        'metric_label': TOTAL_RANK_INVITE_SORT_LABEL,
                    }
                    extra = stats_map.get(yonghuid) or {}
                    for k, v in extra.items():
                        item[k] = v
                    result_list.append(item)
                return Response({
                    'code': 200,
                    'msg': '获取成功',
                    'data': {
                        'list': result_list,
                        'sort_field': sort_key,
                        'sort_label': TOTAL_RANK_INVITE_SORT_LABEL,
                    },
                })

            if riqi == '总榜':
                rows = self._query_rows(shenfen, all_time=True)
                start_date, end_date = None, None
            else:
                start_date, end_date = date_range
                rows = self._query_rows(shenfen, start_date, end_date)

            nick_map, avatar_map = self._load_user_display(rows, shenfen)
            cfg = XZJ_ROLE_CONFIG[shenfen]
            int_fields = cfg['int_fields']
            id_field = cfg['id_field']
            response_field_map = cfg.get('response_field_map', {})

            result_list = []
            for idx, row in enumerate(rows):
                yonghuid = row[id_field]
                item = {
                    'mingci': idx + 1,
                    'yonghuid': yonghuid,
                    'nicheng': nick_map.get(yonghuid, '用户'),
                    'touxiang': avatar_map.get(yonghuid, '') or '',
                }
                for field in cfg['fields']:
                    response_key = response_field_map.get(field, field)
                    item[response_key] = _fmt_value(row.get(field), field in int_fields)

                if shenfen == 'guanshi':
                    apply_guanshi_wuxiao_fields(item)
                elif shenfen == 'zuzhang':
                    apply_zuzhang_wuxiao_fields(item, yonghuid, start_date, end_date)

                result_list.append(item)

            return Response({
                'code': 200,
                'msg': '获取成功',
                'data': {
                    'list': result_list,
                    'sort_field': cfg.get('sort_response_key'),
                },
            })
        except Exception as e:
            logger.error('星之界排行榜失败 shenfen=%s riqi=%s: %s', shenfen, riqi, e, exc_info=True)
            return Response({
                'code': 500,
                'msg': '服务器内部错误',
                'data': {'list': []},
            })

    def _query_rows(self, shenfen, start_date=None, end_date=None, all_time=False):
        cfg = XZJ_ROLE_CONFIG[shenfen]
        model = cfg['model']
        sort_field = cfg['sort_field']
        fields = cfg['fields']
        id_field = cfg['id_field']
        annotate_kwargs = {f: Sum(f) for f in fields}

        if all_time:
            return list(
                model.objects.values(id_field)
                .annotate(**annotate_kwargs)
                .order_by(f'-{sort_field}')[:MAX_RANK]
            )

        if start_date == end_date:
            qs = model.objects.filter(Date=start_date).order_by(f'-{sort_field}')[:MAX_RANK]
            rows = [
                {id_field: getattr(r, id_field), **{f: getattr(r, f) for f in fields}}
                for r in qs
            ]
            if rows:
                return rows
            if start_date == date.today():
                return self._query_today_profiles(shenfen)
            return rows

        return list(
            model.objects.filter(Date__gte=start_date, Date__lte=end_date)
            .values(id_field)
            .annotate(**annotate_kwargs)
            .order_by(f'-{sort_field}')[:MAX_RANK]
        )

    def _query_today_profiles(self, shenfen):
        cfg = XZJ_ROLE_CONFIG[shenfen]
        today_cfg = XZJ_TODAY_PROFILE[shenfen]
        profile_model = today_cfg['profile_model']
        profile_sort = today_cfg['profile_sort_field']
        field_map = today_cfg['field_map']
        id_field = cfg['id_field']
        fields = cfg['fields']

        qs = profile_model.objects.filter(
            **{f'{profile_sort}__gt': 0}
        ).select_related('user').order_by(f'-{profile_sort}')[:MAX_RANK]

        rows = []
        for p in qs:
            uid = p.user.UserUID
            row = {id_field: uid}
            for f in fields:
                profile_field = field_map.get(f)
                row[f] = getattr(p, profile_field, 0) if profile_field else 0
            rows.append(row)
        return rows

    def _load_user_display(self, rows, shenfen):
        id_field = XZJ_ROLE_CONFIG[shenfen]['id_field']
        yonghuids = [r[id_field] for r in rows if r.get(id_field)]
        if not yonghuids:
            return {}, {}

        users = User.objects.filter(UserUID__in=yonghuids)
        avatar_map = {u.UserUID: u.Avatar or '' for u in users}
        nick_map = load_rank_nicknames(shenfen, yonghuids)
        return nick_map, avatar_map
