"""Flask route definitions."""
from flask import jsonify, render_template, request

from .api import (
    get_mmr_history,
    get_replays_api,
    get_latest_api,
    get_stats_api,
    get_maps_api,
    get_tags_api,
    create_tag_api,
    end_tag_api,
    delete_tag_api,
    get_columns_api,
    update_columns_api,
    trigger_scan_api,
    get_config_api,
    update_config_api,
    get_races_api,
    get_notes_api,
    save_notes_api,
    delete_notes_api,
    get_notes_feed_api,
    get_analysis_config_api,
)


def register_routes(app):
    """Register all routes on the Flask app."""

    # ============================================================
    # GUI PAGES
    # ============================================================

    @app.route("/")
    def index():
        """Serve the main GUI page."""
        return render_template("index.html")

    @app.route("/analysis")
    def analysis_page():
        """Serve the dedicated analysis page."""
        return render_template("analysis.html")

    # ============================================================
    # OVERLAYS (existing + new)
    # ============================================================

    @app.route("/overlays/mmr-graph")
    def mmr_graph_overlay():
        """Render MMR graph overlay page."""
        return render_template("mmr_graph.html")

    @app.route("/overlays/stream-widget")
    def stream_widget_overlay():
        """Render configurable stream widget overlay."""
        return render_template("stream_widget.html")

    @app.route("/overlays/analysis-widget")
    def analysis_widget_overlay():
        """Render post-game analysis overlay."""
        return render_template("analysis_widget.html")

    # ============================================================
    # API: MMR History (updated with filter support)
    # ============================================================

    @app.route("/api/v1/mmr/history")
    def mmr_history():
        """Get MMR history for graphing, with optional filters."""
        result = get_mmr_history(
            limit=_int_param("limit") or 100,
            days=_int_param("days"),
            matchup=request.args.get("matchup"),
            result=request.args.get("result"),
            player_race=request.args.get("player_race"),
            is_ladder=_bool_param("is_ladder", default=True),
        )
        return jsonify(result)

    # ============================================================
    # API: Replays
    # ============================================================

    @app.route("/api/v1/replays")
    def replays():
        """Get replays with optional filters."""
        result = get_replays_api(
            matchup=request.args.get("matchup"),
            result=request.args.get("result"),
            map_name=request.args.get("map"),
            days=_int_param("days"),
            limit=_int_param("limit"),
            min_length=_int_param("min_length"),
            max_length=_int_param("max_length"),
            min_workers_8m=_int_param("min_workers_8m"),
            max_workers_8m=_int_param("max_workers_8m"),
            player_race=request.args.get("player_race"),
            is_ladder=_bool_param("is_ladder", default=True),
        )
        return jsonify(result)

    @app.route("/api/v1/replays/latest")
    def latest_replay():
        """Get the most recent replay."""
        result = get_latest_api()
        return jsonify(result)

    # ============================================================
    # API: Stats
    # ============================================================

    @app.route("/api/v1/stats")
    def stats():
        """Get aggregate statistics."""
        result = get_stats_api(
            matchup=request.args.get("matchup"),
            days=_int_param("days"),
            player_race=request.args.get("player_race"),
            is_ladder=_bool_param("is_ladder", default=True),
        )
        return jsonify(result)

    @app.route("/api/v1/maps")
    def maps():
        """Get unique map names."""
        result = get_maps_api()
        return jsonify(result)

    @app.route("/api/v1/races")
    def races():
        """Get race distribution and auto-detected default."""
        result = get_races_api()
        return jsonify(result)

    # ============================================================
    # API: Tags
    # ============================================================

    @app.route("/api/v1/tags", methods=["GET"])
    def tags_list():
        """Get all tags."""
        result = get_tags_api()
        return jsonify(result)

    @app.route("/api/v1/tags", methods=["POST"])
    def tags_create():
        """Create a new tag."""
        data = request.get_json()
        if not data or "label" not in data:
            return jsonify({"success": False, "message": "label is required"}), 400

        result = create_tag_api(
            label=data["label"],
            date=data.get("date"),
            end_date=data.get("end_date"),
        )
        status_code = 201 if result["success"] else 409
        return jsonify(result), status_code

    @app.route("/api/v1/tags/<int:tag_id>/end", methods=["PUT"])
    def tags_end(tag_id):
        """End an ongoing tag."""
        data = request.get_json() or {}
        result = end_tag_api(
            tag_id=tag_id,
            end_date=data.get("end_date"),
        )
        status_code = 200 if result["success"] else 404
        return jsonify(result), status_code

    @app.route("/api/v1/tags/<int:tag_id>", methods=["DELETE"])
    def tags_delete(tag_id):
        """Delete a tag."""
        result = delete_tag_api(tag_id=tag_id)
        status_code = 200 if result["success"] else 404
        return jsonify(result), status_code

    # ============================================================
    # API: Columns
    # ============================================================

    @app.route("/api/v1/columns", methods=["GET"])
    def columns_get():
        """Get display columns configuration."""
        result = get_columns_api()
        return jsonify(result)

    @app.route("/api/v1/columns", methods=["PUT"])
    def columns_update():
        """Update display columns."""
        data = request.get_json()
        if not data or "columns" not in data:
            return jsonify({"success": False, "message": "columns list is required"}), 400

        result = update_columns_api(columns=data["columns"])
        status_code = 200 if result["success"] else 400
        return jsonify(result), status_code

    # ============================================================
    # API: Config
    # ============================================================

    @app.route("/api/v1/config", methods=["GET"])
    def config_get():
        """Get current configuration."""
        result = get_config_api()
        return jsonify(result)

    @app.route("/api/v1/config", methods=["PUT"])
    def config_update():
        """Update configuration (player_name, region)."""
        data = request.get_json()
        if not data:
            return jsonify({"success": False, "message": "Request body required"}), 400

        result = update_config_api(
            player_name=data.get("player_name"),
            region=data.get("region"),
        )
        return jsonify(result)

    # ============================================================
    # API: Scan
    # ============================================================

    @app.route("/api/v1/scan", methods=["POST"])
    def scan():
        """Trigger a replay scan."""
        result = trigger_scan_api()
        return jsonify(result)

    # ============================================================
    # API: Replay Notes (Post Game Analysis)
    # ============================================================

    @app.route("/api/v1/replays/<replay_id>/notes", methods=["GET"])
    def notes_get(replay_id):
        """Get analysis notes for a replay."""
        result = get_notes_api(replay_id)
        return jsonify(result)

    @app.route("/api/v1/replays/<replay_id>/notes", methods=["PUT"])
    def notes_save(replay_id):
        """Save/update analysis notes for a replay."""
        data = request.get_json()
        if not data or "analysis" not in data:
            return jsonify({"success": False, "message": "analysis object required"}), 400

        result = save_notes_api(replay_id, data["analysis"])
        status_code = 200 if result["success"] else 500
        return jsonify(result), status_code

    @app.route("/api/v1/replays/<replay_id>/notes", methods=["DELETE"])
    def notes_delete(replay_id):
        """Delete analysis notes for a replay."""
        result = delete_notes_api(replay_id)
        status_code = 200 if result["success"] else 404
        return jsonify(result), status_code

    @app.route("/api/v1/notes/feed")
    def notes_feed():
        """Get all notes with replay context for feed view."""
        result = get_notes_feed_api(
            days=_int_param("days"),
            limit=_int_param("limit"),
        )
        return jsonify(result)

    @app.route("/api/v1/analysis/config")
    def analysis_config():
        """Get post-game analysis form field configuration."""
        result = get_analysis_config_api()
        return jsonify(result)


# ============================================================
# HELPERS
# ============================================================


def _int_param(name: str):
    """Parse an optional integer query parameter."""
    value = request.args.get(name)
    if value is not None:
        try:
            return int(value)
        except ValueError:
            return None
    return None


def _bool_param(name: str, default=None):
    """Parse an optional boolean query parameter."""
    value = request.args.get(name)
    if value is None:
        return default
    return value.lower() in ("true", "1", "yes")
