import os
from typing import Dict, Any
from fastapi import APIRouter, Depends
from modules.logger_tool import initialise_logger
from modules.auth.supabase_bearer import SupabaseBearer
from modules.database.services.provisioning_service import ProvisioningService
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.schemas.nodes.users as user_nodes
import modules.database.tools.neontology_tools as neon

logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
router = APIRouter()


def _teacher_db(user_id: str) -> str:
    return f"cc.users.teacher.{user_id.replace('-', '')}"


def _ensure_journal_planner(user_id: str, teacher_db: str) -> None:
    neon.init_neontology_connection()
    try:
        with driver_tools.get_session(database=teacher_db) as session:
            has_journal = session.run("MATCH (j:Journal) RETURN count(j) AS n").single()["n"] > 0
            has_planner = session.run("MATCH (p:Planner) RETURN count(p) AS n").single()["n"] > 0

        if not has_journal:
            journal = user_nodes.JournalNode(
                uuid_string=f"{user_id}_journal",
                node_storage_path=f"users/{user_id}/nodes/journal",
                user_id=user_id,
            )
            neon.create_or_merge_neontology_node(journal, database=teacher_db, operation='merge')
            logger.info(f"Created Journal node for {user_id}")

        if not has_planner:
            planner = user_nodes.PlannerNode(
                uuid_string=f"{user_id}_planner",
                node_storage_path=f"users/{user_id}/nodes/planner",
                user_id=user_id,
            )
            neon.create_or_merge_neontology_node(planner, database=teacher_db, operation='merge')
            logger.info(f"Created Planner node for {user_id}")
    finally:
        neon.close_neontology_connection()


@router.post("/init")
async def init_user(credentials: dict = Depends(SupabaseBearer())) -> Dict[str, Any]:
    user_id = credentials.get("sub", "")
    if not user_id:
        return {"status": "error", "message": "No user ID in token"}

    db = _teacher_db(user_id)

    # Fast path: check if already fully provisioned
    try:
        with driver_tools.get_session(database=db) as session:
            r = session.run(
                "MATCH (u:User) "
                "OPTIONAL MATCH (j:Journal) "
                "OPTIONAL MATCH (p:Planner) "
                "RETURN count(u) AS u, count(j) AS j, count(p) AS p"
            ).single()
            if r and r["u"] > 0 and r["j"] > 0 and r["p"] > 0:
                logger.debug(f"User {user_id} already initialized — fast path")
                return {"status": "ok", "initialized": True, "teacher_db": db}
    except Exception:
        pass  # DB doesn't exist yet — fall through to full provisioning

    # Full provisioning
    try:
        logger.info(f"Provisioning user {user_id}...")
        service = ProvisioningService()
        result = service.ensure_user(user_id)
        user_db = result.get("user_db_name") or db
        _ensure_journal_planner(user_id, user_db)
        logger.info(f"User {user_id} provisioned successfully: {user_db}")
        return {"status": "ok", "initialized": True, "teacher_db": user_db}
    except Exception as e:
        logger.error(f"User init failed for {user_id}: {e}")
        return {"status": "error", "message": str(e)}
