from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Depends, Query, status
from fastapi.responses import JSONResponse
from app.backend.db.database import get_db
from sqlalchemy.orm import Session
from app.backend.schemas import UserLogin, CourseList, StoreCourse, UpdateCourse
from app.backend.classes.course_class import CourseClass
from app.backend.classes.inspection_api_client import InspectionApiClient
from app.backend.classes.school_class import SchoolClass
from app.backend.classes.teaching_class import _normalize_school_id
from sqlalchemy import or_
from app.backend.db.models import (
    CourseModel,
    ProfessionalModel,
    ProfessionalTeachingCourseModel,
    SchoolModel,
    UserModel,
)
from app.backend.auth.auth_user import get_current_active_user

courses = APIRouter(
    prefix="/courses",
    tags=["Courses"]
)

def _course_period_year(course: CourseList, period_year_query: Optional[int]) -> Optional[int]:
    """Prioriza query (interceptor/cookie); si no, body CourseList."""
    if period_year_query is not None:
        return period_year_query
    return getattr(course, "period_year", None)


@courses.post("/")
def index(
    course: CourseList,
    period_year: Optional[int] = Query(None, ge=2000, le=2100, description="Año período escolar"),
    session_user: UserLogin = Depends(get_current_active_user),
    db: Session = Depends(get_db),
):
    # Obtener school_id del customer_id del usuario en sesión
    customer_id = session_user.customer_id if session_user else None
    school_id = session_user.school_id if session_user else None
    
    if customer_id and not school_id:
        schools_list = SchoolClass(db).get_all(page=0, customer_id=customer_id)
        if isinstance(schools_list, list) and len(schools_list) > 0:
            school_id = schools_list[0].get('id')
    
    # Si el usuario es profesional, buscar sus cursos en professionals_teachings_courses
    professional_course_ids = []
    if session_user.rut and school_id:
        user_row = (
            db.query(UserModel)
            .filter(
                UserModel.rut == session_user.rut,
                or_(UserModel.deleted_status_id == 0, UserModel.deleted_status_id.is_(None)),
            )
            .first()
        )
        if user_row:
            prof_pk = (
                db.query(ProfessionalModel.id)
                .filter(ProfessionalModel.user_id == user_row.id)
                .order_by(ProfessionalModel.id.desc())
                .first()
            )
            pid = int(prof_pk[0]) if prof_pk else None

            if pid is not None:
                ptc_records = db.query(ProfessionalTeachingCourseModel).filter(
                    ProfessionalTeachingCourseModel.professional_id == pid,
                    ProfessionalTeachingCourseModel.deleted_status_id == 0
                ).all()
                professional_course_ids = [ptc.course_id for ptc in ptc_records]

    py = _course_period_year(course, period_year)

    # Si el profesional tiene cursos asignados, filtrar solo esos cursos
    if professional_course_ids:
        page_value = 0 if course.page is None else course.page
        # NO filtrar por school_id cuando es profesional, ya que sus cursos pueden estar en cualquier escuela
        all_courses = CourseClass(db).get_all(
            page=page_value,
            items_per_page=course.per_page,
            school_id=None,
            period_year=py,
        )

        # Filtrar solo los cursos del profesional
        if isinstance(all_courses, list):
            course_data = [c for c in all_courses if c.get('id') in professional_course_ids]
            return JSONResponse(
                status_code=status.HTTP_200_OK,
                content={
                    "status": 200,
                    "message": "Courses retrieved successfully",
                    "data": course_data
                }
            )
        elif isinstance(all_courses, dict) and 'data' in all_courses:
            available_course_ids = [c.get('id') for c in all_courses['data']]
            course_data = [c for c in all_courses['data'] if c.get('id') in professional_course_ids]
            return JSONResponse(
                status_code=status.HTTP_200_OK,
                content={
                    "status": 200,
                    "message": "Courses retrieved successfully",
                    "data": {
                        "total_items": len(course_data),
                        "total_pages": 1 if len(course_data) > 0 else 0,
                        "current_page": all_courses.get('current_page', 1),
                        "items_per_page": course.per_page,
                        "data": course_data
                    }
                }
            )
    
    # Si no hay school_id, devolver array vacío
    if school_id is None:
        message = "Complete courses list retrieved successfully" if course.page is None else "Courses retrieved successfully"
        return JSONResponse(
            status_code=status.HTTP_200_OK,
            content={
                "status": 200,
                "message": message,
                "data": [] if course.page is None else {
                    "total_items": 0,
                    "total_pages": 0,
                    "current_page": course.page if course.page else 1,
                    "items_per_page": course.per_page,
                    "data": []
                }
            }
        )
    
    page_value = 0 if course.page is None else course.page
    result = CourseClass(db).get_all(
        page=page_value,
        items_per_page=course.per_page,
        course=course.course_name,
        teaching_id=course.teaching_id,
        school_id=school_id,
        period_year=py,
    )

    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_404_NOT_FOUND,
            content={
                "status": 404,
                "message": result.get("message", "Error"),
                "data": None
            }
        )
        
    message = "Complete courses list retrieved successfully" if course.page is None else "Courses retrieved successfully"
    
    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": message,
            "data": result
        }
    )

@courses.get("/list")
def get_all_list(
    teaching_id: int = None,
    period_year: Optional[int] = Query(None, ge=2000, le=2100, description="Año período escolar"),
    school_id: Optional[int] = Query(
        None,
        description="Colegio explícito (p. ej. estudiante). Debe pertenecer al customer de la sesión, o sesión sin customer (admin).",
    ),
    session_user: UserLogin = Depends(get_current_active_user),
    db: Session = Depends(get_db),
):
    customer_id = session_user.customer_id if session_user else None
    effective_school_id = session_user.school_id if session_user else None

    # Override / fijar colegio cuando la sesión no trae school_id (p. ej. administrador editando estudiante)
    if school_id is not None:
        sch = (
            db.query(SchoolModel)
            .filter(SchoolModel.id == int(school_id), SchoolModel.deleted_status_id == 0)
            .first()
        )
        if sch:
            cust = getattr(sch, "customer_id", None)
            if customer_id is None or (cust is not None and int(cust) == int(customer_id)):
                effective_school_id = sch.id

    if effective_school_id is None and customer_id:
        schools_list = SchoolClass(db).get_all(page=0, customer_id=customer_id)
        if isinstance(schools_list, list) and len(schools_list) > 0:
            effective_school_id = schools_list[0].get("id")

    if effective_school_id is None:
        return JSONResponse(
            status_code=status.HTTP_200_OK,
            content={
                "status": 200,
                "message": "Courses list retrieved successfully",
                "data": [],
            },
        )

    result = CourseClass(db).get_all_list(
        school_id=effective_school_id, teaching_id=teaching_id, period_year=period_year
    )

    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_404_NOT_FOUND,
            content={
                "status": 404,
                "message": result.get("message", "Error"),
                "data": None
            }
        )
    
    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": "Courses list retrieved successfully",
            "data": result
        }
    )


def _resolve_session_school_id(session_user, db: Session) -> Optional[int]:
    customer_id = session_user.customer_id if session_user else None
    school_id = session_user.school_id if session_user else None
    if customer_id and not school_id:
        schools_list = SchoolClass(db).get_all(page=0, customer_id=customer_id)
        if isinstance(schools_list, list) and len(schools_list) > 0:
            school_id = schools_list[0].get("id")
    return _normalize_school_id(school_id)


@courses.post("/import_from_inspection")
def import_from_inspection(
    period_year: Optional[int] = Query(None, ge=2000, le=2100, description="Año escolar para Inspection y period_year"),
    session_user: UserLogin = Depends(get_current_active_user),
    db: Session = Depends(get_db),
):
    school_id = _resolve_session_school_id(session_user, db)
    if school_id is None:
        return JSONResponse(
            status_code=status.HTTP_400_BAD_REQUEST,
            content={
                "status": 400,
                "message": "No se pudo determinar el colegio (school_id) de la sesión",
                "data": None,
            },
        )

    client = InspectionApiClient()
    if not client.is_configured():
        return JSONResponse(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            content={
                "status": 503,
                "message": "Inspection API not configured (INSPECTION_API_USERNAME / INSPECTION_API_PASSWORD)",
                "data": None,
            },
        )

    anio = int(period_year) if period_year is not None else datetime.now().year
    remote = client.fetch_courses_list(colegio_id=school_id, anio=anio)
    if not remote.get("ok"):
        return JSONResponse(
            status_code=status.HTTP_502_BAD_GATEWAY,
            content={
                "status": 502,
                "message": remote.get("message") or "Error al obtener cursos desde Inspection",
                "data": remote,
            },
        )

    result = CourseClass(db).import_from_inspection(school_id, remote, anio)
    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content={
                "status": 500,
                "message": result.get("message", "Error al importar cursos"),
                "data": None,
            },
        )

    imported = result.get("imported", 0)
    skipped = result.get("skipped", 0)
    msg = f"Importación de cursos finalizada: {imported} nuevos, {skipped} omitidos (duplicados o sin datos)."
    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": msg,
            "data": result,
        },
    )


@courses.post("/store")
def store(
    course: StoreCourse,
    period_year: Optional[int] = Query(None, ge=2000, le=2100, description="Año período escolar"),
    session_user: UserLogin = Depends(get_current_active_user),
    db: Session = Depends(get_db),
):
    course_inputs = course.model_dump() if hasattr(course, "model_dump") else course.dict()
    if period_year is not None:
        course_inputs["period_year"] = period_year
    elif course_inputs.get("period_year") is None:
        pass
    
    # Obtener school_id del customer_id del usuario en sesión
    customer_id = session_user.customer_id if session_user else None
    school_id = None
    if customer_id:
        schools_list = SchoolClass(db).get_all(page=0, customer_id=customer_id)
        if isinstance(schools_list, list) and len(schools_list) > 0:
            school_id = schools_list[0].get('id')
    
    # Agregar school_id a course_inputs
    course_inputs['school_id'] = school_id
    
    result = CourseClass(db).store(course_inputs)

    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content={
                "status": 500,
                "message": result.get("message", "Error creating course"),
                "data": None
            }
        )

    return JSONResponse(
        status_code=status.HTTP_201_CREATED,
        content={
            "status": 201,
            "message": "Course created successfully",
            "data": result
        }
    )

@courses.get("/edit/{id}")
def edit(
    id: int,
    period_year: Optional[int] = Query(None, ge=2000, le=2100, description="Año período escolar"),
    session_user: UserLogin = Depends(get_current_active_user),
    db: Session = Depends(get_db),
):
    result = CourseClass(db).get(id, period_year)

    if isinstance(result, dict) and (result.get("error") or result.get("status") == "error"):
        return JSONResponse(
            status_code=status.HTTP_404_NOT_FOUND,
            content={
                "status": 404,
                "message": result.get("error") or result.get("message", "Course not found"),
                "data": None
            }
        )

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": "Course retrieved successfully",
            "data": result
        }
    )

@courses.put("/update/{id}")
def update(id: int, course: UpdateCourse, session_user: UserLogin = Depends(get_current_active_user), db: Session = Depends(get_db)):
    course_inputs = course.dict(exclude_unset=True)
    
    # Obtener school_id del customer_id del usuario en sesión
    customer_id = session_user.customer_id if session_user else None
    school_id = None
    if customer_id:
        schools_list = SchoolClass(db).get_all(page=0, customer_id=customer_id)
        if isinstance(schools_list, list) and len(schools_list) > 0:
            school_id = schools_list[0].get('id')
    
    # Agregar school_id a course_inputs si no está presente
    if 'school_id' not in course_inputs:
        course_inputs['school_id'] = school_id
    
    result = CourseClass(db).update(id, course_inputs)

    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content={
                "status": 500,
                "message": result.get("message", "Error updating course"),
                "data": None
            }
        )

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": "Course updated successfully",
            "data": result
        }
    )

@courses.delete("/delete/{id}")
def delete(id: int, session_user: UserLogin = Depends(get_current_active_user), db: Session = Depends(get_db)):
    result = CourseClass(db).delete(id)

    if isinstance(result, dict) and result.get("status") == "error":
        return JSONResponse(
            status_code=status.HTTP_404_NOT_FOUND,
            content={
                "status": 404,
                "message": result.get("message", "Course not found"),
                "data": None
            }
        )

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "status": 200,
            "message": "Course deleted successfully",
            "data": result
        }
    )
