from __future__ import annotations

from typing import Any, BinaryIO, Dict, Optional, Union, TYPE_CHECKING

if TYPE_CHECKING:
    from socialrails.client import SocialRails, AsyncSocialRails


class Media:
    """Synchronous resource for media uploads."""

    def __init__(self, client: SocialRails) -> None:
        self._client = client

    def upload(
        self,
        file: Union[BinaryIO, bytes],
        filename: str,
        *,
        media_type: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Upload a media file via multipart form data.

        Args:
            file: A file-like object (opened in binary mode) or raw bytes.
            filename: The filename including extension (e.g. "photo.jpg").
            media_type: Optional type hint: "image", "video", or "thumbnail".

        Returns:
            Dict with media_id, key, type, url, content_type, and size.
        """
        if isinstance(file, bytes):
            file_data = file
        else:
            file_data = file.read()

        files = {"file": (filename, file_data)}
        data: Dict[str, str] = {}
        if media_type is not None:
            data["type"] = media_type
        return self._client._post_files("/media/upload", files=files, data=data)

    def upload_from_url(
        self,
        url: str,
        *,
        media_type: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Upload media from a remote URL.

        Args:
            url: A publicly accessible HTTP(S) URL to the media file.
            media_type: Optional type hint: "image", "video", or "thumbnail".

        Returns:
            Dict with media_id, key, type, url, content_type, and size.
        """
        body: Dict[str, Any] = {"url": url}
        if media_type is not None:
            body["type"] = media_type
        return self._client._post("/media/upload-url", body)


class AsyncMedia:
    """Asynchronous resource for media uploads."""

    def __init__(self, client: AsyncSocialRails) -> None:
        self._client = client

    async def upload(
        self,
        file: Union[BinaryIO, bytes],
        filename: str,
        *,
        media_type: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Upload a media file via multipart form data.

        Args:
            file: A file-like object (opened in binary mode) or raw bytes.
            filename: The filename including extension (e.g. "photo.jpg").
            media_type: Optional type hint: "image", "video", or "thumbnail".

        Returns:
            Dict with media_id, key, type, url, content_type, and size.
        """
        if isinstance(file, bytes):
            file_data = file
        else:
            file_data = file.read()

        files = {"file": (filename, file_data)}
        data: Dict[str, str] = {}
        if media_type is not None:
            data["type"] = media_type
        return await self._client._post_files("/media/upload", files=files, data=data)

    async def upload_from_url(
        self,
        url: str,
        *,
        media_type: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Upload media from a remote URL.

        Args:
            url: A publicly accessible HTTP(S) URL to the media file.
            media_type: Optional type hint: "image", "video", or "thumbnail".

        Returns:
            Dict with media_id, key, type, url, content_type, and size.
        """
        body: Dict[str, Any] = {"url": url}
        if media_type is not None:
            body["type"] = media_type
        return await self._client._post("/media/upload-url", body)
