import json
import os
from pathlib import Path
from typing import Any, Dict, Optional
from ..models import Document
from .base import BaseResource

class DocumentsResource(BaseResource):
    def upload(
        self,
        collection_id: str,
        file_path: str,
        external_metadata: Optional[Dict[str, Any]] = None,
    ) -> Document:
        path = Path(file_path)
        with open(path, "rb") as f:
            files = {"file": (path.name, f)}
            data = {}
            if external_metadata:
                data["external_metadata"] = json.dumps(external_metadata)
            result = self._request(
                "POST",
                f"/api/v1/sdk/collections/{collection_id}/documents",
                files=files,
                data=data,
            )
        return Document(**result)

    def get(self, document_id: str) -> Document:
        data = self._request("GET", f"/api/v1/sdk/documents/{document_id}")
        return Document(**data)

    def update_metadata(
        self, document_id: str, external_metadata: Dict[str, Any]
    ) -> Document:
        data = self._request(
            "PUT",
            f"/api/v1/sdk/documents/{document_id}/metadata",
            json={"external_metadata": external_metadata},
        )
        return Document(**data)

    def download(self, document_id: str, output_path: str) -> str:
        response = self._client.get(
            f"/api/v1/sdk/documents/{document_id}/download"
        )
        if response.status_code >= 400:
            from ..exceptions import DocufastError
            raise DocufastError(f"Download failed: {response.status_code}", status_code=response.status_code)
        os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
        with open(output_path, "wb") as f:
            f.write(response.content)
        return output_path

    def delete(self, document_id: str) -> dict:
        return self._request("DELETE", f"/api/v1/sdk/documents/{document_id}")
