"docchat router"

import os

# from utils.XCM_logger import ServiceLogger
import logging
from typing import Annotated, List

from fastapi import (
    APIRouter,
    Body,
    Depends,
    File,
    HTTPException,
    Query,
    Request,
    Body,
    UploadFile,
    status,
)

from services.ppt_generator.data_classes.project import Project
from services.team_services import TeamService
from utils.chat.index import ChatDocumentUploader
from utils.mysql_db import mysql_db
from utils.document_loader.DocUploaderV2 import DocUploaderV2
from schemas.chat import (
    ChatMessageCreate,
    ChatMessageResponse,
    ChatSessionCreate,
    ChatSessionResponse,
    UpdateChatSessionPayload,
)

from controllers.presentation import get_team_config_data
from services.docchat.chatService import ChatService
from utils.s3_storage import S3BucketStorage, get_default_bucket_name

XCM_logger = logging.getLogger()


chat = APIRouter(
    prefix="/docchat",
    tags=["docchat"],
    responses={404: {"description": "Not found"}},
    dependencies=[],  # add dependencies here
)


@chat.post("/upload_and_process_files")
async def upload_and_process_files(
    files: List[UploadFile] = File(...),
    project_id: str = Body(...),
    team_id: str = Body(...),
):
    "Upload provided files to the project."

    try:

        if not files:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="No files provided for upload",
            )

        team_service = TeamService()
        team = team_service.get_team_by_id(team_id)

        if not team:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND, detail="Team not found"
            )
        project = Project.check_project_in_db(project_id=project_id)

        if not project:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND, detail="Project not found"
            )

        try:

            uploadedFiles = DocUploaderV2(project=project, team=team, files=files)
            await uploadedFiles.store_on_s3(files, nested_path="chat")

            client_config = get_team_config_data(team_id)
            chat_document_uploader = ChatDocumentUploader(project, client_config)
            chat_document_uploader.doc_upload_call_to_chromadb(
                nested_path="chat",
                team_id=team_id,
            )
            return {
                "message": "Files uploaded successfully",
                "results": uploadedFiles.get_uploaded_files(),
            }
        except Exception as e:
            XCM_logger.error(e)
            raise HTTPException(status_code=400, detail={"message": str(e)}) from e

    except Exception as e:
        XCM_logger.error(e)
        raise HTTPException(status_code=400, detail={"message": str(e)})


@chat.get("/project/{project_id}/get_files")
async def get_project_files(project_id: str, team_id: str = Query(None)):
    "Get the files in a project"
    xcap_s3_storage = get_default_bucket_name()
    s3_storage = S3BucketStorage(bucket_name=xcap_s3_storage)
    return s3_storage.get_files_in_folder(project_id, team_id, "chat")


@chat.post("/chat/session/new")
async def create_chat_session(
    request: Request,
    project_id: str = Body(...),
    team_id: str = Body(...),
    selected_files: List[str] = Body(...),
):
    "Create a new chat session"
    try:
        current_user = request.state.current_user

        return await ChatService.create_chat_session(
            mysql_db, current_user, project_id, team_id, selected_files
        )
    except Exception as e:
        print(e)
        XCM_logger.error(e)
        raise HTTPException(status_code=400, detail={"message": str(e)}) from e


@chat.get("/chat/session/all")
async def get_all_sessions(request: Request, project_id: str, team_id: str):
    "Get all sessions for a user"
    current_user = request.state.current_user
    sessions = await ChatService.get_all_sessions_for_user(
        mysql_db, current_user, project_id, team_id
    )

    return {
        "sessions": sessions,
    }


@chat.get("/chat/session/latest")
async def get_latest_session(request: Request, project_id: str, team_id: str):
    "Get the latest session for a user"
    try:
        current_user = request.state.current_user
        return await ChatService.get_latest_session_for_user(
            mysql_db, current_user, project_id, team_id
        )
    except Exception as e:
        print(e)
        XCM_logger.error(e)
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail={"message": str(e)}
        ) from e


@chat.get("/chat/session/{session_id}/messages")
async def get_messages_for_session(session_id: str, offset: int = 0, limit: int = 10):
    "Get all sessions for a user"
    try:
        messages = await ChatService.get_messages_for_session(
            mysql_db, session_id, offset, limit
        )
        has_more = len(messages) == limit
        return {
            "messages": messages,
            "offset": offset + limit,
            "limit": limit,
            "has_more": has_more,
        }
    except Exception as e:
        print(e)
        XCM_logger.error(e)
        raise HTTPException(status_code=400, detail={"message": str(e)}) from e


@chat.post("/chat/session/{session_id}/end")
async def end_chat_session(request: Request, session_id: str):
    "End a chat session"
    try:
        current_user = request.state.current_user
        session = await ChatService.end_chat_session(mysql_db, session_id, current_user)
        return {"message": "Chat session ended", "session": session}
    except Exception as e:
        print(e)
        XCM_logger.error(e)
        raise HTTPException(status_code=400, detail={"message": str(e)}) from e


@chat.post("/chat/session/{session_id}/update")
async def update_chat_session(
    request: Request, session_id: str, payload: UpdateChatSessionPayload
):
    "Update a chat session"
    try:
        current_user = request.state.current_user
        session = await ChatService.update_chat_session(
            mysql_db, session_id, payload, current_user
        )
        return {"message": "Chat session updated", "session": session}
    except Exception as e:
        print(e)
        XCM_logger.error(e)
        raise HTTPException(status_code=400, detail={"message": str(e)}) from e
