import eventlet
import random
import time
import threading
import logging
import json
from copy import deepcopy
from combat import generate_uuid
from state_manager import player_state_manager, mark_dirty
from notification import send_public, send_private, broadcast_world_boss_event
from online_state import online_cache, cache_lock
from log_utils import log_player_event
from config_center import CONFIG
from db_storage import load_state_from_tables

logger = logging.getLogger(__name__)

class WorldBossManager:
    PREFIXES = {
        "精英": {"multiplier": 1.2, "level_increment": 5, "attack_speed_multiplier": 0.8},
        "史诗": {"multiplier": 1.5, "level_increment": 10, "attack_speed_multiplier": 0.7},
        "传说": {"multiplier": 2.0, "level_increment": 15, "attack_speed_multiplier": 0.8},
        "神话": {"multiplier": 3.0, "level_increment": 20, "attack_speed_multiplier": 0.6}
    }

    def __init__(self, socketio, game_engine, stop_auto_combat_callback=None):
        self.socketio = socketio
        self.game_engine = game_engine
        self.lock = threading.RLock()
        self.active_boss = None
        self.refresh_timer = None
        self.boss_templates = []
        self.selected_boss_id = None
        self._init_from_config()
        self._start_broadcast_thread()
        self.pending_draws = {}
        self.current_boss_map = None
        self.draw_timeout = 10
        self.stop_auto_combat_callback = stop_auto_combat_callback

    def _init_from_config(self):
        try:
            import sqlite3
            from static_db import db
            conn = db.get_static_conn()
            cursor = conn.cursor()
            cursor.execute("SELECT COUNT(*) FROM monsters WHERE is_world_boss = 1")
            total = cursor.fetchone()[0]
            logger.info(f"世界Boss模板总数: {total}")
            
            cursor.execute("""
                SELECT id, name, level, maxHp, attack_min, attack_max, 
                       defense_min, defense_max, exp, gold, 
                       accuracy, dodge, refresh_interval, skills, icon
                FROM monsters 
                WHERE is_world_boss = 1
            """)
            rows = cursor.fetchall()
            db.return_static_conn(conn)

            bosses = []
            for row in rows:
                boss = {
                    'id': row[0],
                    'name': row[1],
                    'level': row[2],
                    'maxHp': row[3],
                    'attackMin': row[4],
                    'attackMax': row[5],
                    'defenseMin': row[6],
                    'defenseMax': row[7],
                    'exp': row[8],
                    'gold': row[9],
                    'accuracy': row[10] or 50,
                    'dodge': row[11] or 50,
                    'refresh_interval': row[12] or 3600,
                    'skills': json.loads(row[13]) if row[13] else [],
                    'icon': row[14] or ''
                }
                bosses.append(boss)
            
            if not bosses:
                logger.warning("数据库中没有 is_world_boss=1 的怪物，无法生成世界Boss")
            self.boss_templates = bosses
            
        except Exception as e:
            logger.error(f"从数据库加载世界Boss模板失败: {e}")
            self.boss_templates = []
        
        # 尝试立即生成，如果失败则安排延迟重试
        try:
            self._schedule_refresh(immediate=True)
        except Exception as e:
            logger.error(f"启动世界Boss失败: {e}，将在60秒后重试")
            self._schedule_refresh(delay_seconds=60)

    def _get_online_players(self):
        with cache_lock:
            return set(online_cache.keys())

    def _schedule_refresh(self, immediate=False, delay_seconds=None):
        with self.lock:
            if self.refresh_timer and not self.refresh_timer.dead:
                self.refresh_timer.kill()
            self.refresh_timer = None

            if immediate:
                self._generate_new_boss()
                self._next_refresh_time = None
            else:
                refresh_interval = delay_seconds
                if refresh_interval is None:
                    if self.active_boss and self.active_boss.get('boss'):
                        refresh_interval = self.active_boss['boss'].get('refresh_interval', 3600)
                    elif self.boss_templates:
                        refresh_interval = self.boss_templates[0].get('refresh_interval', 3600)
                    else:
                        refresh_interval = 3600
                self._next_refresh_time = time.time() + refresh_interval
                self.refresh_timer = eventlet.spawn_after(refresh_interval, self._generate_new_boss)
                logger.info(f"世界 Boss 将在 {refresh_interval} 秒后刷新")

    def _generate_new_boss(self):
        try:
            with self.lock:
                # ========== 关键修复：禁止覆盖存活的世界Boss ==========
                if self.active_boss and self.active_boss['boss'].get('currentHp', 0) > 0:
                    logger.info(f"当前仍有存活Boss {self.active_boss['boss']['name']}，放弃刷新")
                    return

                # 如果有旧的Boss（已死亡或None），发送消失事件
                if self.active_boss:
                    old_map = self.active_boss['map_id']
                    self.socketio.emit('world_boss_disappear', {
                        'map_id': old_map,
                        'boss_name': self.active_boss['boss']['name']
                    }, room=f'map_{old_map}')

                if not self.boss_templates:
                    logger.error("世界 Boss 模板列表为空，60秒后重试")
                    self._schedule_refresh(delay_seconds=60)
                    return

                if self.selected_boss_id:
                    template = next((b for b in self.boss_templates if b.get('id') == self.selected_boss_id), None)
                    if not template:
                        template = random.choice(self.boss_templates)
                else:
                    template = random.choice(self.boss_templates)

                boss = deepcopy(template)
                boss['icon'] = template.get('icon', '')
                boss['id'] = template.get('id')
                boss['refresh_interval'] = template.get('refresh_interval', 3600)

                prefix_name = random.choice(list(self.PREFIXES.keys()))
                prefix_cfg = self.PREFIXES[prefix_name]
                multiplier = prefix_cfg["multiplier"]
                level_increment = prefix_cfg["level_increment"]

                boss['name'] = f"{prefix_name} {boss['name']}"
                boss['maxHp'] = int(boss['maxHp'] * multiplier)
                boss['currentHp'] = boss['maxHp']
                boss['attackMin'] = int(boss.get('attackMin', 100) * multiplier)
                boss['attackMax'] = int(boss.get('attackMax', 200) * multiplier)
                boss['defenseMin'] = int(boss.get('defenseMin', 100) * multiplier)
                boss['defenseMax'] = int(boss.get('defenseMax', 200) * multiplier)
                boss['exp'] = int(boss.get('exp', 0) * multiplier)
                boss['gold'] = int(boss.get('gold', 0) * multiplier)
                boss['accuracy'] = int(boss.get('accuracy', 50) * multiplier)
                boss['dodge'] = int(boss.get('dodge', 50) * multiplier)
                boss['level'] = boss.get('level', 50) + level_increment
                boss['uuid'] = generate_uuid()
                boss['isAlive'] = True
                boss['isBoss'] = True
                boss['isWorldBoss'] = True
                if 'skills' not in boss:
                    boss['skills'] = []
                boss['last_attack_time'] = time.time() + random.uniform(0, 0.5)
                boss['threat_table'] = {'player': 0, 'hero': 0}
                boss['active'] = False

                base_interval = self.game_engine.monster_base_attack_interval
                boss['attack_interval'] = base_interval * prefix_cfg.get("attack_speed_multiplier", 1.0)
                boss['attack_interval'] = max(0.3, boss['attack_interval'])

                maps = CONFIG.get('maps', [])
                if not maps:
                    logger.error("无地图配置，60秒后重试")
                    self._schedule_refresh(delay_seconds=60)
                    return

                eligible_maps = [m for m in maps if m.get('minLevel', 0) >= 40]
                if not eligible_maps:
                    logger.error("没有 minLevel >= 40 的地图，无法生成世界Boss，3600秒后重试")
                    self._schedule_refresh(delay_seconds=3600)
                    return

                current_map = self.active_boss['map_id'] if self.active_boss else None
                candidates = [m['id'] for m in eligible_maps if m['id'] != current_map]
                if not candidates:
                    candidates = [m['id'] for m in eligible_maps]
                if not candidates:
                    logger.error("没有可用的地图ID，60秒后重试")
                    self._schedule_refresh(delay_seconds=60)
                    return

                map_id = random.choice(candidates)
                map_data = next((m for m in maps if m['id'] == map_id), None)
                map_name = map_data['name'] if map_data else f"地图{map_id}"

                self.active_boss = {
                    'map_id': map_id,
                    'map_name': map_name,
                    'boss': boss,
                    'damage_records': {},
                    'participants': set(),
                    'last_hit_time': time.time(),
                    'spawn_time': time.time()
                }
                self._next_refresh_time = None
                logger.info(f"世界 Boss {boss['name']} 刷新在地图 {map_id} ({map_name})")
        except Exception as e:
            logger.exception(f"生成世界 Boss 时发生严重异常: {e}")
            self._schedule_refresh(delay_seconds=60)

    def get_boss_raw(self, map_id):
        with self.lock:
            if (self.active_boss and
                    self.active_boss['map_id'] == map_id and
                    self.active_boss['boss'].get('currentHp', 0) > 0):
                return self.active_boss['boss']
        return None

    def take_damage(self, player_name, map_id, damage, record=True):
        with self.lock:
            if not self.active_boss or self.active_boss['map_id'] != map_id:
                return False, False
            boss = self.active_boss['boss']
            if boss.get('currentHp', 0) <= 0:
                return False, False
            # 如果 player_name 为 'unknown' 且 record=True，则自动设为 None（不记录伤害）
            if record and (player_name is None or player_name == 'unknown' or not player_name.strip()):
                player_name = None
            if record and player_name:
                self.active_boss['damage_records'][player_name] = \
                    self.active_boss['damage_records'].get(player_name, 0) + damage
                self.active_boss['participants'].add(player_name)
            old_hp = boss['currentHp']
            boss['currentHp'] = max(0, boss['currentHp'] - damage)
            actual_damage = old_hp - boss['currentHp']
            if actual_damage > 0:
                # 获取攻击者的 sid，以便排除
                attacker_sid = None
                if player_name:
                    with cache_lock:
                        info = online_cache.get(player_name)
                        if info:
                            attacker_sid = info.get('sid')
                # 广播伤害给同地图其他玩家（排除攻击者本人）
                broadcast_world_boss_event('damage', map_id, {
                    'player': player_name if player_name else '系统',
                    'damage': actual_damage,
                    'boss_hp': boss['currentHp'],
                    'boss_max_hp': boss['maxHp']
                }, skip_sid=attacker_sid)
            if boss['currentHp'] <= 0:
                self._record_boss_kill(map_id, boss['name'], player_name if player_name else '系统')
                # ========== 修复：暂存boss数据，立即清空active_boss，防止后续刷新干扰 ==========
                boss_data = self.active_boss
                self.active_boss = None
                self._grant_rewards(boss_data)
                broadcast_world_boss_event('killed', map_id, {
                    'map_name': boss_data['map_name'],
                    'boss_name': boss['name'],
                    'last_hitter': player_name if player_name else '系统'
                })
                send_public(f"🎉 恭喜 {player_name or '系统'} 击败了世界Boss【{boss['name']}】！所有参与者获得奖励！")
                self._schedule_refresh(immediate=False)
                return True, True
            return True, False

    def _grant_exp_to_player(self, state, base_exp_value):
        """
        根据 base_exp_value（基础经验总值，未平分）计算玩家和英雄的实际获得经验。
        返回玩家实际获得的经验值（用于消息显示）。
        """
        player = state['player']
        hero = state['hero']
        hero_alive = hero.get('summoned', False) and hero.get('hp', 0) > 0
    
        if hero_alive:
            player_base = base_exp_value // 2
            hero_base = base_exp_value - player_base
        else:
            player_base = base_exp_value
            hero_base = 0
    
        player_exp = int(player_base * player.get('expMultiplier', 1) * (1 + player.get('total_exp_bonus', 0)))
        hero_exp = 0
        if hero_alive:
            hero_exp = int(hero_base * hero.get('expMultiplier', 1) * (1 + hero.get('total_exp_bonus', 0)))
    
        player['exp'] += player_exp
        if hero_alive:
            hero['exp'] += hero_exp
    
        return player_exp

    def _grant_rewards(self, boss_data):
        """
        发放奖励，boss_data 为暂存的Boss数据（已经清空 self.active_boss）
        改进版：参与奖占比10%，剩余由高伤害玩家瓜分
        """
        try:
            if not boss_data:
                logger.error("_grant_rewards: boss_data 为空")
                return
            boss = boss_data['boss']
            records = boss_data['damage_records']
            participants = boss_data['participants']

            if not participants and records:
                participants = set(records.keys())
                boss_data['participants'] = participants

            if not participants:
                logger.error("_grant_rewards: participants 为空，无法发放奖励")
                send_public(f"🎉 世界Boss【{boss['name']}】已被击败！")
                return

            total_damage = sum(records.values())
            if total_damage == 0:
                logger.warning("世界Boss总伤害为0，无法计算奖励")
                return

            # 获取总奖励池
            total_exp_pool = boss.get('exp', 0)
            total_gold_pool = boss.get('gold', 0)
            # 保底奖励
            if total_exp_pool == 0 and total_gold_pool == 0:
                logger.warning(f"Boss {boss['name']} 的 exp/gold 为0，使用保底奖励")
                total_exp_pool = 50000
                total_gold_pool = 50000

            # 参与奖比例 (10%)
            participation_ratio = 0.1
            participation_exp = int(total_exp_pool * participation_ratio)
            participation_gold = int(total_gold_pool * participation_ratio)
            # 高伤害奖池
            high_exp_pool = total_exp_pool - participation_exp
            high_gold_pool = total_gold_pool - participation_gold

            # 参与奖平均分配
            total_participants = len(participants)
            avg_participation_exp = participation_exp // total_participants if total_participants else 0
            avg_participation_gold = participation_gold // total_participants if total_participants else 0

            # 分类玩家：低伤害（<10%）和高伤害
            low_damage_players = []
            high_damage_players = []
            for player_name, damage in records.items():
                damage_percent = damage / total_damage if total_damage > 0 else 0
                if damage_percent < 0.10:
                    low_damage_players.append(player_name)
                else:
                    high_damage_players.append(player_name)

            # 1. 发放参与奖（所有参与者都有）
            for player_name in participants:
                try:
                    state = self._get_player_state(player_name)
                    if not state:
                        logger.error(f"无法获取玩家 {player_name} 状态，跳过参与奖")
                        continue

                    # 发放平均参与奖
                    if avg_participation_gold:
                        state['player']['gold'] = state['player'].get('gold', 0) + avg_participation_gold
                    player_exp_gained = self._grant_exp_to_player(state, avg_participation_exp)

                    # 触发升级检查
                    self.game_engine._check_level_up(state, 'player')
                    if state['hero'].get('summoned', False):
                        self.game_engine._check_level_up(state, 'hero')

                    mark_dirty(player_name)
                    player_state_manager.set(player_name, state)

                    diff = {'player': {'gold': state['player']['gold'], 'exp': state['player']['exp']}}
                    hero = state['hero']
                    if hero.get('summoned', False) and hero.get('hp', 0) > 0:
                        diff['hero'] = {'exp': hero['exp']}
                    self.socketio.emit('combat_update', {'diff': diff, 'skip_auto_combat': True}, room=player_name)

                    self.socketio.emit('world_boss_reward', {
                        'rank': None,
                        'damage': records.get(player_name, 0),
                        'gold': avg_participation_gold,
                        'exp': player_exp_gained,
                        'message': f"击败世界boss获得 {avg_participation_gold} 金币, {player_exp_gained} 经验（参与奖）"
                    }, room=player_name)
                    send_private(player_name, f"击败世界boss获得 {avg_participation_gold} 金币, {player_exp_gained} 经验（参与奖）")
                    log_player_event(player_name, 'world_boss_reward', f'世界Boss {boss["name"]} 参与奖', {
                        'boss_name': boss['name'],
                        'damage': records.get(player_name, 0),
                        'gold_gained': avg_participation_gold,
                        'exp_gained': player_exp_gained,
                        'rank_type': 'participation'
                    })
                except Exception as e:
                    logger.exception(f"发放参与奖给 {player_name} 时发生异常: {e}")

            # 2. 高伤害奖励（瓜分剩余池）
            num_high = len(high_damage_players)
            if num_high > 0:
                gold_per_high = high_gold_pool // num_high if high_gold_pool > 0 else 0
                exp_per_high = high_exp_pool // num_high if high_exp_pool > 0 else 0
                gold_remainder = high_gold_pool % num_high
                exp_remainder = high_exp_pool % num_high

                for idx, player_name in enumerate(high_damage_players):
                    try:
                        extra_gold = 1 if idx < gold_remainder else 0
                        extra_exp = 1 if idx < exp_remainder else 0
                        gold_gain = gold_per_high + extra_gold
                        exp_gain = exp_per_high + extra_exp

                        if gold_gain == 0 and exp_gain == 0:
                            continue

                        state = self._get_player_state(player_name)
                        if not state:
                            logger.error(f"无法获取玩家 {player_name} 状态，跳过高伤害奖励")
                            continue

                        if gold_gain:
                            state['player']['gold'] = state['player'].get('gold', 0) + gold_gain
                        player_exp_gained = self._grant_exp_to_player(state, exp_gain)

                        self.game_engine._check_level_up(state, 'player')
                        if state['hero'].get('summoned', False):
                            self.game_engine._check_level_up(state, 'hero')

                        mark_dirty(player_name)
                        player_state_manager.set(player_name, state)

                        diff = {'player': {'gold': state['player']['gold'], 'exp': state['player']['exp']}}
                        hero = state['hero']
                        if hero.get('summoned', False) and hero.get('hp', 0) > 0:
                            diff['hero'] = {'exp': hero['exp']}
                        self.socketio.emit('combat_update', {'diff': diff, 'skip_auto_combat': True}, room=player_name)

                        self.socketio.emit('world_boss_reward', {
                            'rank': None,
                            'damage': records.get(player_name, 0),
                            'gold': gold_gain,
                            'exp': player_exp_gained,
                            'message': f"击败世界boss获得 {gold_gain} 金币, {player_exp_gained} 经验（高伤害奖励）"
                        }, room=player_name)
                        send_private(player_name, f"击败世界boss获得 {gold_gain} 金币, {player_exp_gained} 经验（高伤害奖励）")
                        log_player_event(player_name, 'world_boss_reward', f'世界Boss {boss["name"]} 高伤害奖励', {
                            'boss_name': boss['name'],
                            'damage': records.get(player_name, 0),
                            'gold_gained': gold_gain,
                            'exp_gained': player_exp_gained,
                            'rank_type': 'high'
                        })
                    except Exception as e:
                        logger.exception(f"发放高伤害奖励给 {player_name} 时发生异常: {e}")

            # 3. 掉落抽取（保持不变）
            online_players = self._get_online_players()
            all_participants = list(participants)
            for player_name in all_participants:
                if player_name in online_players:
                    self.pending_draws[player_name] = {'drawn': False, 'timer': None, 'boss': boss}
                    self.socketio.emit('boss_drop_ready', {
                        'boss_name': boss['name'],
                        'timeout': self.draw_timeout
                    }, room=player_name)
                    timer = eventlet.spawn_after(self.draw_timeout, self._auto_draw, player_name)
                    self.pending_draws[player_name]['timer'] = timer
                    logger.info(f"已向玩家 {player_name} 发送掉落抽取弹窗")
                else:
                    logger.info(f"玩家 {player_name} 离线，不参与掉落抽取")

            # 4. 伤害排行广播
            if records:
                valid_records = {name: dmg for name, dmg in records.items()
                                 if name and name != 'unknown' and name.strip()}
                if valid_records:
                    sorted_players = sorted(valid_records.items(), key=lambda x: x[1], reverse=True)[:10]
                    rank_msg = "，".join([f"第{i+1}名 {name}({damage}伤害)" for i, (name, damage) in enumerate(sorted_players)])
                    send_public(f"🏆 世界Boss伤害排行：{rank_msg}")

            logger.info(f"世界Boss结算完成，参与人数: {len(participants)}，已触发掉落抽取")
        except Exception as e:
            logger.exception("_grant_rewards 发生严重异常")

    def _get_player_state(self, player_name):
        state = player_state_manager.get(player_name)
        if state:
            return state
        from db_storage import load_state_from_tables
        state = load_state_from_tables(player_name)
        if state:
            player_state_manager.set(player_name, state)
        return state

    def get_boss_info(self, map_id):
        with self.lock:
            if self.active_boss and self.active_boss['map_id'] == map_id:
                boss = self.active_boss['boss']
                return {
                    'exists': True,
                    'map_id': map_id,
                    'map_name': self.active_boss['map_name'],
                    'boss_name': boss['name'],
                    'boss_hp': boss.get('currentHp', 0),
                    'boss_max_hp': boss.get('maxHp', 0),
                    'boss_hp_percent': (boss.get('currentHp', 0) / boss.get('maxHp', 1)) * 100,
                    'refresh_seconds': None
                }
            if hasattr(self, '_next_refresh_time') and self._next_refresh_time:
                remaining = max(0, int(self._next_refresh_time - time.time()))
                return {'exists': False, 'refresh_seconds': remaining}
        return {'exists': False, 'refresh_seconds': None}

    def get_boss_damage_rank(self, map_id):
        with self.lock:
            if self.active_boss and self.active_boss['map_id'] == map_id:
                records = self.active_boss['damage_records']
                sorted_players = sorted(records.items(), key=lambda x: x[1], reverse=True)[:10]
                return [{'name': name, 'damage': damage} for name, damage in sorted_players]
        return []

    def _start_broadcast_thread(self):
        def broadcast_worker():
            while True:
                time.sleep(5)
                try:
                    self._broadcast_boss_status()
                except Exception as e:
                    logger.error(f"广播Boss状态失败: {e}")
        thread = threading.Thread(target=broadcast_worker, daemon=True)
        thread.start()

    def _broadcast_boss_status(self):
        with self.lock:
            if self.active_boss and self.active_boss['boss'].get('currentHp', 0) > 0:
                boss = self.active_boss['boss']
                map_id = self.active_boss['map_id']
                self.socketio.emit('world_boss_status', {
                    'map_id': map_id,
                    'map_name': self.active_boss['map_name'],
                    'boss_name': boss['name'],
                    'boss_hp': boss['currentHp'],
                    'boss_max_hp': boss['maxHp'],
                    'boss_hp_percent': (boss['currentHp'] / boss['maxHp']) * 100,
                    'participants': len(self.active_boss['participants'])
                }, room=f'map_{map_id}')

    def _record_boss_kill(self, map_id, boss_name, killer_name):
        import sqlite3
        from chat import get_game_db, close_game_connection
        conn = get_game_db()
        try:
            c = conn.cursor()
            c.execute('''
                      INSERT INTO world_boss_kills (boss_name, killer_name, kill_time, map_id)
                      VALUES (?, ?, ?, ?)
                      ''', (boss_name, killer_name, int(time.time()), map_id))
            conn.commit()
        except Exception as e:
            logger.error(f"记录Boss击杀失败: {e}")
        finally:
            close_game_connection(conn)

    def _auto_draw(self, player_name):
        with self.lock:
            if player_name not in self.pending_draws:
                return
            if self.pending_draws[player_name]['drawn']:
                return
            self._do_draw(player_name, auto=True)

    def draw_boss_drop(self, player_name):
        with self.lock:
            if player_name not in self.pending_draws:
                return False, "没有可抽取的Boss掉落"
            if self.pending_draws[player_name]['drawn']:
                return False, "你已经抽取过了"
            timer = self.pending_draws[player_name]['timer']
            if timer and not timer.dead:
                timer.kill()
            return self._do_draw(player_name, auto=False)

    def _do_draw(self, player_name, auto):
        with self.lock:
            if player_name not in self.pending_draws:
                return False, "没有可抽取的Boss掉落"
            if self.pending_draws[player_name]['drawn']:
                return False, "你已经抽取过了"
            self.pending_draws[player_name]['drawn'] = True
            boss = self.pending_draws[player_name].get('boss')
            if not boss:
                return False, "掉落信息丢失"

        state = self._get_player_state(player_name)
        if not state:
            logger.error(f"无法获取玩家 {player_name} 状态")
            return False, "状态获取失败"

        drop_items = self.game_engine.generate_boss_drops_for_player(boss, state)

        if not drop_items:
            msg = "很遗憾，没有获得掉落物品"
            if auto:
                msg = "自动抽取：" + msg
            send_private(player_name, msg)
            self.socketio.emit('boss_draw_result', {
                'success': True,
                'items': [],
                'message': msg
            }, room=player_name)
            return True, msg

        obtained = []
        for item in drop_items:
            if self.game_engine._add_item_to_inventory(state, item):
                obtained.append(item['name'])
            else:
                logger.warning(f"玩家 {player_name} 背包已满，无法获得 {item['name']}")

        if obtained:
            msg = f"恭喜获得：{', '.join(obtained)}"
            if auto:
                msg = "自动抽取：" + msg
            send_private(player_name, msg)
            send_public(f"🎁 {player_name} 从世界Boss【{boss['name']}】中获得了 {', '.join(obtained)}！")
        else:
            msg = "获得物品失败（背包已满）"

        mark_dirty(player_name)
        log_player_event(player_name, 'world_boss_drop', f'抽取世界Boss {boss["name"]} 掉落', {
            'boss_name': boss['name'],
            'items': obtained,
            'auto': auto
        })
        player_state_manager.set(player_name, state)

        diff = {'inventory': state['inventory']}
        self.socketio.emit('combat_update', {'diff': diff, 'skip_auto_combat': True}, room=player_name)
        self.socketio.emit('boss_draw_result', {
            'success': True,
            'items': obtained,
            'message': msg
        }, room=player_name)
        return True, msg

    def remove_player_data(self, player_name: str):
        with self.lock:
            if self.active_boss:
                self.active_boss['participants'].discard(player_name)
                self.active_boss['damage_records'].pop(player_name, None)
            if player_name in self.pending_draws:
                timer = self.pending_draws[player_name].get('timer')
                if timer and not timer.dead:
                    timer.kill()
                del self.pending_draws[player_name]