"""
Routine Templates API - pre-built routines that users can clone
"""

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/templates", methods=["GET"])
    def api_listTemplates():
        """List all available templates. Optional query param: category"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        
        # Check for category filter
        category = flask.request.args.get('category')
        if category:
            templates = postgres.select("routine_templates", where={"category": category}, order_by="name")
        else:
            templates = postgres.select("routine_templates", order_by="category, name")
        
        for template in templates:
            steps = postgres.select("routine_template_steps", {"template_id": template["id"]}, order_by="position")
            template["step_count"] = len(steps)
        return flask.jsonify(templates), 200

    @app.route("/api/templates/categories", methods=["GET"])
    def api_listTemplateCategories():
        """List all unique template categories."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        
        # Get distinct categories
        result = postgres.execute("""
            SELECT DISTINCT category FROM routine_templates 
            WHERE category IS NOT NULL 
            ORDER BY category
        """)
        categories = [row["category"] for row in result]
        return flask.jsonify(categories), 200

    @app.route("/api/templates", methods=["POST"])
    def api_createTemplate():
        """Create a new template (admin only in production). Body: {name, description?, icon?}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        data = flask.request.get_json()
        if not data:
            return flask.jsonify({"error": "missing body"}), 400
        if not data.get("name"):
            return flask.jsonify({"error": "missing required field: name"}), 400
        data["id"] = str(uuid.uuid4())
        data["created_by_admin"] = False
        template = postgres.insert("routine_templates", data)
        return flask.jsonify(template), 201

    @app.route("/api/templates/<template_id>", methods=["GET"])
    def api_getTemplate(template_id):
        """Get a template with its steps."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        template = postgres.select_one("routine_templates", {"id": template_id})
        if not template:
            return flask.jsonify({"error": "template not found"}), 404
        steps = postgres.select("routine_template_steps", {"template_id": template_id}, order_by="position")
        return flask.jsonify({"template": template, "steps": steps}), 200

    @app.route("/api/templates/<template_id>/clone", methods=["POST"])
    def api_cloneTemplate(template_id):
        """Clone a template to user's routines."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        template = postgres.select_one("routine_templates", {"id": template_id})
        if not template:
            return flask.jsonify({"error": "template not found"}), 404
        template_steps = postgres.select("routine_template_steps", {"template_id": template_id}, order_by="position")
        new_routine = {
            "id": str(uuid.uuid4()),
            "user_uuid": user_uuid,
            "name": template["name"],
            "description": template.get("description"),
            "icon": template.get("icon"),
        }
        routine = postgres.insert("routines", new_routine)
        for step in template_steps:
            new_step = {
                "id": str(uuid.uuid4()),
                "routine_id": routine["id"],
                "name": step["name"],
                "instructions": step.get("instructions"),
                "step_type": step.get("step_type", "generic"),
                "duration_minutes": step.get("duration_minutes"),
                "media_url": step.get("media_url"),
                "position": step["position"],
            }
            postgres.insert("routine_steps", new_step)
        return flask.jsonify(routine), 201

    @app.route("/api/templates/<template_id>", methods=["PUT"])
    def api_updateTemplate(template_id):
        """Update a template."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        template = postgres.select_one("routine_templates", {"id": template_id})
        if not template:
            return flask.jsonify({"error": "template not found"}), 404
        data = flask.request.get_json()
        if not data:
            return flask.jsonify({"error": "missing body"}), 400
        allowed = ["name", "description", "icon"]
        updates = {k: v for k, v in data.items() if k in allowed}
        if not updates:
            return flask.jsonify({"error": "no valid fields to update"}), 400
        result = postgres.update("routine_templates", updates, {"id": template_id})
        return flask.jsonify(result[0] if result else {}), 200

    @app.route("/api/templates/<template_id>", methods=["DELETE"])
    def api_deleteTemplate(template_id):
        """Delete a template."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        template = postgres.select_one("routine_templates", {"id": template_id})
        if not template:
            return flask.jsonify({"error": "template not found"}), 404
        postgres.delete("routine_template_steps", {"template_id": template_id})
        postgres.delete("routine_templates", {"id": template_id})
        return flask.jsonify({"deleted": True}), 200

    @app.route("/api/templates/<template_id>/steps", methods=["POST"])
    def api_addTemplateStep(template_id):
        """Add a step to a template. Body: {name, instructions?, step_type?, duration_minutes?, position?}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        template = postgres.select_one("routine_templates", {"id": template_id})
        if not template:
            return flask.jsonify({"error": "template not found"}), 404
        data = flask.request.get_json()
        if not data or not data.get("name"):
            return flask.jsonify({"error": "missing required field: name"}), 400
        max_pos = postgres.select(
            "routine_template_steps",
            {"template_id": template_id},
            order_by="position DESC",
            limit=1,
        )
        next_pos = (max_pos[0]["position"] + 1) if max_pos else 1
        step = {
            "id": str(uuid.uuid4()),
            "template_id": template_id,
            "name": data["name"],
            "instructions": data.get("instructions"),
            "step_type": data.get("step_type", "generic"),
            "duration_minutes": data.get("duration_minutes"),
            "media_url": data.get("media_url"),
            "position": data.get("position", next_pos),
        }
        result = postgres.insert("routine_template_steps", step)
        return flask.jsonify(result), 201
