"""Synor Storage SDK Types."""

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional, Callable, List


class PinStatus(str, Enum):
    """Pin status."""
    QUEUED = "queued"
    PINNING = "pinning"
    PINNED = "pinned"
    FAILED = "failed"
    UNPINNED = "unpinned"


class HashAlgorithm(str, Enum):
    """Hash algorithm."""
    SHA2_256 = "sha2-256"
    BLAKE3 = "blake3"


class EntryType(str, Enum):
    """Entry type."""
    FILE = "file"
    DIRECTORY = "directory"


class MatchType(str, Enum):
    """Match type for listing pins."""
    EXACT = "exact"
    IEXACT = "iexact"
    PARTIAL = "partial"
    IPARTIAL = "ipartial"


@dataclass
class StorageConfig:
    """Storage SDK configuration."""
    api_key: str
    endpoint: str = "https://storage.synor.cc/api/v1"
    gateway: str = "https://gateway.synor.cc"
    pinning_service: Optional[str] = None
    chunk_size: int = 262144  # 256KB
    timeout: float = 30.0
    debug: bool = False


@dataclass
class UploadProgress:
    """Upload progress."""
    bytes_uploaded: int
    total_bytes: int
    percentage: float


@dataclass
class UploadOptions:
    """Upload options."""
    pin: bool = True
    wrap_with_directory: bool = False
    cid_version: int = 1
    hash_algorithm: HashAlgorithm = HashAlgorithm.SHA2_256
    on_progress: Optional[Callable[[UploadProgress], None]] = None


@dataclass
class UploadResponse:
    """Upload response."""
    cid: str
    size: int
    name: Optional[str] = None
    hash: Optional[str] = None


@dataclass
class DownloadProgress:
    """Download progress."""
    bytes_downloaded: int
    total_bytes: int
    percentage: float


@dataclass
class DownloadOptions:
    """Download options."""
    offset: Optional[int] = None
    length: Optional[int] = None
    on_progress: Optional[Callable[[DownloadProgress], None]] = None


@dataclass
class Pin:
    """Pin information."""
    cid: str
    status: PinStatus
    name: Optional[str] = None
    size: Optional[int] = None
    created_at: Optional[int] = None
    expires_at: Optional[int] = None
    delegates: List[str] = field(default_factory=list)


@dataclass
class PinRequest:
    """Pin request."""
    cid: str
    name: Optional[str] = None
    duration: Optional[int] = None
    origins: List[str] = field(default_factory=list)


@dataclass
class ListPinsOptions:
    """List pins options."""
    status: Optional[List[PinStatus]] = None
    match: Optional[MatchType] = None
    name: Optional[str] = None
    limit: Optional[int] = None
    offset: Optional[int] = None


@dataclass
class ListPinsResponse:
    """List pins response."""
    pins: List[Pin]
    total: int
    has_more: bool


@dataclass
class GatewayUrl:
    """Gateway URL."""
    url: str
    cid: str
    path: Optional[str] = None


@dataclass
class CarBlock:
    """CAR block."""
    cid: str
    data: str  # Base64-encoded
    size: Optional[int] = None


@dataclass
class CarFile:
    """CAR file."""
    version: int
    roots: List[str]
    blocks: List[CarBlock] = field(default_factory=list)
    size: Optional[int] = None


@dataclass
class FileEntry:
    """File entry for directory creation."""
    name: str
    content: Optional[bytes] = None
    cid: Optional[str] = None


@dataclass
class DirectoryEntry:
    """Directory entry."""
    name: str
    cid: str
    type: EntryType
    size: Optional[int] = None


@dataclass
class ImportCarResponse:
    """Import CAR response."""
    roots: List[str]
    blocks_imported: int


@dataclass
class StorageStats:
    """Storage statistics."""
    total_size: int
    pin_count: int
    upload_bandwidth: Optional[int] = None
    download_bandwidth: Optional[int] = None
