"""
Python 108 — Gamification Engine
XP system, 10 levels, 30 badges across 6 categories.
"""

# ── XP values for every action ───────────────────────────────────
XP_RULES = {
    "program_complete":    10,
    "exercise_solved":     15,
    "quiz_pass":           50,
    "quiz_perfect":        100,   # 10/10
    "daily_bonus":          5,    # first program of the day
    "streak_7":            35,
    "streak_30":          150,
    "module_complete":     25,    # all programs in a module done
    "all_programs":       500,    # all 108 done
}

# ── 10 Levels ────────────────────────────────────────────────────
LEVELS = [
    {"level": 1,  "name": "Beginner",          "icon": "🐣", "xp_required": 0},
    {"level": 2,  "name": "Hatchling",          "icon": "🐍", "xp_required": 100},
    {"level": 3,  "name": "Coder",              "icon": "📝", "xp_required": 300},
    {"level": 4,  "name": "Builder",            "icon": "⚙️", "xp_required": 600},
    {"level": 5,  "name": "Developer",          "icon": "🔧", "xp_required": 1000},
    {"level": 6,  "name": "Architect",          "icon": "🏗️", "xp_required": 1500},
    {"level": 7,  "name": "Pythonista",         "icon": "🔥", "xp_required": 2200},
    {"level": 8,  "name": "Expert",             "icon": "⚡", "xp_required": 3000},
    {"level": 9,  "name": "Master",             "icon": "🚀", "xp_required": 4000},
    {"level": 10, "name": "Python 108 Champion","icon": "🏆", "xp_required": 5000},
]

# ── 30 Badges across 6 categories ────────────────────────────────
BADGES = {
    # ── Getting started (3) ─────────────────────────────────────
    "first_step": {
        "key": "first_step", "category": "Getting started",
        "name": "First Step", "icon": "👣",
        "desc": "Complete Program #1 — Hello, World!",
    },
    "week1_done": {
        "key": "week1_done", "category": "Getting started",
        "name": "Week 1 Done", "icon": "🌱",
        "desc": "Complete the first 9 programs",
    },
    "hello_hero": {
        "key": "hello_hero", "category": "Getting started",
        "name": "Hello World Hero", "icon": "🌟",
        "desc": "Complete all Getting Started programs",
    },
    # ── Streak (6) ──────────────────────────────────────────────
    "streak_3": {
        "key": "streak_3", "category": "Streak",
        "name": "On Fire", "icon": "🔥",
        "desc": "Maintain a 3-day streak",
    },
    "streak_7": {
        "key": "streak_7", "category": "Streak",
        "name": "Week Warrior", "icon": "⭐",
        "desc": "Maintain a 7-day streak",
    },
    "streak_14": {
        "key": "streak_14", "category": "Streak",
        "name": "Fortnight Fighter", "icon": "💪",
        "desc": "Maintain a 14-day streak",
    },
    "streak_30": {
        "key": "streak_30", "category": "Streak",
        "name": "Monthly Master", "icon": "🏅",
        "desc": "Maintain a 30-day streak",
    },
    "streak_60": {
        "key": "streak_60", "category": "Streak",
        "name": "The Unstoppable", "icon": "🥇",
        "desc": "Maintain a 60-day streak",
    },
    "streak_108": {
        "key": "streak_108", "category": "Streak",
        "name": "108-Day Legend", "icon": "🐉",
        "desc": "Maintain a 108-day streak",
    },
    # ── Module completion (6) ────────────────────────────────────
    "module_functions": {
        "key": "module_functions", "category": "Module",
        "name": "Function Master", "icon": "🔧",
        "desc": "Complete all Functions programs",
    },
    "module_oop": {
        "key": "module_oop", "category": "Module",
        "name": "OOP Architect", "icon": "🏗️",
        "desc": "Complete all OOP Basics programs",
    },
    "module_data": {
        "key": "module_data", "category": "Module",
        "name": "Data Wrangler", "icon": "📦",
        "desc": "Complete all Data Structures programs",
    },
    "module_files": {
        "key": "module_files", "category": "Module",
        "name": "File Handler", "icon": "💾",
        "desc": "Complete all Files & Exceptions programs",
    },
    "module_advanced": {
        "key": "module_advanced", "category": "Module",
        "name": "Decorator Guru", "icon": "🎨",
        "desc": "Complete all Decorators & Advanced Functions programs",
    },
    "module_capstone": {
        "key": "module_capstone", "category": "Module",
        "name": "Project Builder", "icon": "🏆",
        "desc": "Complete all Capstone Projects",
    },
    # ── Quiz (5) ────────────────────────────────────────────────
    "first_quiz_pass": {
        "key": "first_quiz_pass", "category": "Quiz",
        "name": "First Pass", "icon": "✅",
        "desc": "Pass your first module quiz",
    },
    "quiz_perfect": {
        "key": "quiz_perfect", "category": "Quiz",
        "name": "Perfect Score", "icon": "💯",
        "desc": "Score 10/10 on any quiz",
    },
    "quiz_champion": {
        "key": "quiz_champion", "category": "Quiz",
        "name": "Quiz Champion", "icon": "🎓",
        "desc": "Pass all 12 module quizzes",
    },
    "quiz_first_attempt": {
        "key": "quiz_first_attempt", "category": "Quiz",
        "name": "Speed Quizzer", "icon": "⚡",
        "desc": "Pass a quiz on the very first attempt",
    },
    "quiz_5_passed": {
        "key": "quiz_5_passed", "category": "Quiz",
        "name": "Quiz Enthusiast", "icon": "📝",
        "desc": "Pass 5 module quizzes",
    },
    # ── Effort (5) ──────────────────────────────────────────────
    "note_taker": {
        "key": "note_taker", "category": "Effort",
        "name": "Note Taker", "icon": "📓",
        "desc": "Write notes on 10 programs",
    },
    "bookworm": {
        "key": "bookworm", "category": "Effort",
        "name": "Bookworm", "icon": "🔖",
        "desc": "Bookmark 20 programs",
    },
    "exercise_champion": {
        "key": "exercise_champion", "category": "Effort",
        "name": "Exercise Champion", "icon": "💡",
        "desc": "Solve all 108 exercises",
    },
    "half_exercises": {
        "key": "half_exercises", "category": "Effort",
        "name": "Half Way There (Exercises)", "icon": "📚",
        "desc": "Solve 54 exercises",
    },
    "daily_coder": {
        "key": "daily_coder", "category": "Effort",
        "name": "Daily Coder", "icon": "☀️",
        "desc": "Code every day for 7 days (streak + daily bonus)",
    },
    # ── Completion (5) ──────────────────────────────────────────
    "halfway": {
        "key": "halfway", "category": "Completion",
        "name": "Halfway There", "icon": "🌓",
        "desc": "Complete 54 programs",
    },
    "almost_there": {
        "key": "almost_there", "category": "Completion",
        "name": "Almost There", "icon": "🌔",
        "desc": "Complete 90 programs",
    },
    "graduate": {
        "key": "graduate", "category": "Completion",
        "name": "Python 108 Graduate", "icon": "🎓",
        "desc": "Complete all 108 programs",
    },
    "level_5": {
        "key": "level_5", "category": "Completion",
        "name": "Level 5 Achieved", "icon": "🔧",
        "desc": "Reach Developer level (Level 5)",
    },
    "level_10": {
        "key": "level_10", "category": "Completion",
        "name": "Champion!", "icon": "🏆",
        "desc": "Reach Python 108 Champion (Level 10)",
    },
}

# ── Level calculation ────────────────────────────────────────────
def get_level_info(total_xp: int) -> dict:
    """Return current level dict + XP progress to next level."""
    current = LEVELS[0]
    for lvl in LEVELS:
        if total_xp >= lvl["xp_required"]:
            current = lvl
        else:
            break
    idx = current["level"] - 1
    next_lvl = LEVELS[idx + 1] if idx + 1 < len(LEVELS) else None
    if next_lvl:
        xp_in_level  = total_xp - current["xp_required"]
        xp_needed    = next_lvl["xp_required"] - current["xp_required"]
        pct          = min(100, round(xp_in_level / xp_needed * 100))
    else:
        xp_in_level = xp_needed = 0
        pct = 100
    return {
        **current,
        "total_xp":    total_xp,
        "next_level":  next_lvl,
        "xp_in_level": xp_in_level,
        "xp_needed":   xp_needed,
        "pct":         pct,
    }

# ── Badge checking ───────────────────────────────────────────────
def check_badges(user_id, db, all_programs, modules_list) -> list:
    """
    Check all badge conditions for user_id.
    Returns list of badge keys newly earned (not previously held).
    """
    existing  = db.get_earned_badges(user_id)
    existing_keys = {b["badge_key"] for b in existing}
    newly_earned  = []

    prog_done = db.get_program_progress(user_id)
    done_count = sum(1 for v in prog_done.values() if v == 1)
    ex_done_count = len([v for v in db.get_exercise_progress(user_id).values() if v == 1])
    streak_data = db.get_streak_data(user_id)
    current_streak = streak_data["current_streak"]
    quiz_results = db.get_all_quiz_results(user_id)
    notes_count = len(db.get_all_notes(user_id))
    bookmarks_count = len(db.get_bookmarks(user_id))
    total_xp = db.get_total_xp(user_id)
    level_info = get_level_info(total_xp)

    def award(key):
        if key not in existing_keys:
            db.award_badge(user_id, key)
            newly_earned.append(key)

    # ── Getting started ──────────────────────────────────────────
    if prog_done.get(1, 0) == 1:
        award("first_step")
    if done_count >= 9:
        award("week1_done")
    gs_progs = [p["n"] for p in all_programs if p["mod"] == "Getting started"]
    if all(prog_done.get(n, 0) == 1 for n in gs_progs):
        award("hello_hero")

    # ── Streak ──────────────────────────────────────────────────
    for days, key in [(3,"streak_3"),(7,"streak_7"),(14,"streak_14"),
                      (30,"streak_30"),(60,"streak_60"),(108,"streak_108")]:
        if current_streak >= days or streak_data["longest_streak"] >= days:
            award(key)

    # ── Module completion ────────────────────────────────────────
    mod_badge_map = {
        "Functions":                     "module_functions",
        "OOP basics":                    "module_oop",
        "Data structures":               "module_data",
        "Files & exceptions":            "module_files",
        "Decorators & advanced functions": "module_advanced",
        "Capstone projects":             "module_capstone",
    }
    for mod_name, badge_key in mod_badge_map.items():
        mod_progs = [p["n"] for p in all_programs if p["mod"] == mod_name]
        if mod_progs and all(prog_done.get(n, 0) == 1 for n in mod_progs):
            award(badge_key)

    # ── Quiz ────────────────────────────────────────────────────
    passed_count = sum(1 for r in quiz_results.values() if r["passed"])
    if passed_count >= 1:
        award("first_quiz_pass")
    if passed_count >= 5:
        award("quiz_5_passed")
    if passed_count >= 12:
        award("quiz_champion")
    if any(r["score"] == r["total"] for r in quiz_results.values()):
        award("quiz_perfect")

    # ── Effort ──────────────────────────────────────────────────
    if notes_count >= 10:
        award("note_taker")
    if bookmarks_count >= 20:
        award("bookworm")
    if ex_done_count >= 54:
        award("half_exercises")
    if ex_done_count >= 108:
        award("exercise_champion")
    if current_streak >= 7:
        award("daily_coder")

    # ── Completion ──────────────────────────────────────────────
    if done_count >= 54:
        award("halfway")
    if done_count >= 90:
        award("almost_there")
    if done_count >= 108:
        award("graduate")
    if level_info["level"] >= 5:
        award("level_5")
    if level_info["level"] >= 10:
        award("level_10")

    return newly_earned
