"""Document operations adapter."""

from __future__ import annotations

from ragflow_sdk.modules.dataset import DataSet
from ragflow_sdk.modules.document import Document


class DocumentClient:
    def list_docs(
        self,
        dataset: DataSet,
        name: str | None = None,
        keywords: str | None = None,
        page: int = 1,
        page_size: int = 1000,
        doc_id: str | None = None,
        metadata_condition: str | None = None,
    ) -> list[Document]:
        if metadata_condition is not None:
            # SDK's list_documents() doesn't expose metadata_condition,
            # so use low-level GET with the JSON string as a query param.
            params = {
                "id": doc_id,
                "name": name,
                "keywords": keywords,
                "page": page,
                "page_size": page_size,
                "metadata_condition": metadata_condition,
            }
            res = dataset.get(f"/datasets/{dataset.id}/documents", params=params)
            res = res.json()
            if res.get("code") == 0:
                return [Document(dataset.rag, d) for d in res["data"].get("docs", [])]
            raise Exception(res.get("message", "Unknown error"))
        return dataset.list_documents(
            id=doc_id,
            name=name,
            keywords=keywords,
            page=page,
            page_size=page_size,
        )

    def download_content(self, doc: Document) -> str:
        try:
            raw = doc.download()
            return raw.decode("utf-8")
        except Exception as exc:
            raise RuntimeError(f"Failed to download content for document {doc.id}: {exc}") from exc

    def upload_doc(self, dataset: DataSet, name: str, content: bytes) -> Document:
        docs = dataset.upload_documents([{"display_name": name, "blob": content}])
        if not docs:
            raise RuntimeError("Upload returned no documents")
        return docs[0]

    def upsert_doc(
        self,
        dataset: DataSet,
        name: str,
        content: bytes,
        meta_fields: dict | None = None,
    ) -> Document:
        existing = self.list_docs(dataset=dataset, name=name, page_size=1)
        if existing:
            dataset.delete_documents([existing[0].id])
        uploaded = self.upload_doc(dataset=dataset, name=name, content=content)
        if meta_fields:
            uploaded.update({"meta_fields": meta_fields})
        return uploaded
