from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
import os
import modules.logger_tool as logger
log_name = 'api_routers_database_init_timetables'
log_dir = os.getenv("LOG_PATH", "/logs")  # Default path as fallback
logging = logger.get_logger(
    name=log_name,
    log_level=os.getenv("LOG_LEVEL", "DEBUG"),
    log_path=log_dir,
    log_file=log_name,
    runtime=True,
    log_format='default'
)
from fastapi import APIRouter, File, UploadFile, Form, HTTPException, BackgroundTasks
import pandas as pd
import modules.database.tools.neo4j_driver_tools as driver
from modules.database.tools.neo4j_session_tools import get_node_by_uuid_string
import modules.database.init.init_school_timetable as init_school_timetable
import modules.database.init.init_worker_timetable as init_worker_timetable
from modules.database.schemas.nodes.users import UserNode
from modules.database.schemas.nodes.schools.schools import SchoolNode
from modules.database.schemas.nodes.workers.workers import TeacherNode
import modules.database.init.xl_tools as xl
import json
import modules.database.tools.neontology_tools as neon

router = APIRouter()

@router.post("/upload-school-timetable")
async def upload_school_timetable(
    file: UploadFile = File(...),
    db_name: str = Form(...),
    school_uuid_string: str = Form(...),
    school_name: str = Form(...),
    school_website: str = Form(...),
    school_node_storage_path: str = Form(...)
):
    school_node = SchoolNode(
        uuid_string=school_uuid_string,
        name=school_name,
        website=school_website,
        node_storage_path=school_node_storage_path
    )
    if file.content_type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
        return {"status": "Error", "message": "Invalid file format"}
    logging.info(f"Uploading timetable for {db_name} from {file.filename}")
    dataframes = xl.create_dataframes_from_fastapiuploadfile(file)
    return init_school_timetable.create_school_timetable(dataframes, db_name, school_node)

@router.post("/upload-worker-timetable")
async def upload_worker_timetable(
    background_tasks: BackgroundTasks,
    file: UploadFile = File(...),
    user_node: str = Form(...),
    worker_node: str = Form(...)
):
    if file.content_type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
        raise HTTPException(status_code=422, detail="Invalid file format")
    
    try:
        worker_node_data = json.loads(worker_node)
        user_node_data = json.loads(user_node)
        logging.info(f"Uploading worker timetable for {worker_node_data['teacher_code']} from {file.filename} for {worker_node_data['worker_db_name']}")
        logging.debug(f"Worker node data: {worker_node_data}")
        logging.debug(f"User node data: {user_node_data}")

        # Read file content into memory
        file_content = await file.read()
        
        # Schedule the processing of the timetable in the background
        background_tasks.add_task(
            process_worker_timetable,
            file_content,
            user_node_data,
            worker_node_data
        )
        
        return {
            "status": "Accepted",
            "message": "Processing of teacher timetable started"
        }
    except Exception as e:
        logging.error(f"Error handling timetable upload: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

async def process_worker_timetable(file_content, user_node_data, worker_node_data):
    # Initialize neontology connection first
    neon.init_neontology_connection()
    
    neo_driver = driver.get_driver(db_name=worker_node_data['worker_db_name'])
    if neo_driver is None:
        logging.error(f"Failed to connect to the database {worker_node_data['worker_db_name']}")
        return
    
    try:
        # Create a DataFrame from the file content
        from io import BytesIO
        timetable_df = pd.read_excel(BytesIO(file_content))
        
        # Get the school version of the worker node
        logging.info(f"Getting school worker node for {worker_node_data['uuid_string']} from {worker_node_data['worker_db_name']}")
        
        with neo_driver.session(database=worker_node_data['worker_db_name']) as neo_session:
            school_worker_node = get_node_by_uuid_string(session=neo_session, uuid_string=worker_node_data['uuid_string'])
            
            if school_worker_node is None:
                error_msg = f"School worker node not found for uuid_string: {worker_node_data['uuid_string']}"
                logging.error(error_msg)
                raise Exception(error_msg)
                
            logging.debug(f"School worker node found: {school_worker_node}")
            
            # Create timetable in school database
            logging.info(f"Initializing worker timetable for school worker: {school_worker_node['teacher_code']}")
            init_worker_timetable.init_worker_timetable(timetable_df, school_worker_node)
            logging.info(f"Worker timetable initialized for school worker: {school_worker_node['teacher_code']}")
            
            # Create timetable in user database
            if 'user_db_name' in worker_node_data:
                from modules.database.init.init_user_timetable import create_user_worker_timetable
                from modules.database.schemas.nodes.workers.workers import TeacherNode
                
                logging.info(f"Creating user timetable structure in {worker_node_data['user_db_name']}")
                
                # Create TeacherNode from worker_node_data
                user_worker_node = TeacherNode(
                    uuid_string=worker_node_data['uuid_string'],
                    teacher_code=worker_node_data['teacher_code'],
                    teacher_name_formal=worker_node_data['teacher_name_formal'],
                    teacher_email=worker_node_data['teacher_email'],
                    node_storage_path=worker_node_data['node_storage_path'],
                    worker_db_name=worker_node_data['worker_db_name'],
                    user_db_name=worker_node_data['user_db_name']
                )
                
                # Create user node
                user_node = UserNode(
                    uuid_string=user_node_data['uuid_string'],
                    user_id=user_node_data['user_id'],
                    user_type=user_node_data['user_type'],
                    user_name=user_node_data['user_name'],
                    user_email=user_node_data['user_email'],
                    node_storage_path=user_node_data['node_storage_path'],
                    worker_node_data=user_node_data['worker_node_data']
                )
                
                # Create user timetable structure
                create_user_worker_timetable(
                    user_node=user_node,
                    user_worker_node=user_worker_node,
                    school_db_name=worker_node_data['worker_db_name']
                )

                logging.info(f"User timetable structure created in {worker_node_data['user_db_name']}")
            else:
                logging.warning("No user_db_name provided, skipping user timetable creation")
            
    except Exception as e:
        logging.error(f"Error processing worker timetable: {str(e)}")
        raise
    finally:
        logging.info(f"Closing driver for {worker_node_data['worker_db_name']}")
        driver.close_driver(neo_driver)

@router.get("/current-period")
async def get_current_period(user_id: str = ""):
    """Get the current active timetable period for a teacher.
    
    Queries Neo4j for Academic or Registration periods where now() falls
    between start_time and end_time for the given teacher's uuid_string.
    """
    if not user_id:
        return {
            "period_id": None,
            "event_type": None,
            "event_label": None,
            "start_time": None,
            "end_time": None,
        }
    
    # The user_id from Supabase JWT maps to the TeacherNode's uuid_string
    teacher_uuid = user_id
    
    # Try to find the current period across all known databases
    # First, try to get the user's database name from the UserNode
    neo_driver = driver.get_driver()
    if neo_driver is None:
        logging.error("Failed to connect to Neo4j for current-period query")
        return {
            "period_id": None,
            "event_type": None,
            "event_label": None,
            "start_time": None,
            "end_time": None,
        }
    
    try:
        # Query for the current period
        # Look for Teacher nodes with matching uuid_string that have relationships to Academic/Registration periods
        query = """
        MATCH (t:Teacher {uuid_string: $teacher_uuid})-[:HAS_PERIOD]->(p:AcademicPeriod|RegistrationPeriod)
        WHERE p.start_time <= datetime() AND p.end_time >= datetime()
        RETURN p.uuid_string AS period_id,
               p.name AS event_label,
               p.start_time AS start_time,
               p.end_time AS end_time,
               CASE WHEN p:AcademicPeriod THEN 'lesson' ELSE 'registration' END AS event_type
        ORDER BY p.start_time ASC
        LIMIT 1
        """
        
        with neo_driver.session() as session:
            result = session.run(query, teacher_uuid=teacher_uuid)
            record = result.single()
            
            if record:
                logging.info(f"Found current period for teacher {teacher_uuid}: {record['event_label']}")
                return {
                    "period_id": record["period_id"],
                    "event_type": record["event_type"],
                    "event_label": record["event_label"],
                    "start_time": str(record["start_time"]) if record["start_time"] else None,
                    "end_time": str(record["end_time"]) if record["end_time"] else None,
                }
            else:
                logging.info(f"No current period found for teacher {teacher_uuid}")
                return {
                    "period_id": None,
                    "event_type": None,
                    "event_label": None,
                    "start_time": None,
                    "end_time": None,
                }
    except Exception as e:
        logging.error(f"Error querying current period: {str(e)}")
        return {
            "period_id": None,
            "event_type": None,
            "event_label": None,
            "start_time": None,
            "end_time": None,
        }
    finally:
        driver.close_driver(neo_driver)
