from fastapi import Depends, HTTPException, Request
from sqlmodel import Session, select
from src.db.organization_config import OrganizationConfig
from src.db.organizations import Organization
from src.security.features_utils.usage import (
    check_limits_with_usage,
    increase_feature_usage,
)
from src.db.courses.courses import Course, CourseRead
from src.core.events.database import get_db_session
from src.db.users import PublicUser
from src.db.courses.activities import Activity, ActivityRead
from src.security.auth import get_current_user
from src.services.ai.base import ask_ai, get_chat_session_history

from src.services.ai.schemas.ai import (
    ActivityAIChatSessionResponse,
    SendActivityAIChatMessage,
    StartActivityAIChatSession,
)
from src.services.courses.activities.utils import (
    serialize_activity_text_to_ai_comprehensible_text,
    structure_activity_content_by_type,
)


def ai_start_activity_chat_session(
    request: Request,
    chat_session_object: StartActivityAIChatSession,
    current_user: PublicUser = Depends(get_current_user),
    db_session: Session = Depends(get_db_session),
) -> ActivityAIChatSessionResponse:
    """
    Start a new AI Chat session with a Course Activity
    """

    # Get the Activity
    statement = select(Activity).where(
        Activity.activity_uuid == chat_session_object.activity_uuid
    )
    activity = db_session.exec(statement).first()

    activity = ActivityRead.model_validate(activity)

    # Get the Course
    statement = (
        select(Course)
        .join(Activity)
        .where(Activity.activity_uuid == chat_session_object.activity_uuid)
    )
    course = db_session.exec(statement).first()
    course = CourseRead.model_validate(course)

    # Get the Organization
    statement = select(Organization).where(Organization.id == course.org_id)
    org = db_session.exec(statement).first()

    if not org or org.id is None:
        raise HTTPException(
            status_code=404,
            detail="Organization not found",
        )

    # Check limits and usage
    check_limits_with_usage("ai", org.id, db_session)
    increase_feature_usage("ai", org.id, db_session)

    if not activity:
        raise HTTPException(
            status_code=404,
            detail="Activity not found",
        )

    # Get Activity Content Blocks
    content = activity.content

    # Serialize Activity Content Blocks to a text comprehensible by the AI
    structured = structure_activity_content_by_type(content)

    isEmpty = structured == []

    ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text(
        structured, course, activity, isActivityEmpty=isEmpty
    )

    # Get Activity Organization
    statement = select(Organization).where(Organization.id == course.org_id)
    org = db_session.exec(statement).first()

    # Get Organization Config
    statement = select(OrganizationConfig).where(
        OrganizationConfig.org_id == org.id  # type: ignore
    )
    result = db_session.exec(statement)
    org_config = result.first()

    org_config = OrganizationConfig.model_validate(org_config)
    embeddings = "text-embedding-ada-002"
    ai_model = org_config.config["features"]["ai"]["model"]

    chat_session = get_chat_session_history()

    message = "You are a helpful Education Assistant, and you are helping a student with the associated Course. "
    message += "Use the available tools to get context about this question even if the question is not specific enough."
    message += "For context, this is the Course name :"
    message += course.name
    message += " and this is the Lecture name :"
    message += activity.name
    message += "."
    message += "Use your knowledge to help the student if the context is not enough."

    response = ask_ai(
        chat_session_object.message,
        chat_session["message_history"],
        ai_friendly_text,
        message,
        embeddings,
        ai_model,
    )

    return ActivityAIChatSessionResponse(
        aichat_uuid=chat_session["aichat_uuid"],
        activity_uuid=activity.activity_uuid,
        message=response["output"],
    )


def ai_send_activity_chat_message(
    request: Request,
    chat_session_object: SendActivityAIChatMessage,
    current_user: PublicUser = Depends(get_current_user),
    db_session: Session = Depends(get_db_session),
) -> ActivityAIChatSessionResponse:
    """
    Start a new AI Chat session with a Course Activity
    """
    # Get the Activity
    statement = select(Activity).where(
        Activity.activity_uuid == chat_session_object.activity_uuid
    )
    activity = db_session.exec(statement).first()

    activity = ActivityRead.model_validate(activity)

    # Get the Course
    statement = (
        select(Course)
        .join(Activity)
        .where(Activity.activity_uuid == chat_session_object.activity_uuid)
    )
    course = db_session.exec(statement).first()
    course = CourseRead.model_validate(course)

    # Get the Organization
    statement = select(Organization).where(Organization.id == course.org_id)
    org = db_session.exec(statement).first()

    # Check limits and usage
    check_limits_with_usage("ai", course.org_id, db_session)
    increase_feature_usage("ai", course.org_id, db_session)

    if not activity:
        raise HTTPException(
            status_code=404,
            detail="Activity not found",
        )

    # Get Activity Content Blocks
    content = activity.content

    # Serialize Activity Content Blocks to a text comprehensible by the AI
    structured = structure_activity_content_by_type(content)
    ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text(
        structured, course, activity
    )

    # Get Activity Organization
    statement = select(Organization).where(Organization.id == course.org_id)
    org = db_session.exec(statement).first()

    # Get Organization Config
    statement = select(OrganizationConfig).where(
        OrganizationConfig.org_id == org.id  # type: ignore
    )
    result = db_session.exec(statement)
    org_config = result.first()

    org_config = OrganizationConfig.model_validate(org_config)
    embeddings = "text-embedding-ada-002"
    ai_model = org_config.config["features"]["ai"]["model"]

    chat_session = get_chat_session_history(chat_session_object.aichat_uuid)

    message = "You are a helpful Education Assistant, and you are helping a student with the associated Course. "
    message += "Use the available tools to get context about this question even if the question is not specific enough."
    message += "For context, this is the Course name :"
    message += course.name
    message += " and this is the Lecture name :"
    message += activity.name
    message += "."
    message += "Use your knowledge to help the student if the context is not enough."

    response = ask_ai(
        chat_session_object.message,
        chat_session["message_history"],
        ai_friendly_text,
        message,
        embeddings,
        ai_model,
    )

    return ActivityAIChatSessionResponse(
        aichat_uuid=chat_session["aichat_uuid"],
        activity_uuid=activity.activity_uuid,
        message=response["output"],
    )
