"""
排行榜接口 — 基于 houtai 日统计表聚合查询
POST /yonghu/phbhqsj
"""
import logging
from datetime import date, timedelta
from decimal import Decimal

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 (
    PlayerDailyStats,
    ManagerDailyStats,
    LeaderDailyStats,
    MerchantDailyStats,
)
from users.models import UserDashou, UserShangjia, UserGuanshi, UserZuzhang
from users.business_models import User
from rank.display_utils import load_rank_nicknames

logger = logging.getLogger(__name__)

MAX_RANK = 50

RIQI_OPTIONS = frozenset({'今日', '本周', '本月', '总榜', '昨日', '上周', '上月'})
SHENFEN_OPTIONS = frozenset({'dashou', 'guanshi', 'zuzhang', 'shangjia'})

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',
        },
    },
    'guanshi': {
        'model': ManagerDailyStats,
        'id_field': 'ManagerID',
        'sort_field': 'TotalIncome',
        'fields': ('InvitedPlayerCount', 'RechargedPlayerCount', 'TotalIncome'),
        'int_fields': frozenset({'InvitedPlayerCount', 'RechargedPlayerCount'}),
        'response_field_map': {
            'InvitedPlayerCount': 'yaoqing_dashou_shu',
            'RechargedPlayerCount': 'chongzhi_dashou_shu',
            'TotalIncome': 'shouru_zonge',
        },
    },
    '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',
        },
    },
    'shangjia': {
        'model': MerchantDailyStats,
        'id_field': 'MerchantID',
        'sort_field': 'SettledAmount',
        'fields': ('AssignedOrderCount', 'AssignedAmount', 'SettledOrderCount', 'SettledAmount'),
        'int_fields': frozenset({'AssignedOrderCount', 'SettledOrderCount'}),
        'response_field_map': {
            'AssignedOrderCount': 'paifa_dingdan_shu',
            'AssignedAmount': 'paifa_jine',
            'SettledOrderCount': 'jiesuan_dingdan_shu',
            'SettledAmount': 'jiesuan_jine',
        },
    },
}

# "今日"实时数据 — 从用户Profile表读取（jinri系列字段）
TODAY_PROFILE_CONFIG = {
    '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',
            'SettledOrderCount': None,
            'SettledAmount': None,
        },
    },
}


def _resolve_date_range(riqi: str):
    """根据前端 riqi 参数返回 (start_date, end_date) 闭区间。"""
    today = date.today()
    if riqi == '今日':
        return today, today
    if riqi == '昨日':
        d = today - timedelta(days=1)
        return d, d
    if riqi == '本周':
        monday = today - timedelta(days=today.weekday())
        return monday, today
    if riqi == '上周':
        this_monday = today - timedelta(days=today.weekday())
        last_sunday = this_monday - timedelta(days=1)
        last_monday = last_sunday - timedelta(days=6)
        return last_monday, last_sunday
    if riqi == '本月':
        return today.replace(day=1), today
    if riqi == '上月':
        first_this_month = today.replace(day=1)
        last_day_prev = first_this_month - timedelta(days=1)
        return last_day_prev.replace(day=1), last_day_prev
    return None


def _fmt_value(val, is_int: bool):
    if val is None:
        return 0 if is_int else 0.0
    if is_int:
        return int(val)
    if isinstance(val, Decimal):
        return float(val.quantize(Decimal('0.01')))
    return float(val)


class PhbHqsjView(APIView):
    """
    排行榜数据接口
    POST /yonghu/phbhqsj

    请求参数:
      shenfen: dashou | guanshi | zuzhang | shangjia
      riqi:    今日 | 本周 | 本月 | 总榜 | 昨日 | 上周 | 上月

    响应 data.list[]（最多50条，已按各身份排序字段降序）:
      mingci, yonghuid, nicheng, touxiang + 各身份统计字段
    """

    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': []},
            })

        try:
            if riqi == '总榜':
                rows = self._query_rank_rows(shenfen, all_time=True)
            else:
                date_range = _resolve_date_range(riqi)
                if date_range is None:
                    return Response({
                        'code': 400,
                        'msg': '参数错误：无效的日期范围',
                        'data': {'list': []},
                    })
                rows = self._query_rank_rows(shenfen, date_range[0], date_range[1])
            nick_map, avatar_map = self._load_user_display(rows, shenfen)
            cfg = ROLE_CONFIG[shenfen]
            int_fields = cfg['int_fields']
            id_field = cfg['id_field']

            result_list = []
            response_field_map = cfg.get('response_field_map', {})
            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)
                result_list.append(item)

            return Response({
                'code': 200,
                'msg': '获取成功',
                'data': {'list': result_list},
            })
        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_rank_rows(self, shenfen, start_date=None, end_date=None, all_time=False):
        cfg = 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:
            rows = (
                model.objects
                .values(id_field)
                .annotate(**annotate_kwargs)
                .order_by(f'-{sort_field}')[:MAX_RANK]
            )
            return list(rows)

        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
            # 日统计表无数据 — 对于"今日"回退到用户Profile实时字段
            today = date.today()
            if start_date == today:
                return self._query_today_from_profiles(shenfen)
            return rows

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

    def _query_today_from_profiles(self, shenfen):
        """从用户Profile表读取今日实时数据（jinri系列字段）"""
        cfg = ROLE_CONFIG[shenfen]
        today_cfg = TODAY_PROFILE_CONFIG[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)
                if profile_field:
                    row[f] = getattr(p, profile_field)
                else:
                    row[f] = 0
            rows.append(row)
        return rows

    def _load_user_display(self, rows, shenfen):
        id_field = 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
