from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query, Request, status
from fastapi.responses import FileResponse

from app.api.deps import CurrentUserContext, get_current_user, require_admin_user
from app.schemas.knowledge import (
    KnowledgeActionResponse,
    KnowledgeDocumentDetailRead,
    KnowledgeLibraryRead,
    KnowledgeOnlyOfficeCallbackRead,
    KnowledgeOnlyOfficeConfigRead,
)
from app.services.knowledge import KnowledgeService

router = APIRouter(prefix="/knowledge")


@router.get("/library", response_model=KnowledgeLibraryRead)
def get_knowledge_library(
    _: Annotated[CurrentUserContext, Depends(get_current_user)],
) -> KnowledgeLibraryRead:
    return KnowledgeService().list_library()


@router.get("/documents/{document_id}", response_model=KnowledgeDocumentDetailRead)
def get_knowledge_document(
    document_id: str,
    _: Annotated[CurrentUserContext, Depends(get_current_user)],
) -> KnowledgeDocumentDetailRead:
    try:
        return KnowledgeService().get_document_detail(document_id)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc


@router.get("/documents/{document_id}/onlyoffice-config", response_model=KnowledgeOnlyOfficeConfigRead)
def get_knowledge_document_onlyoffice_config(
    document_id: str,
    current_user: Annotated[CurrentUserContext, Depends(get_current_user)],
) -> KnowledgeOnlyOfficeConfigRead:
    try:
        return KnowledgeService().build_onlyoffice_config(document_id, current_user)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc


@router.post("/documents", response_model=KnowledgeDocumentDetailRead, status_code=status.HTTP_201_CREATED)
async def upload_knowledge_document(
    request: Request,
    folder: Annotated[str, Query(min_length=1)],
    filename: Annotated[str, Query(min_length=1)],
    current_user: Annotated[CurrentUserContext, Depends(require_admin_user)],
) -> KnowledgeDocumentDetailRead:
    content = await request.body()
    try:
        return KnowledgeService().upload_document(folder, filename, content, current_user)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc


@router.delete("/documents/{document_id}", response_model=KnowledgeActionResponse)
def delete_knowledge_document(
    document_id: str,
    _: Annotated[CurrentUserContext, Depends(require_admin_user)],
) -> KnowledgeActionResponse:
    try:
        KnowledgeService().delete_document(document_id)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc

    return KnowledgeActionResponse(detail="知识库文件已删除。")


@router.get("/documents/{document_id}/content")
def get_knowledge_document_content(
    document_id: str,
    disposition: Annotated[str, Query(pattern="^(inline|attachment)$")] = "inline",
    _: Annotated[CurrentUserContext, Depends(get_current_user)] = None,
) -> FileResponse:
    try:
        file_path, media_type, filename = KnowledgeService().get_document_content(document_id)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc

    _ = disposition
    return FileResponse(file_path, media_type=media_type, filename=filename)


@router.get("/documents/{document_id}/onlyoffice/content")
def get_knowledge_document_onlyoffice_content(
    document_id: str,
    access_token: Annotated[str, Query(min_length=1)],
) -> FileResponse:
    try:
        service = KnowledgeService()
        service.validate_onlyoffice_access_token(document_id, access_token)
        file_path, media_type, filename = service.get_document_content(document_id)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(exc)) from exc

    return FileResponse(file_path, media_type=media_type, filename=filename)


@router.post("/documents/{document_id}/onlyoffice/callback", response_model=KnowledgeOnlyOfficeCallbackRead)
async def handle_knowledge_document_onlyoffice_callback(
    document_id: str,
    request: Request,
) -> KnowledgeOnlyOfficeCallbackRead:
    payload = await request.json()
    try:
        KnowledgeService().handle_onlyoffice_callback(document_id, payload)
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="知识库文件不存在。") from exc
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc

    return KnowledgeOnlyOfficeCallbackRead()
