"""
main.py - Flask API with auth routes and module registry

Domain routes are registered via the routes registry.
"""

import os
import flask
from flask_cors import CORS
import core.auth as auth
import core.users as users
import core.postgres as postgres
import api.routes.routines as routines_routes
import api.routes.medications as medications_routes
import api.routes.routine_steps_extended as routine_steps_extended_routes
import api.routes.routine_sessions_extended as routine_sessions_extended_routes
import api.routes.routine_templates as routine_templates_routes
import api.routes.routine_stats as routine_stats_routes
import api.routes.routine_tags as routine_tags_routes
import api.routes.notifications as notifications_routes
import api.routes.preferences as preferences_routes
import api.routes.rewards as rewards_routes
import api.routes.victories as victories_routes

app = flask.Flask(__name__)
CORS(app)

ROUTE_MODULES = [
    routines_routes,
    medications_routes,
    routine_steps_extended_routes,
    routine_sessions_extended_routes,
    routine_templates_routes,
    routine_stats_routes,
    routine_tags_routes,
    notifications_routes,
    preferences_routes,
    rewards_routes,
    victories_routes,
]


def register_routes(module):
    """Register a routes module. Module should have a register(app) function."""
    ROUTE_MODULES.append(module)


# ── Auth Routes ────────────────────────────────────────────────────


@app.route("/api/register", methods=["POST"])
def api_register():
    data = flask.request.get_json()
    username = data.get("username")
    password = data.get("password")
    if not username or not password:
        return flask.jsonify({"error": "username and password required"}), 400
    result = users.registerUser(username, password, data)
    if result:
        return flask.jsonify({"success": True}), 201
    else:
        return flask.jsonify({"error": "username taken"}), 409


@app.route("/api/login", methods=["POST"])
def api_login():
    data = flask.request.get_json()
    username = data.get("username")
    password = data.get("password")
    if not username or not password:
        return flask.jsonify({"error": "username and password required"}), 400
    token = auth.getLoginToken(username, password)
    if token:
        return flask.jsonify({"token": token}), 200
    else:
        return flask.jsonify({"error": "invalid credentials"}), 401


# ── User Routes ────────────────────────────────────────────────────


@app.route("/api/getUserUUID/<username>", methods=["GET"])
def api_getUserUUID(username):
    header = flask.request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return flask.jsonify({"error": "missing token"}), 401
    token = header[7:]
    if auth.verifyLoginToken(token, username):
        return flask.jsonify(users.getUserUUID(username)), 200
    else:
        return flask.jsonify({"error": "unauthorized"}), 401


@app.route("/api/user/<userUUID>", methods=["GET"])
def api_getUser(userUUID):
    header = flask.request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return flask.jsonify({"error": "missing token"}), 401
    token = header[7:]
    if auth.verifyLoginToken(token, userUUID=userUUID):
        user = postgres.select_one("users", {"id": userUUID})
        if user:
            user.pop("password_hashed", None)
            return flask.jsonify(user), 200
        else:
            return flask.jsonify({"error": "user not found"}), 404
    else:
        return flask.jsonify({"error": "unauthorized"}), 401


@app.route("/api/user/<userUUID>", methods=["PUT"])
def api_updateUser(userUUID):
    header = flask.request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return flask.jsonify({"error": "missing token"}), 401
    token = header[7:]
    if auth.verifyLoginToken(token, userUUID=userUUID):
        data = flask.request.get_json()
        result = users.updateUser(userUUID, data)
        if result:
            return flask.jsonify({"success": True}), 200
        else:
            return flask.jsonify({"error": "no valid fields to update"}), 400
    else:
        return flask.jsonify({"error": "unauthorized"}), 401


@app.route("/api/user/<userUUID>", methods=["DELETE"])
def api_deleteUser(userUUID):
    header = flask.request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return flask.jsonify({"error": "missing token"}), 401
    token = header[7:]
    if auth.verifyLoginToken(token, userUUID=userUUID):
        data = flask.request.get_json()
        password = data.get("password")
        if not password:
            return flask.jsonify(
                {"error": "password required for account deletion"}
            ), 400
        result = auth.unregisterUser(userUUID, password)
        if result:
            return flask.jsonify({"success": True}), 200
        else:
            return flask.jsonify({"error": "invalid password"}), 401
    else:
        return flask.jsonify({"error": "unauthorized"}), 401


# ── Health Check ───────────────────────────────────────────────────


@app.route("/health", methods=["GET"])
def health_check():
    return flask.jsonify({"status": "ok"}), 200


def _seed_templates_if_empty():
    """Auto-seed routine templates if the table is empty."""
    try:
        count = postgres.count("routine_templates")
        if count == 0:
            import logging
            logging.getLogger(__name__).info("No templates found, seeding from seed_templates.sql...")
            seed_path = os.path.join(os.path.dirname(__file__), "..", "config", "seed_templates.sql")
            if os.path.exists(seed_path):
                with open(seed_path, "r") as f:
                    sql = f.read()
                with postgres.get_cursor() as cur:
                    cur.execute(sql)
                logging.getLogger(__name__).info("Templates seeded successfully.")
    except Exception as e:
        import logging
        logging.getLogger(__name__).warning(f"Failed to seed templates: {e}")


def _seed_rewards_if_empty():
    """Auto-seed reward pool if the table is empty."""
    try:
        count = postgres.count("reward_pool")
        if count == 0:
            import logging
            logging.getLogger(__name__).info("No rewards found, seeding from seed_rewards.sql...")
            seed_path = os.path.join(os.path.dirname(__file__), "..", "config", "seed_rewards.sql")
            if os.path.exists(seed_path):
                with open(seed_path, "r") as f:
                    sql = f.read()
                with postgres.get_cursor() as cur:
                    cur.execute(sql)
                logging.getLogger(__name__).info("Rewards seeded successfully.")
    except Exception as e:
        import logging
        logging.getLogger(__name__).warning(f"Failed to seed rewards: {e}")


if __name__ == "__main__":
    for module in ROUTE_MODULES:
        if hasattr(module, "register"):
            module.register(app)
    _seed_templates_if_empty()
    _seed_rewards_if_empty()
    app.run(host="0.0.0.0", port=5000)
