from __future__ import annotations

import click

from .extensions import db
from .models import BadgeDefinition, User
from .services.monthly import archive_months_missing_up_to_previous
from .services.notifications import run_scheduled_notifications, send_due_notifications, send_monthly_winner_notifications


DEFAULT_BADGES = [
    {
        "key": "first_wipe",
        "name": "Erster Wisch",
        "description": "Erledige deine erste Aufgabe.",
        "icon_name": "sparkles",
        "trigger_type": "first_task_completed",
        "threshold": 1,
        "bonus_points": 5,
    },
    {
        "key": "warmed_up",
        "name": "Warmgelaufen",
        "description": "Erledige 10 Aufgaben insgesamt.",
        "icon_name": "fire",
        "trigger_type": "total_tasks_completed",
        "threshold": 10,
        "bonus_points": 10,
    },
    {
        "key": "punctuality_pro",
        "name": "Pünktlichkeitsprofi",
        "description": "Erledige 10 Aufgaben pünktlich.",
        "icon_name": "check-double",
        "trigger_type": "on_time_tasks_completed",
        "threshold": 10,
        "bonus_points": 15,
    },
    {
        "key": "early_bird",
        "name": "Der frühe Vogel",
        "description": "Erledige eine Aufgabe mindestens 1 Tag vor der Deadline.",
        "icon_name": "calendar-day",
        "trigger_type": "early_tasks_completed",
        "threshold": 1,
        "bonus_points": 8,
    },
    {
        "key": "early_starter",
        "name": "Frühstarter",
        "description": "Erledige 5 Aufgaben mindestens 1 Tag vor der Deadline.",
        "icon_name": "rocket-launch",
        "trigger_type": "early_tasks_completed",
        "threshold": 5,
        "bonus_points": 15,
    },
    {
        "key": "weekly_flow",
        "name": "Wochenflow",
        "description": "Erledige 7 Tage in Folge mindestens eine Aufgabe.",
        "icon_name": "flag-checkered",
        "trigger_type": "streak_days",
        "threshold": 7,
        "bonus_points": 20,
    },
    {
        "key": "monthly_champion",
        "name": "Monatssieger",
        "description": "Gewinne einen Monat mit den meisten Punkten.",
        "icon_name": "trophy",
        "trigger_type": "monthly_win_count",
        "threshold": 1,
        "bonus_points": 25,
    },
    {
        "key": "title_defender",
        "name": "Titelverteidiger",
        "description": "Gewinne 2 Monate in Folge.",
        "icon_name": "crown",
        "trigger_type": "consecutive_month_wins",
        "threshold": 2,
        "bonus_points": 30,
    },
    {
        "key": "boss_battle",
        "name": "Bosskampf",
        "description": "Erledige eine Aufgabe mit besonders hohem Punktwert.",
        "icon_name": "bolt",
        "trigger_type": "high_point_task",
        "threshold": 25,
        "bonus_points": 12,
    },
    {
        "key": "foreign_savior",
        "name": "Fremdretter",
        "description": "Erledige 5 Aufgaben, die ursprünglich jemand anderem zugewiesen waren.",
        "icon_name": "users-crown",
        "trigger_type": "foreign_tasks_completed",
        "threshold": 5,
        "bonus_points": 18,
    },
    {
        "key": "white_glove",
        "name": "Weiße Weste",
        "description": "Bleibe einen ganzen Monat ohne überfällige Aufgabe.",
        "icon_name": "shield",
        "trigger_type": "clean_month",
        "threshold": 1,
        "bonus_points": 20,
    },
    {
        "key": "comeback_kid",
        "name": "Comeback Kid",
        "description": "Gewinne nach einem verlorenen Monat den nächsten Monat.",
        "icon_name": "award",
        "trigger_type": "comeback_win",
        "threshold": 1,
        "bonus_points": 18,
    },
]


def seed_badges() -> None:
    wanted_keys = {payload["key"] for payload in DEFAULT_BADGES}
    BadgeDefinition.query.filter(~BadgeDefinition.key.in_(wanted_keys)).delete(synchronize_session=False)
    for payload in DEFAULT_BADGES:
        badge = BadgeDefinition.query.filter_by(key=payload["key"]).first()
        if not badge:
            db.session.add(BadgeDefinition(**payload))
            continue
        badge.name = payload["name"]
        badge.description = payload["description"]
        badge.icon_name = payload["icon_name"]
        badge.trigger_type = payload["trigger_type"]
        badge.threshold = payload["threshold"]
        badge.bonus_points = payload["bonus_points"]
        badge.active = True
    db.session.commit()


def register_cli(app) -> None:
    @app.cli.command("init-db")
    def init_db_command():
        db.create_all()
        seed_badges()
        click.echo("Datenbank und Standard-Badges sind bereit.")

    @app.cli.command("create-user")
    @click.option("--name", prompt=True, help="Anzeigename")
    @click.option("--email", prompt=True, help="E-Mail")
    @click.option("--password", prompt=True, hide_input=True, confirmation_prompt=True, help="Passwort")
    def create_user_command(name: str, email: str, password: str):
        existing = User.query.filter_by(email=email.lower().strip()).first()
        if existing:
            click.echo("Es existiert bereits ein Nutzer mit dieser E-Mail.")
            raise SystemExit(1)

        user = User(name=name.strip(), email=email.lower().strip())
        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        click.echo(f"Nutzer {user.email} wurde angelegt.")

    @app.cli.command("archive-months")
    def archive_months_command():
        archive_months_missing_up_to_previous()
        click.echo("Monatsarchiv wurde geprüft.")

    @app.cli.command("notify-due")
    def notify_due_command():
        result = send_due_notifications()
        click.echo(f"Due-Push: sent={result.sent} skipped={result.skipped} failed={result.failed}")

    @app.cli.command("notify-monthly-winner")
    def notify_monthly_winner_command():
        result = send_monthly_winner_notifications()
        click.echo(f"Winner-Push: sent={result.sent} skipped={result.skipped} failed={result.failed}")

    @app.cli.command("notify-all")
    def notify_all_command():
        results = run_scheduled_notifications()
        daily = results["daily_due"]
        monthly = results["monthly_winner"]
        click.echo(
            "Scheduled-Pushes: "
            f"daily(sent={daily.sent}, skipped={daily.skipped}, failed={daily.failed}) "
            f"monthly(sent={monthly.sent}, skipped={monthly.skipped}, failed={monthly.failed})"
        )
