"""Allowlist API: list, adjust threshold, remove."""

from quart import Blueprint, jsonify, request

from ..extensions import get_session
from ..models import TagAllowlist
from ..services.ml.allowlist import AllowlistService

allowlist_bp = Blueprint("allowlist", __name__, url_prefix="/api")


@allowlist_bp.route("/allowlist", methods=["GET"])
async def list_allowlist():
    async with get_session() as session:
        rows = await AllowlistService(session).list_all()
    return jsonify(
        [
            {
                "tag_id": r.tag_id,
                "tag_name": r.tag_name,
                "tag_kind": r.tag_kind,
                "min_confidence": r.min_confidence,
                "applied_count": r.applied_count,
                "coverage_count": r.coverage_count,
            }
            for r in rows
        ]
    )


@allowlist_bp.route("/tags/<int:tag_id>/allowlist/coverage", methods=["GET"])
async def coverage(tag_id: int):
    """Live "at threshold T, a sweep would cover ~N images" projection for the
    allowlist tuning dashboard. Defaults to the tag's stored threshold."""
    raw = request.args.get("threshold")
    async with get_session() as session:
        svc = AllowlistService(session)
        if raw is not None:
            try:
                threshold = float(raw)
            except ValueError:
                return jsonify({"error": "threshold must be a float"}), 400
            if not (0 < threshold <= 1):
                return jsonify({"error": "threshold must be in (0, 1]"}), 400
        else:
            row = await session.get(TagAllowlist, tag_id)
            if row is None:
                return jsonify({"error": "not on allowlist"}), 404
            threshold = row.min_confidence
        count = await svc.coverage(tag_id, threshold)
    return jsonify({"count": count, "threshold": threshold})


@allowlist_bp.route("/tags/<int:tag_id>/allowlist", methods=["GET"])
async def get_one(tag_id: int):
    async with get_session() as session:
        row = await session.get(TagAllowlist, tag_id)
    if row is None:
        return jsonify({"error": "not on allowlist"}), 404
    return jsonify(
        {"min_confidence": row.min_confidence, "added_at": row.added_at.isoformat()}
    )


@allowlist_bp.route("/tags/<int:tag_id>/allowlist", methods=["PATCH"])
async def patch_threshold(tag_id: int):
    body = await request.get_json()
    if not body or "min_confidence" not in body:
        return jsonify({"error": "min_confidence required"}), 400
    mc = float(body["min_confidence"])
    if not (0 < mc <= 1):
        return jsonify({"error": "min_confidence must be in (0, 1]"}), 400
    async with get_session() as session:
        await AllowlistService(session).update_threshold(tag_id, mc)
        await session.commit()
    return "", 204


@allowlist_bp.route("/tags/<int:tag_id>/allowlist", methods=["DELETE"])
async def remove(tag_id: int):
    async with get_session() as session:
        await AllowlistService(session).remove(tag_id)
        await session.commit()
    return "", 204
