"""
Routine Tags API - structured categories for routines
"""

import os
import uuid
import flask
import jwt
import core.auth as auth
import core.postgres as postgres


def _get_user_uuid(token):
    try:
        payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
        return payload.get("sub")
    except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
        return None


def _auth(request):
    header = request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return None
    token = header[7:]
    user_uuid = _get_user_uuid(token)
    if not user_uuid or not auth.verifyLoginToken(token, userUUID=user_uuid):
        return None
    return user_uuid


def register(app):

    @app.route("/api/tags", methods=["GET"])
    def api_listTags():
        """List all available tags."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        tags = postgres.select("routine_tags", order_by="name")
        return flask.jsonify(tags), 200

    @app.route("/api/tags", methods=["POST"])
    def api_createTag():
        """Create a new tag. Body: {name, color?}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        data = flask.request.get_json()
        if not data or not data.get("name"):
            return flask.jsonify({"error": "missing required field: name"}), 400
        existing = postgres.select_one("routine_tags", {"name": data["name"]})
        if existing:
            return flask.jsonify({"error": "tag already exists"}), 409
        tag = {
            "id": str(uuid.uuid4()),
            "name": data["name"],
            "color": data.get("color", "#888888"),
        }
        result = postgres.insert("routine_tags", tag)
        return flask.jsonify(result), 201

    @app.route("/api/tags/<tag_id>", methods=["DELETE"])
    def api_deleteTag(tag_id):
        """Delete a tag."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        tag = postgres.select_one("routine_tags", {"id": tag_id})
        if not tag:
            return flask.jsonify({"error": "tag not found"}), 404
        postgres.delete("routine_routine_tags", {"tag_id": tag_id})
        postgres.delete("routine_tags", {"id": tag_id})
        return flask.jsonify({"deleted": True}), 200

    @app.route("/api/routines/<routine_id>/tags", methods=["POST"])
    def api_addTagToRoutine(routine_id):
        """Add tags to a routine. Body: {tag_ids: [uuid, ...]}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
        if not routine:
            return flask.jsonify({"error": "routine not found"}), 404
        data = flask.request.get_json()
        if not data or not data.get("tag_ids"):
            return flask.jsonify({"error": "missing tag_ids"}), 400
        for tag_id in data["tag_ids"]:
            existing_link = postgres.select_one("routine_routine_tags", {"routine_id": routine_id, "tag_id": tag_id})
            if not existing_link:
                postgres.insert("routine_routine_tags", {"routine_id": routine_id, "tag_id": tag_id})
        tags = postgres.execute("""
            SELECT t.* FROM routine_tags t
            JOIN routine_routine_tags rt ON t.id = rt.tag_id
            WHERE rt.routine_id = %s
        """, {"routine_id": routine_id})
        return flask.jsonify(tags), 200

    @app.route("/api/routines/<routine_id>/tags/<tag_id>", methods=["DELETE"])
    def api_removeTagFromRoutine(routine_id, tag_id):
        """Remove a tag from a routine."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
        if not routine:
            return flask.jsonify({"error": "routine not found"}), 404
        postgres.delete("routine_routine_tags", {"routine_id": routine_id, "tag_id": tag_id})
        return flask.jsonify({"removed": True}), 200

    @app.route("/api/routines/<routine_id>/tags", methods=["GET"])
    def api_getRoutineTags(routine_id):
        """Get tags for a routine."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        routine = postgres.select_one("routines", {"id": routine_id, "user_uuid": user_uuid})
        if not routine:
            return flask.jsonify({"error": "routine not found"}), 404
        tags = postgres.execute("""
            SELECT t.* FROM routine_tags t
            JOIN routine_routine_tags rt ON t.id = rt.tag_id
            WHERE rt.routine_id = %s
        """, {"routine_id": routine_id})
        return flask.jsonify(tags), 200
