"""抢单大厅假单：无资格/封禁打手仅展示假数据。"""
import random
from datetime import datetime, timedelta
from decimal import Decimal

from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.utils import timezone
from django.utils.dateparse import parse_datetime
from rest_framework.response import Response

from backend.utils import fmt_datetime, pick_leixing_id
from jituan.services.club_context import resolve_effective_club_id
from jituan.services.dashou_exam import user_has_active_member
from orders.models import FakeGrabOrder, FakeGrabOrderShuffleState

DEFAULT_DISPATCHER_AVATAR = 'beijing/morentouxiang.jpg'
SHUFFLE_STATE_PK = 1


def dashou_should_use_fake_pool(user):
    """
    打手是否只能看假单：
    - 账号封禁（zhanghaozhuangtai != 1）
    - 或未开通有效会员 且 押金不大于 5
    """
    try:
        dashou = user.DashouProfile
    except ObjectDoesNotExist:
        return True

    if dashou.zhanghaozhuangtai != 1:
        return True

    yajin = Decimal(str(dashou.yajin or 0))
    if yajin > Decimal('5'):
        return False

    if user_has_active_member(user.UserUID):
        return False

    return True


def _scope_key(club_id, leixing_id):
    lid = leixing_id if leixing_id is not None else 'all'
    return f'{club_id}|{lid}'


def _ensure_aware(dt):
    if dt is None:
        return None
    if timezone.is_naive(dt):
        return timezone.make_aware(dt, timezone.get_current_timezone())
    return dt


def _to_unix_ts(dt):
    """统一转为 Unix 时间戳，避免 naive/aware 直接相减报错。"""
    if dt is None:
        return None
    if timezone.is_aware(dt):
        return dt.timestamp()
    try:
        return timezone.make_aware(dt, timezone.get_current_timezone()).timestamp()
    except Exception:
        return dt.timestamp()


def _elapsed_seconds(since_dt, until_dt):
    since_ts = _to_unix_ts(since_dt)
    until_ts = _to_unix_ts(until_dt)
    if since_ts is None or until_ts is None:
        return None
    return until_ts - since_ts


def _parse_shuffle_time(value):
    if not value:
        return None
    if isinstance(value, str):
        dt = parse_datetime(value)
        return _ensure_aware(dt)
    return _ensure_aware(value)


def _display_time_str_for_order(order_id, anchor_dt):
    """同一假单在打乱窗口内展示时间固定。"""
    seed = abs(hash(str(order_id))) % (2 ** 32)
    seconds_ago = 120 + (seed % 181)
    base_ts = _to_unix_ts(_ensure_aware(anchor_dt) or timezone.now())
    if base_ts is None:
        base_ts = _to_unix_ts(timezone.now()) or 0
    display_dt = datetime.fromtimestamp(
        base_ts - seconds_ago,
        tz=timezone.get_current_timezone(),
    )
    return fmt_datetime(display_dt)


def _load_fake_rows_in_saved_order(club_id, leixing_id):
    """
    读取/更新 id=1 打乱状态表：
    - 未满 IntervalSeconds：按库中 order_ids 顺序返回（全用户一致）
    - 已满：重新打乱并写回 order_ids
    - 新增假单：追加到顺序末尾并写回；已删假单：自动跳过
    返回 (rows, anchor_dt) 供展示时间固定。
    """
    qs = FakeGrabOrder.query.filter(ClubID=club_id)
    if leixing_id is not None:
        qs = qs.filter(ProductTypeID=leixing_id)

    all_rows = list(qs)
    id_to_row = {r.OrderID: r for r in all_rows if r.OrderID}
    all_ids = list(id_to_row.keys())
    scope = _scope_key(club_id, leixing_id)
    now = timezone.now()

    with transaction.atomic():
        state, created = FakeGrabOrderShuffleState.objects.select_for_update().get_or_create(
            pk=SHUFFLE_STATE_PK,
            defaults={
                'LastShuffleTime': now - timedelta(days=1),
                'IntervalSeconds': 120,
                'OrderSequence': {},
            },
        )
        interval = max(1, int(state.IntervalSeconds or 120))
        seq_map = dict(state.OrderSequence or {})
        entry = dict(seq_map.get(scope) or {})
        stored_ids = list(entry.get('order_ids') or [])
        last_dt = _parse_shuffle_time(entry.get('last_shuffle_time'))
        if not last_dt and not created:
            last_dt = _ensure_aware(state.LastShuffleTime)

        elapsed = _elapsed_seconds(last_dt, now)
        need_reshuffle = (
            not stored_ids
            or last_dt is None
            or elapsed is None
            or elapsed >= interval
        )

        if need_reshuffle:
            stored_ids = list(all_ids)
            random.shuffle(stored_ids)
            entry = {
                'last_shuffle_time': now.isoformat(),
                'order_ids': stored_ids,
            }
            seq_map[scope] = entry
            state.OrderSequence = seq_map
            state.LastShuffleTime = now
            state.save(update_fields=['OrderSequence', 'LastShuffleTime', 'UpdateTime'])
        else:
            valid_ids = [oid for oid in stored_ids if oid in id_to_row]
            new_ids = [oid for oid in all_ids if oid not in set(valid_ids)]
            if len(valid_ids) != len(stored_ids) or new_ids:
                valid_ids.extend(new_ids)
                entry['order_ids'] = valid_ids
                seq_map[scope] = entry
                state.OrderSequence = seq_map
                state.save(update_fields=['OrderSequence', 'UpdateTime'])
            stored_ids = valid_ids

    anchor_dt = _parse_shuffle_time(entry.get('last_shuffle_time')) or _ensure_aware(now)
    ordered = [id_to_row[oid] for oid in stored_ids if oid in id_to_row]
    return ordered, anchor_dt


def _format_fake_row(row, anchor_dt=None):
    """字段与 DashouDingdanHuoquView 真实单列表保持一致。"""
    avatar = (getattr(row, 'DispatcherAvatar', None) or '').strip() or DEFAULT_DISPATCHER_AVATAR
    platform = int(row.Platform or 1)
    oid = row.OrderID
    price = float(row.Amount or 0)
    ct = _display_time_str_for_order(oid, anchor_dt)
    zid = (row.DispatcherUserID or '').strip()
    sj_name = (getattr(row, 'MerchantNickname', None) or '').strip()

    return {
        'dingdan_id': oid,
        'zhuangtai': 1,
        'pingtai': platform,
        'dashou_fencheng': price,
        'leixing_id': row.ProductTypeID or 0,
        'tupian': avatar,
        'yaoqiuleixing': 0,
        'huiyuan_id': '',
        'yajin': 0.0,
        'jieshao': row.Description or '',
        'beizhu': row.Remark or '',
        'creat_time': ct,
        'create_time': ct,
        'sjnicheng': sj_name if platform == 2 else '',
        'sj_avatar': avatar if platform == 2 else '',
        'zhiding_uid': zid,
        'zhiding_avatar': avatar,
        'zhiding_nicheng': '',
        'xuqiu_biaoqian': [],
        'dashou_biaoqian': [],
        'shangjia_biaoqian': [],
        'shangjia_identity_biaoqian': [],
        'zhiding_identity_biaoqian': [],
        'shangjia_youzhi': bool(row.IsPremiumMerchant) if platform == 2 else False,
    }


def build_fake_order_pool_response(request):
    data = request.data
    leixing_id = pick_leixing_id(data)
    page = max(1, int(data.get('page', 1)))
    page_size = max(1, min(int(data.get('page_size', 10)), 50))

    club_id = resolve_effective_club_id(request, getattr(request, 'user', None))

    rows, anchor_dt = _load_fake_rows_in_saved_order(club_id, leixing_id)

    total = len(rows)
    offset = (page - 1) * page_size
    page_rows = rows[offset:offset + page_size]

    formatted_list = [_format_fake_row(r, anchor_dt) for r in page_rows]
    has_more = (page * page_size) < total

    return Response({
        'code': 200,
        'msg': '获取成功',
        'data': {
            'list': formatted_list,
            'has_more': has_more,
            'total': total,
            'current_page': page,
            'page_size': page_size,
            'total_pages': (total + page_size - 1) // page_size if page_size else 0,
        },
    })
