import os
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.tools.neo4j_session_tools as session_tools
import modules.database.init.init_user as init_user
from modules.database.tools.neo4j_db_formatter import format_user_email_for_neo_db
import modules.database.init.init_school as init_school
import modules.database.init.init_school_timetable as init_school_timetable
import modules.database.init.init_school_curriculum as init_school_curriculum
import modules.database.init.xl_tools as xl
from modules.database.schemas.nodes.schools.schools import SchoolNode, SubjectClassNode, RoomNode, DepartmentNode
from fastapi import APIRouter, Form, HTTPException
from fastapi.responses import JSONResponse
import json

VALID_USER_TYPES = ['admin', 'cc_admin', 'cc_email_school_admin', 'cc_ms_school_admin', 'email_school_admin', 'ms_school_admin', 'cc_email_teacher', 'cc_ms_teacher', 'cc_email_student', 'cc_ms_student', 'email_teacher', 'ms_teacher', 'email_student', 'ms_student', 'ms_federated_teacher', 'ms_federated_student', 'standard', 'developer'] # TODO: Implement dev_ user types for pytests, consider use of cc_ user types

router = APIRouter()

# Helpers
def initialise_schools_from_config():
        """Initialize a school with the configuration provided from env variables
        """
        default_config = {
            "uuid_string": "kevlarai-dev",
            "name": "KevlarAI School",
            "website": "https://kevlarai.com",
            "timetable_file": "kevlarai_data/kevlarai_timetable.xlsx",
            "curriculum_file": "kevlarai_data/kevlarai_curriculum.xlsx"
        }
        
        # school_config_str = os.getenv("SCHOOL_CONFIG") # TODO: Implement this
        school_config = default_config
    
        db_name = f"cc.institutes.{school_config['uuid_string']}"
        curriculum_db_name = f"{db_name}.curriculum"
        
        logger.info(f"Creating database for {school_config['name']} using db_name: {db_name}")
        driver = driver_tools.get_driver()
        if driver is None:
            logger.error("Failed to connect to Neo4j")
            return
        
        with driver.session() as session:
            # Create main school database
            session_tools.create_database(session, db_name)
            logger.debug(f"Database {db_name} created")
            
            # Create curriculum database
            session_tools.create_database(session, curriculum_db_name)
            logger.debug(f"Curriculum database {curriculum_db_name} created")
        
        # Add filesystem path debugging
        base_path = os.getenv("NODE_FILESYSTEM_PATH")
        schools_path = os.path.join(base_path, "schools")
        school_path = os.path.join(schools_path, f"cc.institutes.{school_config['uuid_string']}")
        
        logger.debug("Filesystem paths:", {
            "base_path": base_path,
            "schools_path": schools_path,
            "school_path": school_path
        })
        
        # Check if directories exist
        logger.debug("Directory existence check:", {
            "base_exists": os.path.exists(base_path),
            "schools_exists": os.path.exists(schools_path),
            "school_exists": os.path.exists(school_path)
        })
        
        # Create database entry for school without timetable or curriculum
        logger.info(f"Creating school entry for {school_config['name']} in database {db_name} without timetable or curriculum")
        
        school_uuid_string=school_config["uuid_strig"]
        school_name=school_config["name"]
        school_website=school_config["website"]

        result = init_school.create_school(
            db_name=db_name,
            school_type="development",
            uuid_string=school_uuid_string,
            name=school_name,
            website=school_website
        )
        logger.success(f"{school_config['name']} school entry created successfully")
        
        # Create school node from result
        school_node = result['school_node']
        refreshed_school_node = SchoolNode(
            school_type="development",
            uuid_string=school_node.uuid_string,
            name=school_node.name,
            website=school_node.website
        )

        # Create timetable entries for school from Excel file
        timetable_file = os.path.join(os.getenv("BACKEND_INIT_PATH"), school_config["timetable_file"])
        
        logger.info(f"Creating timetable entries for {school_config['name']} using timetable file: {timetable_file}.")
        school_timetable_dataframes = xl.create_dataframes(timetable_file)
        
        
        init_school_timetable.create_school_timetable(
            dataframes=school_timetable_dataframes, 
            db_name=db_name, 
            school_node=refreshed_school_node
        )
        logger.success("Timetable entries created successfully")

        # Create curriculum entries for school from Excel file in both databases
        curriculum_file = os.path.join(os.getenv("BACKEND_INIT_PATH"), school_config["curriculum_file"])
        school_curriculum_dataframes = xl.create_dataframes(curriculum_file)
        
        logger.info(f"Creating curriculum entries for {school_config['name']} using curriculum file: {curriculum_file}.")
        init_school_curriculum.create_curriculum(
            dataframes=school_curriculum_dataframes, 
            db_name=db_name,
            curriculum_db_name=curriculum_db_name,
            school_node=refreshed_school_node
        )
        logger.success("Curriculum entries created successfully")


@router.post("/create-user")
async def create_user(
    user_id: str = Form(...),
    user_type: str = Form(...),
    user_name: str = Form(...),
    user_email: str = Form(...),
    school_uuid_string: str = Form(None),
    school_name: str = Form(None),
    school_website: str = Form(None),
    school_node_storage_path: str = Form(None),
    worker_data: str = Form(None)
):
    logger.info(f"Creating user with user_id: {user_id}, user_type: {user_type}, user_name: {user_name}, user_email: {user_email}")
    
    if school_uuid_string:
        logger.info(f"School UUID string provided: {school_uuid_string}")
    else:
        logger.info(f"No school UUID string provided")
        
    if school_name:
        logger.info(f"School name provided: {school_name}")
    else:
        logger.info(f"No school name provided")
    
    if school_website:
        logger.info(f"School website provided: {school_website}")
    else:
        logger.info(f"No school website provided")
        
    if school_node_storage_path:
        logger.info(f"School path provided: {school_node_storage_path}")
    else:
        logger.info(f"No school path provided")
    
    if worker_data:
        logger.info(f"Worker data provided: {worker_data}")
    else:
        logger.info(f"No worker data provided")
    
    # Validate inputs
    if any(param is None for param in (user_type, user_name, user_email, user_id)):
        raise HTTPException(status_code=400, detail=f"Invalid user data")
    
    if user_type not in VALID_USER_TYPES:
        raise HTTPException(status_code=400, detail=f"Invalid user type: {user_type}")
    
    try:
        # Parse worker data
        worker_data_dict = json.loads(worker_data) if worker_data else None
        
        # Create school node if school data provided
        school_node = None
        if all([school_uuid_string, school_name, school_website, school_node_storage_path]):
            school_node = SchoolNode(
                uuid_string=school_uuid_string,
                name=school_name,
                website=school_website,
                node_storage_path=school_node_storage_path
            )
        
        # Create user with single database reference
        formatted_email = format_user_email_for_neo_db(user_email)
        user_db_name = f"cc.users.{formatted_email}"
        
        result = init_user.create_user(
            db_name=user_db_name,
            user_id=user_id,
            user_type=user_type,
            username=user_name,
            email=user_email,
            school_node=school_node,
            worker_data=worker_data_dict
        )
        
        # Ensure the result is JSON serializable
        response_data = {
            "status": "success",
            "data": {
                "user_node": result['user_node'],
                "worker_node": result['worker_node'],
                "calendar_nodes": result.get('calendar_nodes')
            }
        }
        
        return JSONResponse(content=response_data)
        
    except Exception as e:
        logger.error(f"Error creating user in Neo4j: {str(e)}", exc_info=True)
        return JSONResponse(
            content={"status": "error", "message": str(e)},
            status_code=500
        )

@router.post("/create-schools")
async def create_schools():
    initialise_schools_from_config()
    return JSONResponse(content={"status": "success", "message": "Schools created successfully"})

@router.post("/create-department")
async def create_department(
    db_name: str = Form(...),
    uuid_string: str = Form(...),
    department_name: str = Form(...),
    department_code: str = Form(...),
    department_node_storage_path: str = Form(...)
):
    if db_name is None or uuid_string is None or department_name is None or department_code is None or department_node_storage_path is None:
        logging.error(f"Invalid department data: {db_name}, {uuid_string}, {department_name}, {department_code}, {department_node_storage_path}")
        raise HTTPException(status_code=400, detail="Invalid department data")

    department = DepartmentNode(
        uuid_string=uuid_string,
        department_name=department_name,
        department_code=department_code,
        node_storage_path=department_node_storage_path
    )

    logger.info(f"Creating department {department_name} with uuid_string {uuid_string}")
    try:
        result = init_school.create_department(db_name, department)
        return JSONResponse(content={"status": "success", "data": result})
    except Exception as e:
        logger.error(f"Error creating department: {str(e)}")
        return JSONResponse(content={"status": "error", "message": str(e)}, status_code=500)

@router.post("/create-class")
async def create_class(
    db_name: str = Form(...),
    uuid_string: str = Form(...),
    subject_class_code: str = Form(...),
    year_group: str = Form(...),
    subject: str = Form(...),
    subject_code: str = Form(...),
    subject_node_storage_path: str = Form(...)
):
    subject_class_node = SubjectClassNode(
        uuid_string=uuid_string,
        subject_class_code=subject_class_code,
        year_group=year_group,
        subject=subject,
        subject_code=subject_code,
        node_storage_path=subject_node_storage_path
    )
    # Implementation for creating a class
    pass

@router.post("/create-room")
async def create_room(
    db_name: str = Form(...),
    room_uuid_string: str = Form(...),
    room_code: str = Form(...),
    room_node_storage_path: str = Form(...)
):
    room = RoomNode(
        room_uuid_string=room_uuid_string,
        room_code=room_code,
        node_storage_path=room_node_storage_path
    )
    # Implementation for creating a room
    pass