from __future__ import annotations

import logging

from muleline.storage.base import StorageBackend

log = logging.getLogger(__name__)


class DropboxStorage(StorageBackend):
    """Dropbox storage backend."""

    def __init__(self, access_token: str, root_path: str = "/muleline"):
        self.root_path = "/" + root_path.strip("/")

        try:
            import dropbox
            from dropbox.files import WriteMode
        except ImportError:
            raise ImportError("Install dropbox SDK: pip install muleline[dropbox]")

        self._dbx = dropbox.Dropbox(access_token)
        self._WriteMode = WriteMode

    def _key(self, key: str) -> str:
        return f"{self.root_path}/{key}"

    def save(self, key: str, content: bytes, mime_type: str = "") -> bool:
        try:
            self._dbx.files_upload(content, self._key(key), mode=self._WriteMode.overwrite)
            return True
        except Exception as e:
            log.error("Dropbox save failed for %s: %s", key, e)
            return False

    def read(self, key: str) -> bytes | None:
        try:
            _, resp = self._dbx.files_download(self._key(key))
            return resp.content
        except Exception as e:
            log.error("Dropbox read failed for %s: %s", key, e)
            return None

    def delete(self, key: str) -> bool:
        try:
            self._dbx.files_delete_v2(self._key(key))
            return True
        except Exception as e:
            log.error("Dropbox delete failed for %s: %s", key, e)
            return False

    def exists(self, key: str) -> bool:
        try:
            from dropbox.exceptions import ApiError
            self._dbx.files_get_metadata(self._key(key))
            return True
        except Exception:
            return False

    def url(self, key: str, expires: int = 3600) -> str | None:
        try:
            from dropbox.sharing import RequestedVisibility, SharedLinkSettings
            settings = SharedLinkSettings(requested_visibility=RequestedVisibility.public)
            result = self._dbx.sharing_create_shared_link_with_settings(self._key(key), settings)
            return result.url
        except Exception as e:
            log.error("Dropbox url failed for %s: %s", key, e)
            return None
