from __future__ import annotations

from pathlib import Path
from typing import Any

from niannian.storage.cloud_base import FileCloudBackend, HttpOpener, LiveCloudBackend
from niannian.storage.feimao_api import DEFAULT_FEIMAO_API_BASE, FeimaoDriveClient, FEIMAO_TIMEOUT_CAP
from niannian.storage.feimao_auth import feimao_request_headers


class FeimaoLiveBackend(LiveCloudBackend):
    """飞猫 L1 live — fmpapi 8s；CDN upload 可配至 10min+。"""

    def __init__(
        self,
        mirror_root: Path,
        *,
        session_token: str | None,
        api_base: str | None = None,
        timeout: float = FEIMAO_TIMEOUT_CAP,
        http_opener: HttpOpener | None = None,
        credential_manager: Any | None = None,
        remote_root: str | None = None,
        cdn_timeout: float | None = None,
        upload_progress_wait: float | None = None,
    ) -> None:
        capped = min(float(timeout), FEIMAO_TIMEOUT_CAP)
        self._drive_client: FeimaoDriveClient | None = None
        if session_token:
            state_path = mirror_root.parent.parent / "sync" / "feimao_state.json"
            from niannian.storage.feimao_api import normalize_feimao_api_base

            self._drive_client = FeimaoDriveClient(
                session_token,
                remote_root=remote_root,
                api_base=normalize_feimao_api_base(api_base),
                timeout=capped,
                http_opener=http_opener,
                state_path=state_path,
                cdn_timeout=cdn_timeout,
                upload_progress_wait=upload_progress_wait,
            )
        super().__init__(
            "feimao",
            mirror_root,
            token=session_token,
            api_base=api_base or DEFAULT_FEIMAO_API_BASE,
            timeout=capped,
            max_retries=0,
            http_opener=http_opener,
            credential_manager=credential_manager,
            provider="feimao",
            remote_root=remote_root,
        )

    def _auth_headers(self) -> dict[str, str]:
        return feimao_request_headers(self.token, with_json=True)

    def _remote_put(self, rel_path: str, data: bytes) -> None:
        if self._drive_client is not None:
            self._drive_client.upload_object(rel_path, data)
            return
        super()._remote_put(rel_path, data)

    def _remote_get(self, rel_path: str) -> bytes | None:
        if self._drive_client is not None:
            return self._drive_client.download_object(rel_path)
        return super()._remote_get(rel_path)


def build_feimao_backend(
    root: Path,
    *,
    session_token: str | None = None,
    force_mirror: bool = True,
    live: bool = False,
    api_base: str | None = None,
    http_opener: HttpOpener | None = None,
    credential_manager: Any | None = None,
    **kwargs: Any,
) -> FileCloudBackend | FeimaoLiveBackend:
    token = session_token
    if credential_manager is not None:
        token = credential_manager.get_session_token("feimao") or token
    if token and live and not force_mirror:
        return FeimaoLiveBackend(
            root,
            session_token=token,
            api_base=api_base,
            http_opener=http_opener,
            credential_manager=credential_manager,
            **{
                k: v
                for k, v in kwargs.items()
                if k in ("timeout", "remote_root", "cdn_timeout", "upload_progress_wait", "http_opener")
            },
        )
    return FileCloudBackend("feimao", root, token=token)
