from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy.orm import Session

from app.api.deps import get_current_user
from app.api.permissions import require_permission, require_read
from app.core.exceptions import DocumentNotFoundError
from app.core.i18n import get_translator
from app.db.session import get_db
from app.models import KnowledgeBase, KnowledgeCategory, KnowledgeDocument, Model, User
from common_logging import get_logger

logger = get_logger(__name__)
router = APIRouter()


@router.get("/documents/{document_id}/vectorization-status")
def get_vectorization_status(
    request: Request,
    document_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_read("knowledge_bases")),
):
    from app.services.knowledge.vectorization_task_manager import get_task_manager

    get_translator(request)
    doc = db.query(KnowledgeDocument).filter(KnowledgeDocument.id == document_id).first()
    if not doc:
        raise DocumentNotFoundError(document_id)
    task_manager = get_task_manager()
    task = task_manager.get_task(document_id)
    if task:
        return task.to_dict()
    else:
        return {
            "document_id": document_id,
            "status": "completed" if doc.is_vectorized else "not_started",
            "progress": 100.0 if doc.is_vectorized else 0.0,
            "is_vectorized": doc.is_vectorized,
            "vector_model": doc.vector_model,
        }


@router.get("/vectorization-tasks")
def get_all_vectorization_tasks(
    db: Session = Depends(get_db), current_user: User = Depends(require_read("knowledge_bases"))
):
    from app.services.knowledge.vectorization_task_manager import get_task_manager

    task_manager = get_task_manager()
    all_tasks = task_manager.get_all_tasks()
    if current_user.role in ["platform_admin", "platform_user"]:
        filtered_tasks = all_tasks
    else:
        filtered_tasks = []
        for task in all_tasks:
            doc = (
                db.query(KnowledgeDocument)
                .filter(KnowledgeDocument.id == task.get("document_id"))
                .first()
            )
            if doc:
                filtered_tasks.append(task)
    return {"tasks": filtered_tasks, "total": len(filtered_tasks)}


@router.post("/documents/{document_id}/vectorize")
def vectorize_document(
    request: Request,
    document_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
    _: None = Depends(require_permission("knowledge_bases", "update")),
):
    from app.services.rag.async_vectorization_service import AsyncVectorizationService
    from app.services.storage.vector_store_factory import get_vector_store

    t = get_translator(request)
    doc = db.query(KnowledgeDocument).filter(KnowledgeDocument.id == document_id).first()
    if not doc:
        raise DocumentNotFoundError(document_id)
    category = db.query(KnowledgeCategory).filter(KnowledgeCategory.id == doc.category_id).first()
    if not category:
        raise HTTPException(status_code=400, detail=t.t("knowledge.document_no_category"))
    knowledge_base_id = category.knowledge_base_id
    kb = db.query(KnowledgeBase).filter(KnowledgeBase.id == knowledge_base_id).first()
    if not kb or not kb.code:
        raise HTTPException(status_code=400, detail=t.t("knowledge.kb_vector_model_not_configured"))
    if kb.code.isdigit():
        vector_model = db.query(Model).filter(Model.id == int(kb.code)).first()
    else:
        vector_model = db.query(Model).filter(Model.code == kb.code).first()
    if not vector_model:
        raise HTTPException(status_code=400, detail=t.t("knowledge.vector_model_not_found"))
    if doc.is_vectorized:
        try:
            vector_store = get_vector_store(db, knowledge_base_id=knowledge_base_id)
            vector_store.delete_document_vectors(document_id)
            logger.info(f"Deleted old vectors for document {document_id}")
        except Exception as e:
            logger.warning(f"Failed to delete old vectors: {e}")
    doc.is_vectorized = False
    doc.vectorization_status = "pending"
    db.commit()
    try:
        AsyncVectorizationService.vectorize_document_async(
            document_id=document_id,
            model_id=vector_model.id,
            chunk_size=doc.chunk_size if hasattr(doc, "chunk_size") else None,
            chunk_overlap=doc.chunk_overlap if hasattr(doc, "chunk_overlap") else None,
            splitter_type=doc.segmentation_mode if hasattr(doc, "segmentation_mode") else None,
        )
        logger.info("Vectorization task created", task_id=document_id)
        return {
            "success": True,
            "message": t.t("knowledge.vectorization_started"),
            "document_id": document_id,
            "status": "pending",
        }
    except Exception as e:
        logger.error(f"Failed to start vectorization task: {e}".opt(exception=True))
        doc.vectorization_status = "failed"
        db.commit()
        raise HTTPException(
            status_code=500, detail=t.t("knowledge.vectorization_failed", error=str(e))
        ) from e


@router.get("/documents/{document_id}/vectorize/progress")
def get_vectorization_progress(
    document_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_read("knowledge_bases")),
):
    from app.services.knowledge.vectorization_task_manager import get_task_manager

    doc = db.query(KnowledgeDocument).filter(KnowledgeDocument.id == document_id).first()
    if not doc:
        raise DocumentNotFoundError(document_id)
    task_manager = get_task_manager()
    task = task_manager.get_task(document_id)
    if not task:
        doc = db.query(KnowledgeDocument).filter(KnowledgeDocument.id == document_id).first()
        if doc and doc.is_vectorized:
            return {
                "status": "completed",
                "progress": 100,
                "total_chunks": 0,
                "completed_chunks": 0,
            }
        return {"status": "not_started", "progress": 0, "total_chunks": 0, "completed_chunks": 0}
    return task.to_dict()


@router.post("/documents/vectorize-all")
def vectorize_all_documents(
    request: Request,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
    _: None = Depends(require_permission("knowledge_bases", "update")),
):
    t = get_translator(request)
    query = db.query(KnowledgeDocument).filter(not KnowledgeDocument.is_vectorized)
    if current_user.role == "customer_user":
        query = query.filter(KnowledgeDocument.author_id == current_user.id)
    not_vectorized_docs = query.all()
    if not not_vectorized_docs:
        return {
            "success": True,
            "message": t.t("knowledge.all_documents_vectorized"),
            "total": 0,
            "success_count": 0,
            "failed_count": 0,
        }
    success_count = 0
    failed_count = 0
    failed_docs = []
    for doc in not_vectorized_docs:
        try:
            vectorize_document(request, doc.id, db, current_user)
            success_count += 1
        except Exception as e:
            failed_count += 1
            failed_docs.append({"id": doc.id, "title": doc.title, "error": str(e)})
            logger.error(f"Failed to vectorize document {doc.id}: {e}")
    return {
        "success": True,
        "message": t.t("knowledge.batch_vectorization_complete"),
        "total": len(not_vectorized_docs),
        "success_count": success_count,
        "failed_count": failed_count,
        "failed_docs": failed_docs,
    }


@router.post("/documents/batch-vectorize")
def batch_vectorize_documents(
    request: Request,
    document_ids: list[int],
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
    _: None = Depends(require_permission("knowledge_bases", "update")),
):
    t = get_translator(request)
    if not document_ids:
        raise HTTPException(status_code=400, detail=t.t("knowledge.no_documents_specified"))
    success_count = 0
    failed_count = 0
    skipped_count = 0
    results = []
    for doc_id in document_ids:
        try:
            doc = db.query(KnowledgeDocument).filter(KnowledgeDocument.id == doc_id).first()
            if not doc:
                failed_count += 1
                results.append(
                    {"id": doc_id, "success": False, "error": t.t("knowledge.document_not_found")}
                )
                continue
            if doc.is_vectorized:
                skipped_count += 1
                results.append(
                    {
                        "id": doc_id,
                        "title": doc.title,
                        "success": True,
                        "skipped": True,
                        "message": t.t("knowledge.already_vectorized"),
                    }
                )
                continue
            result = vectorize_document(request, doc_id, db, current_user)
            success_count += 1
            results.append(
                {
                    "id": doc_id,
                    "title": doc.title,
                    "success": True,
                    "skipped": False,
                    "chunks": result.get("chunks", 0),
                    "vectorized": result.get("vectorized", 0),
                }
            )
        except Exception as e:
            failed_count += 1
            results.append({"id": doc_id, "success": False, "error": str(e)})
            logger.error(f"Failed to vectorize document {doc_id}: {e}")
    return {
        "success": True,
        "message": t.t("knowledge.batch_vectorization_complete"),
        "total": len(document_ids),
        "success_count": success_count,
        "failed_count": failed_count,
        "skipped_count": skipped_count,
        "results": results,
    }
