import sqlite3
import time

from config import achievements_earned, ACHIEVEMENTS_BY_ID, EVENT_TEMPLATES_BY_ID

import os as _os
DB_PATH = _os.environ.get("GAME_DB_PATH") or _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "game.db")
conn = sqlite3.connect(DB_PATH, check_same_thread=False)
cursor = conn.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
    user_id     TEXT PRIMARY KEY,
    username    TEXT NOT NULL DEFAULT 'هویج_ناشناس',
    size        INTEGER NOT NULL DEFAULT 1,
    last_grow   INTEGER NOT NULL DEFAULT 0,
    wins        INTEGER NOT NULL DEFAULT 0,
    total_pvp   INTEGER NOT NULL DEFAULT 0,
    created_at  INTEGER DEFAULT (CAST(strftime('%s', 'now') AS INTEGER))
)
""")

for stmt in (
    "ALTER TABLE users ADD COLUMN wins INTEGER NOT NULL DEFAULT 0",
    "ALTER TABLE users ADD COLUMN total_pvp INTEGER NOT NULL DEFAULT 0",
    "ALTER TABLE users ADD COLUMN grows_count INTEGER NOT NULL DEFAULT 0",
    "ALTER TABLE users ADD COLUMN golden_count INTEGER NOT NULL DEFAULT 0",
    "ALTER TABLE users ADD COLUMN tg_handle TEXT",
):
    try:
        cursor.execute(stmt)
    except sqlite3.OperationalError:
        pass

cursor.execute("""
CREATE TABLE IF NOT EXISTS challenges (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    chat_id TEXT,
    timestamp INTEGER,
    challenger_id TEXT,
    amount INTEGER,
    created_at INTEGER DEFAULT (CAST(strftime('%s', 'now') AS INTEGER))
)
""")

try:
    cursor.execute("ALTER TABLE challenges ADD COLUMN timestamp INTEGER")
except sqlite3.OperationalError:
    pass

try:
    cursor.execute("ALTER TABLE challenges ADD COLUMN message_id INTEGER")
except sqlite3.OperationalError:
    pass

try:
    cursor.execute("ALTER TABLE challenges ADD COLUMN code TEXT")
except sqlite3.OperationalError:
    pass

cursor.execute("""
CREATE TABLE IF NOT EXISTS promos (
    code        TEXT PRIMARY KEY,
    amount      INTEGER NOT NULL,
    created_at  INTEGER NOT NULL,
    expires_at  INTEGER NOT NULL
)
""")

cursor.execute("""
CREATE TABLE IF NOT EXISTS promo_redemptions (
    code    TEXT NOT NULL,
    user_id TEXT NOT NULL,
    used_at INTEGER NOT NULL,
    PRIMARY KEY (code, user_id)
)
""")

cursor.execute("""
CREATE TABLE IF NOT EXISTS banned_users (
    user_id     TEXT PRIMARY KEY,
    banned_at   INTEGER NOT NULL,
    reason      TEXT
)
""")

conn.commit()


cursor.execute("""
CREATE TABLE IF NOT EXISTS user_achievements (
    user_id         TEXT NOT NULL,
    achievement_id  TEXT NOT NULL,
    unlocked_at     INTEGER NOT NULL,
    PRIMARY KEY (user_id, achievement_id)
)
""")

cursor.execute("""
CREATE TABLE IF NOT EXISTS user_chats (
    user_id  TEXT NOT NULL,
    chat_id  TEXT NOT NULL,
    PRIMARY KEY (user_id, chat_id)
)
""")

cursor.execute("""
CREATE TABLE IF NOT EXISTS ban_history (
    id       INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id  TEXT NOT NULL,
    action   TEXT NOT NULL,
    reason   TEXT,
    at       INTEGER NOT NULL
)
""")

conn.commit()


def record_user_chat(user_id: str, chat_id: str):
    try:
        cursor.execute("INSERT OR IGNORE INTO user_chats (user_id, chat_id) VALUES (?, ?)", (user_id, chat_id))
        conn.commit()
    except Exception as e:
        conn.rollback()
        print(f"خطا در record_user_chat: {e}")


def leaderboard_for_chat(chat_id: str, limit: int = 10) -> list:
    cursor.execute("""
        SELECT u.username, u.size FROM users u
        JOIN user_chats uc ON u.user_id = uc.user_id
        WHERE uc.chat_id = ? AND u.username NOT LIKE 'هویج_%'
        ORDER BY u.size DESC LIMIT ?
    """, (chat_id, limit))
    return cursor.fetchall()


def get_user_rank(user_id: str):
    cursor.execute("SELECT user_id FROM users WHERE username NOT LIKE 'هویج_%' ORDER BY size DESC")
    ids = [row[0] for row in cursor.fetchall()]
    return ids.index(user_id) + 1 if user_id in ids else None


def get_user_group_rank(user_id: str, chat_id: str):
    cursor.execute("""
        SELECT u.user_id FROM users u
        JOIN user_chats uc ON u.user_id = uc.user_id
        WHERE uc.chat_id = ? AND u.username NOT LIKE 'هویج_%'
        ORDER BY u.size DESC
    """, (chat_id,))
    ids = [row[0] for row in cursor.fetchall()]
    return ids.index(user_id) + 1 if user_id in ids else None


def get_user_group_size(user_id: str, chat_id: str):
    cursor.execute("""
        SELECT COUNT(*) FROM users u
        JOIN user_chats uc ON u.user_id = uc.user_id
        WHERE uc.chat_id = ? AND u.username NOT LIKE 'هویج_%'
    """, (chat_id,))
    row = cursor.fetchone()
    return row[0] if row else 0


def get_user_streak(user_id: str) -> int:
    user = get_user(user_id)
    if not user or user["last_grow"] == 0:
        return 0
    now = int(time.time())
    day = 86400
    streak = 0
    check_time = now
    while True:
        day_start = check_time - (check_time % day)
        day_end = day_start + day
        cursor.execute(
            "SELECT 1 FROM grow_log WHERE user_id = ? AND timestamp >= ? AND timestamp < ? LIMIT 1",
            (user_id, day_start, day_end)
        )
        if cursor.fetchone():
            streak += 1
            check_time -= day
        else:
            break
    return streak


cursor.execute("""
CREATE TABLE IF NOT EXISTS grow_log (
    user_id     TEXT NOT NULL,
    timestamp   INTEGER NOT NULL,
    amount      INTEGER NOT NULL
)
""")
conn.commit()


cursor.execute("""
CREATE TABLE IF NOT EXISTS admin_log (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    admin_id    TEXT NOT NULL,
    action      TEXT NOT NULL,
    target_id   TEXT,
    details     TEXT,
    at          INTEGER NOT NULL
)
""")
conn.commit()


def log_admin_action(admin_id: str, action: str, target_id: str = None, details: str = None):
    try:
        cursor.execute(
            "INSERT INTO admin_log (admin_id, action, target_id, details, at) VALUES (?, ?, ?, ?, ?)",
            (admin_id, action, target_id, details, int(time.time()))
        )
        conn.commit()
    except Exception as e:
        print(f"خطا در log_admin_action: {e}")


def get_admin_log(limit: int = 20) -> list:
    cursor.execute("SELECT admin_id, action, target_id, details, at FROM admin_log ORDER BY id DESC LIMIT ?", (limit,))
    return cursor.fetchall()


def ban_user(user_id: str, reason: str = "") -> bool:
    try:
        now = int(time.time())
        cursor.execute(
            "INSERT OR REPLACE INTO banned_users (user_id, banned_at, reason) VALUES (?, ?, ?)",
            (user_id, now, reason)
        )
        cursor.execute(
            "INSERT INTO ban_history (user_id, action, reason, at) VALUES (?, 'ban', ?, ?)",
            (user_id, reason, now)
        )
        conn.commit()
        return True
    except Exception as e:
        conn.rollback()
        print(f"خطا در ban_user: {e}")
        return False


def unban_user(user_id: str) -> bool:
    cursor.execute("DELETE FROM banned_users WHERE user_id = ?", (user_id,))
    was_banned = cursor.rowcount > 0
    if was_banned:
        cursor.execute(
            "INSERT INTO ban_history (user_id, action, reason, at) VALUES (?, 'unban', NULL, ?)",
            (user_id, int(time.time()))
        )
    conn.commit()
    return was_banned


def get_ban_history(user_id: str) -> list:
    cursor.execute(
        "SELECT action, reason, at FROM ban_history WHERE user_id = ? ORDER BY at DESC",
        (user_id,)
    )
    return [{"action": r[0], "reason": r[1], "at": r[2]} for r in cursor.fetchall()]


def get_current_ban(user_id: str):
    cursor.execute("SELECT banned_at, reason FROM banned_users WHERE user_id = ?", (user_id,))
    row = cursor.fetchone()
    return {"banned_at": row[0], "reason": row[1]} if row else None


def is_banned(user_id: str) -> bool:
    cursor.execute("SELECT 1 FROM banned_users WHERE user_id = ?", (user_id,))
    return cursor.fetchone() is not None


def bot_stats() -> dict:
    cursor.execute("SELECT COUNT(*), COALESCE(SUM(size), 0), COALESCE(AVG(size), 0) FROM users")
    count, total_size, avg_size = cursor.fetchone()
    cursor.execute("SELECT COUNT(*) FROM banned_users")
    banned_count = cursor.fetchone()[0]
    return {
        "user_count": count,
        "total_size": total_size,
        "avg_size": round(avg_size, 1),
        "banned_count": banned_count,
    }


def set_size(user_id: str, new_size: int) -> bool:
    cursor.execute("UPDATE users SET size = ? WHERE user_id = ?", (new_size, user_id))
    if cursor.rowcount == 0:
        return False
    conn.commit()
    return True


def get_user(user_id: str, default_username: str = None) -> dict:
    cursor.execute(
        "SELECT size, last_grow, username, wins, total_pvp, grows_count, golden_count "
        "FROM users WHERE user_id = ?",
        (user_id,)
    )
    row = cursor.fetchone()
    if row:
        stored_username = row[2]
        if default_username and default_username != stored_username:
            try:
                cursor.execute("UPDATE users SET username = ? WHERE user_id = ?", (default_username, user_id))
                conn.commit()
                stored_username = default_username
            except Exception as e:
                conn.rollback()
                print(f"خطا در sync کردن یوزرنیم: {e}")
        return {
            "size": row[0],
            "last_grow": row[1],
            "username": stored_username,
            "wins": row[3],
            "total_pvp": row[4],
            "grows_count": row[5],
            "golden_count": row[6],
        }

    username_to_use = default_username or f"هویج_{str(user_id)[-6:]}"
    try:
        cursor.execute(
            "INSERT INTO users (user_id, username, created_at) "
            "VALUES (?, ?, CAST(strftime('%s', 'now') AS INTEGER))",
            (user_id, username_to_use)
        )
        conn.commit()
        return {"size": 1, "last_grow": 0, "username": username_to_use, "wins": 0, "total_pvp": 0,
                "grows_count": 0, "golden_count": 0}
    except sqlite3.IntegrityError:
        conn.rollback()
        return get_user(user_id)


def resolve_user_id(identifier: str):
    identifier = identifier.strip()
    if identifier.isdigit():
        return identifier
    cursor.execute("SELECT user_id FROM users WHERE user_id = ?", (identifier,))
    row = cursor.fetchone()
    return row[0] if row else None


def record_grow_event(user_id: str, is_golden: bool):
    try:
        cursor.execute("UPDATE users SET grows_count = grows_count + 1 WHERE user_id = ?", (user_id,))
        if is_golden:
            cursor.execute("UPDATE users SET golden_count = golden_count + 1 WHERE user_id = ?", (user_id,))
        conn.commit()
    except Exception as e:
        conn.rollback()
        print(f"خطا در record_grow_event: {e}")


def unlock_achievement(user_id: str, achievement_id: str) -> bool:
    try:
        cursor.execute(
            "INSERT INTO user_achievements (user_id, achievement_id, unlocked_at) VALUES (?, ?, ?)",
            (user_id, achievement_id, int(time.time()))
        )
        conn.commit()
        return True
    except sqlite3.IntegrityError:
        conn.rollback()
        return False


def get_user_achievement_ids(user_id: str) -> set:
    cursor.execute("SELECT achievement_id FROM user_achievements WHERE user_id = ?", (user_id,))
    return {row[0] for row in cursor.fetchall()}


def get_user_achievements_map(user_id: str) -> dict:
    cursor.execute("SELECT achievement_id, unlocked_at FROM user_achievements WHERE user_id = ?", (user_id,))
    return {row[0]: row[1] for row in cursor.fetchall()}


def check_and_unlock_achievements(user_id: str) -> list:
    user = get_user(user_id)
    already = get_user_achievement_ids(user_id)
    earned_ids = set(achievements_earned(user))

    rank = get_user_rank(user_id)
    if rank is not None and rank <= 10:
        earned_ids.add("top10_global")
    if rank == 1:
        earned_ids.add("top1_global")

    newly_unlocked = []
    for aid in earned_ids:
        if aid not in already and unlock_achievement(user_id, aid):
            newly_unlocked.append(ACHIEVEMENTS_BY_ID[aid])
    return newly_unlocked


def update_grow(user_id: str, grow_amount: int) -> bool:
    ts = int(time.time())
    try:
        cursor.execute(
            "UPDATE users SET size = size + ?, last_grow = ? WHERE user_id = ?",
            (grow_amount, ts, user_id)
        )
        if cursor.rowcount == 0:
            return False
        cursor.execute(
            "INSERT INTO grow_log (user_id, timestamp, amount) VALUES (?, ?, ?)",
            (user_id, ts, grow_amount)
        )
        conn.commit()
        return True
    except Exception as e:
        conn.rollback()
        print(f"خطا در update_grow: {e}")
        return False


def transfer_size(from_id: str, to_id: str, amount: int) -> bool:
    if amount <= 0:
        return False
    try:
        cursor.execute("BEGIN TRANSACTION")
        cursor.execute("UPDATE users SET size = size - ? WHERE user_id = ? AND size >= ?", (amount, from_id, amount))
        if cursor.rowcount == 0:
            conn.rollback()
            return False
        cursor.execute("UPDATE users SET size = size + ? WHERE user_id = ?", (amount, to_id))
        conn.commit()
        return True
    except Exception as e:
        conn.rollback()
        print(f"خطا در انتقال اندازه: {e}")
        return False


def leaderboard(limit: int = 10) -> list:
    cursor.execute("SELECT username, size FROM users WHERE username NOT LIKE 'هویج_%' ORDER BY size DESC LIMIT ?", (limit,))
    return cursor.fetchall()


def create_challenge(chat_id: str, message_id: int, timestamp: int, challenger_id: str, amount: int) -> bool:
    try:
        cursor.execute(
            "INSERT INTO challenges (chat_id, message_id, timestamp, challenger_id, amount) VALUES (?, ?, ?, ?, ?)",
            (chat_id, message_id, timestamp, challenger_id, amount)
        )
        conn.commit()
        return True
    except Exception as e:
        print(f"خطا در create_challenge: {e}")
        return False


def get_challenge_by_message(chat_id: str, message_id: int):
    cursor.execute(
        "SELECT challenger_id, amount FROM challenges WHERE chat_id = ? AND message_id = ?",
        (chat_id, message_id)
    )
    row = cursor.fetchone()
    if row:
        return {"challenger_id": row[0], "amount": row[1]}
    return None


def delete_challenge(chat_id: str, message_id: int):
    cursor.execute(
        "DELETE FROM challenges WHERE chat_id = ? AND message_id = ?",
        (chat_id, message_id)
    )
    conn.commit()


def update_pvp_stats(user_id: str, is_winner: bool):
    try:
        cursor.execute("UPDATE users SET total_pvp = total_pvp + 1 WHERE user_id = ?", (user_id,))
        if is_winner:
            cursor.execute("UPDATE users SET wins = wins + 1 WHERE user_id = ?", (user_id,))
        conn.commit()
    except Exception as e:
        conn.rollback()
        print(f"خطا در بروزرسانی آمار PVP: {e}")


def close_db():
    conn.commit()
    conn.close()


def add_size_to_all(amount: int) -> bool:
    if amount == 0:
        return False
    try:
        cursor.execute("UPDATE users SET size = size + ?", (amount,))
        conn.commit()
        return True
    except Exception as e:
        conn.rollback()
        print(f"خطا در add_size_to_all: {e}")
        return False


def get_all_user_ids() -> list:
    cursor.execute("SELECT user_id FROM users")
    return [row[0] for row in cursor.fetchall()]


def get_all_private_chat_ids() -> list:
    cursor.execute("SELECT DISTINCT chat_id FROM user_chats WHERE chat_id LIKE 'b%'")
    return [row[0] for row in cursor.fetchall()]


def get_banned_user_ids() -> list:
    cursor.execute("SELECT user_id FROM banned_users")
    return [row[0] for row in cursor.fetchall()]


def get_active_user_ids() -> list:
    cursor.execute("SELECT user_id FROM users WHERE username NOT LIKE 'هویج_%'")
    return [row[0] for row in cursor.fetchall()]


def search_users(query: str, limit: int = 15) -> list:
    cursor.execute(
        "SELECT user_id, username, size, wins, total_pvp FROM users "
        "WHERE user_id = ? OR username LIKE ? LIMIT ?",
        (query, f"%{query}%", limit)
    )
    rows = cursor.fetchall()
    return [
        {"user_id": r[0], "username": r[1], "size": r[2], "wins": r[3], "total_pvp": r[4]}
        for r in rows
    ]


def create_promo(code: str, amount: int, days: int) -> bool:
    now = int(time.time())
    try:
        cursor.execute(
            "INSERT INTO promos (code, amount, created_at, expires_at) VALUES (?, ?, ?, ?)",
            (code, amount, now, now + days * 86400)
        )
        conn.commit()
        return True
    except sqlite3.IntegrityError:
        conn.rollback()
        return False
    except Exception as e:
        conn.rollback()
        print(f"خطا در create_promo: {e}")
        return False


def get_promo(code: str):
    cursor.execute("SELECT code, amount, expires_at FROM promos WHERE code = ?", (code,))
    row = cursor.fetchone()
    if row:
        return {"code": row[0], "amount": row[1], "expires_at": row[2]}
    return None


def has_redeemed(code: str, user_id: str) -> bool:
    cursor.execute(
        "SELECT 1 FROM promo_redemptions WHERE code = ? AND user_id = ?",
        (code, user_id)
    )
    return cursor.fetchone() is not None


def redeem_promo(code: str, user_id: str) -> bool:
    try:
        cursor.execute(
            "INSERT INTO promo_redemptions (code, user_id, used_at) VALUES (?, ?, ?)",
            (code, user_id, int(time.time()))
        )
        conn.commit()
        return True
    except sqlite3.IntegrityError:
        conn.rollback()
        return False
    except Exception as e:
        conn.rollback()
        print(f"خطا در redeem_promo: {e}")
        return False


cursor.execute("""
CREATE TABLE IF NOT EXISTS broadcast_queue (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    target      TEXT NOT NULL,
    text        TEXT NOT NULL,
    status      TEXT NOT NULL DEFAULT 'pending',
    sent_count  INTEGER NOT NULL DEFAULT 0,
    failed_count INTEGER NOT NULL DEFAULT 0,
    created_by  TEXT,
    created_at  INTEGER NOT NULL,
    finished_at INTEGER
)
""")
conn.commit()


def queue_broadcast(target: str, text: str, created_by: str = None) -> int:
    """target: 'all' | 'active' | 'banned'. The live bot process (main.py) polls
    this table and performs the actual send, since only that process holds the
    authenticated bot session."""
    cursor.execute(
        "INSERT INTO broadcast_queue (target, text, created_by, created_at) VALUES (?, ?, ?, ?)",
        (target, text, created_by, int(time.time()))
    )
    conn.commit()
    return cursor.lastrowid


def get_pending_broadcasts() -> list:
    cursor.execute(
        "SELECT id, target, text FROM broadcast_queue WHERE status = 'pending' ORDER BY id ASC"
    )
    return [{"id": r[0], "target": r[1], "text": r[2]} for r in cursor.fetchall()]


def mark_broadcast_sending(broadcast_id: int):
    cursor.execute("UPDATE broadcast_queue SET status = 'sending' WHERE id = ?", (broadcast_id,))
    conn.commit()


def finish_broadcast(broadcast_id: int, sent: int, failed: int):
    cursor.execute(
        "UPDATE broadcast_queue SET status = 'done', sent_count = ?, failed_count = ?, finished_at = ? WHERE id = ?",
        (sent, failed, int(time.time()), broadcast_id)
    )
    conn.commit()


def list_broadcasts(limit: int = 20) -> list:
    cursor.execute(
        "SELECT id, target, text, status, sent_count, failed_count, created_by, created_at, finished_at "
        "FROM broadcast_queue ORDER BY id DESC LIMIT ?", (limit,)
    )
    return [
        {"id": r[0], "target": r[1], "text": r[2], "status": r[3], "sent_count": r[4],
         "failed_count": r[5], "created_by": r[6], "created_at": r[7], "finished_at": r[8]}
        for r in cursor.fetchall()
    ]


def list_promos(limit: int = 50) -> list:
    now = int(time.time())
    cursor.execute(
        "SELECT p.code, p.amount, p.created_at, p.expires_at, "
        "(SELECT COUNT(*) FROM promo_redemptions r WHERE r.code = p.code) "
        "FROM promos p ORDER BY p.created_at DESC LIMIT ?", (limit,)
    )
    return [
        {"code": r[0], "amount": r[1], "created_at": r[2], "expires_at": r[3],
         "redemptions": r[4], "expired": r[3] < now}
        for r in cursor.fetchall()
    ]


cursor.execute("""
CREATE TABLE IF NOT EXISTS events (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    template_id  TEXT NOT NULL,
    name         TEXT NOT NULL,
    start_at     INTEGER NOT NULL,
    end_at       INTEGER NOT NULL,
    created_by   TEXT,
    created_at   INTEGER NOT NULL
)
""")
conn.commit()


def _event_row_to_dict(row) -> dict:
    template = EVENT_TEMPLATES_BY_ID.get(row[1], {})
    return {
        "id": row[0],
        "template_id": row[1],
        "name": row[2],
        "start_at": row[3],
        "end_at": row[4],
        "created_by": row[5],
        "created_at": row[6],
        "params": template.get("params", {}),
    }


def create_event(template_id: str, name: str, start_at: int, end_at: int, created_by: str):
    if template_id not in EVENT_TEMPLATES_BY_ID:
        return None
    if end_at <= start_at:
        return None
    try:
        cursor.execute(
            "INSERT INTO events (template_id, name, start_at, end_at, created_by, created_at) "
            "VALUES (?, ?, ?, ?, ?, ?)",
            (template_id, name, start_at, end_at, created_by, int(time.time()))
        )
        conn.commit()
        return cursor.lastrowid
    except Exception as e:
        conn.rollback()
        print(f"خطا در create_event: {e}")
        return None


def list_events() -> list:
    cursor.execute("SELECT id, template_id, name, start_at, end_at, created_by, created_at FROM events ORDER BY start_at ASC")
    return [_event_row_to_dict(row) for row in cursor.fetchall()]


def get_active_events(now: int = None) -> list:
    now = now if now is not None else int(time.time())
    cursor.execute(
        "SELECT id, template_id, name, start_at, end_at, created_by, created_at "
        "FROM events WHERE start_at <= ? AND end_at >= ?",
        (now, now)
    )
    return [_event_row_to_dict(row) for row in cursor.fetchall()]


def get_event(event_id: int):
    cursor.execute(
        "SELECT id, template_id, name, start_at, end_at, created_by, created_at FROM events WHERE id = ?",
        (event_id,)
    )
    row = cursor.fetchone()
    return _event_row_to_dict(row) if row else None


def delete_event(event_id: int) -> bool:
    cursor.execute("DELETE FROM events WHERE id = ?", (event_id,))
    conn.commit()
    return cursor.rowcount > 0


def get_active_event_multipliers(now: int = None) -> dict:
    result = {
        "golden_chance_multiplier": 1.0,
        "golden_bonus_multiplier": 1.0,
        "grow_multiplier": 1.0,
        "cooldown_multiplier": 1.0,
        "pvp_bonus_percent": 0,
    }
    for event in get_active_events(now):
        params = event["params"]
        for key in ("golden_chance_multiplier", "golden_bonus_multiplier", "grow_multiplier", "cooldown_multiplier"):
            if key in params:
                result[key] *= params[key]
        if "pvp_bonus_percent" in params:
            result["pvp_bonus_percent"] += params["pvp_bonus_percent"]
    return result
