"""Azure Storage Blob helper utilities."""

from __future__ import annotations

import logging

from azure.storage.blob import BlobServiceClient


class FileManager:
    """Provide high-level blob operations."""

    def __init__(
        self,
        account_name: str,
        account_key: str,
        container_name: str,
    ) -> None:
        if not account_name:
            raise ValueError("account_name cannot be empty")
        if not account_key:
            raise ValueError("account_key cannot be empty")
        if not container_name:
            raise ValueError("container_name cannot be empty")

        connection_string = (
            "DefaultEndpointsProtocol=https;"
            f"AccountName={account_name};"
            f"AccountKey={account_key};"
            "EndpointSuffix=core.windows.net"
        )
        logging.info("Initializing BlobServiceClient for account %s.", account_name)
        service_client = BlobServiceClient.from_connection_string(connection_string)
        self._container = service_client.get_container_client(container_name)

    def count_files(self, prefix: str = "") -> int:
        logging.info("Counting blobs under '%s'", prefix)
        count = 0
        for count, _ in enumerate(self._container.list_blobs(name_starts_with=prefix), start=1):
            if count % 10000 == 0:
                logging.info("Progress: %s blobs", count)
        logging.info("Completed count with %s blobs", count)
        return count

    def download_bytes(self, blob_path: str) -> bytes:
        if not blob_path:
            raise ValueError("blob_path cannot be empty")

        logging.info("Downloading blob %s.", blob_path)
        blob_client = self._container.get_blob_client(blob_path)

        try:
            data = blob_client.download_blob().readall()
        except Exception as exc:  # noqa: BLE001 - surface unexpected SDK errors
            logging.error("Failed to download blob %s: %s", blob_path, exc)
            raise RuntimeError(f"Failed to download blob '{blob_path}'.") from exc

        return data

    def copy(self, source_blob_path: str, dest_blob_path: str) -> None:
        dest = self._container.get_blob_client(dest_blob_path)
        source = self._container.get_blob_client(source_blob_path)
        dest.start_copy_from_url(source.url)

    def delete(self, blob_path: str) -> None:
        self._container.get_blob_client(blob_path).delete_blob()

    def move(self, source_blob_path: str, dest_blob_path: str) -> None:
        self.copy(source_blob_path, dest_blob_path)
        self.delete(source_blob_path)
