"""
Artifacts API
"""

from typing import Optional, Dict, Any, Union
from pathlib import Path
from io import BytesIO
from .base import BaseAPI


class ArtifactsAPI(BaseAPI):
    """Model artifact endpoints"""
    
    def list(
        self,
        model_id: Optional[int] = None,
        page: int = 1,
        page_size: int = 20,
    ) -> Dict[str, Any]:
        """List artifacts"""
        params = {"page": page, "page_size": min(page_size, 100)}
        if model_id:
            params["model_id"] = model_id
        return self.client._request("GET", "model-artifacts/", params=params)
    
    def get(self, artifact_id: int) -> Dict[str, Any]:
        """Get artifact by ID"""
        return self.client._request("GET", f"model-artifacts/{artifact_id}")
    
    def upload(
        self,
        file_path: Union[str, Path],
        model_id: int,
        run_id: int,
        artifact_type: str = "tflite",
        framework: str = "tensorflow",
        target_device: str = "CPU",
        is_default: bool = True,
        storage_path: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Upload model artifact file to MinIO and create DB record."""
        path = Path(file_path)
        if not path.exists():
            raise FileNotFoundError(f"File not found: {path}")
        filename = path.name
        file_bytes = path.read_bytes()
        # multipart: file + form fields (requests expects file-like for upload)
        files = {"file": (filename, BytesIO(file_bytes), "application/octet-stream")}
        data = {
            "model_id": model_id,
            "run_id": run_id,
            "artifact_type": artifact_type,
            "framework": framework,
            "target_device": target_device,
            "is_default": is_default,
        }
        if storage_path:
            data["storage_path"] = storage_path
        return self.client._request(
            "POST",
            "model-artifacts/upload",
            data=data,
            files=files,
        )
    
    def create(
        self,
        model_id: int,
        run_id: int,
        artifact_type: str,
        framework: str,
        file_path: str,
        file_size_mb: float,
        checksum: str,
        target_device: str = "CPU",
        is_default: bool = False,
    ) -> Dict[str, Any]:
        """Create artifact metadata only (no file upload). Prefer upload() to upload file to MinIO."""
        data = {
            "model_id": model_id,
            "run_id": run_id,
            "artifact_type": artifact_type,
            "framework": framework,
            "file_path": file_path,
            "file_size_mb": file_size_mb,
            "checksum": checksum,
            "target_device": target_device,
            "is_default": is_default,
        }
        return self.client._request("POST", "model-artifacts/", json=data)
    
    def download(self, artifact_id: int, output_path: str) -> str:
        """Download artifact (redirects to MinIO presigned URL)"""
        response = self.client._request(
            "GET",
            f"model-artifacts/{artifact_id}/download",
            stream=True
        )
        
        output_path = Path(output_path)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        
        with open(output_path, "wb") as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        
        return str(output_path)
    
    def export(self, artifact_id: int) -> Dict[str, Any]:
        """Export artifact (background job)"""
        return self.client._request(
            "POST",
            f"model-artifacts/{artifact_id}/export"
        )
