"""
GCS Client - Google Cloud Storage Operations
Handles all GCS read/write/list operations with error handling.
"""

from typing import List
import logging
from google.cloud import storage
from google.api_core.exceptions import GoogleAPIError

logger = logging.getLogger(__name__)


class GCSClient:
    """Google Cloud Storage client with real implementation."""

    def __init__(self, project: str = None):
        """Initialize GCS client.

        Args:
            project: GCP project ID (optional, uses default credentials if
                     not provided)
        """
        self.project = project
        try:
            self.client = storage.Client(project=project)
            logger.info("GCSClient initialized for project: %s", project)
        except Exception as exc:
            logger.error("Failed to initialize GCS client: %s", exc)
            raise

    def read_file(self, bucket: str, path: str) -> str:
        """Read file from GCS.

        Args:
            bucket: GCS bucket name
            path: Path to file in bucket

        Returns:
            File content as string

        Raises:
            IOError: If file read fails
        """
        try:
            bucket_obj = self.client.bucket(bucket)
            blob = bucket_obj.blob(path)
            content = blob.download_as_string().decode('utf-8')
            logger.info("Successfully read %s/%s", bucket, path)
            return content
        except GoogleAPIError as exc:
            logger.error("GCS API error reading %s/%s: %s", bucket, path, exc)
            raise IOError(
                f"Failed to read {bucket}/{path}: {exc}") from exc
        except Exception as exc:
            logger.error("Error reading %s/%s: %s", bucket, path, exc)
            raise IOError(
                f"Failed to read {bucket}/{path}: {exc}") from exc

    def write_file(self, bucket: str, path: str, content: str) -> bool:
        """Write file to GCS.

        Args:
            bucket: GCS bucket name
            path: Path to file in bucket
            content: Content to write

        Returns:
            True if write successful

        Raises:
            IOError: If file write fails
        """
        try:
            bucket_obj = self.client.bucket(bucket)
            blob = bucket_obj.blob(path)
            blob.upload_from_string(content)
            logger.info("Successfully wrote to %s/%s", bucket, path)
            return True
        except GoogleAPIError as exc:
            logger.error("GCS API error writing to %s/%s: %s",
                        bucket, path, exc)
            raise IOError(
                f"Failed to write {bucket}/{path}: {exc}") from exc
        except Exception as exc:
            logger.error("Error writing to %s/%s: %s", bucket, path, exc)
            raise IOError(
                f"Failed to write {bucket}/{path}: {exc}") from exc

    def list_files(self, bucket: str, prefix: str = "") -> List[str]:
        """List files in GCS bucket.

        Args:
            bucket: GCS bucket name
            prefix: Optional prefix to filter files

        Returns:
            List of file paths in bucket

        Raises:
            IOError: If listing fails
        """
        try:
            blobs = self.client.list_blobs(bucket, prefix=prefix)
            files = [blob.name for blob in blobs]
            logger.info("Listed %d files in %s/%s", len(files), bucket, prefix)
            return files
        except GoogleAPIError as exc:
            logger.error("GCS API error listing %s/%s: %s",
                        bucket, prefix, exc)
            raise IOError(
                f"Failed to list {bucket}/{prefix}: {exc}") from exc
        except Exception as exc:
            logger.error("Error listing %s/%s: %s", bucket, prefix, exc)
            raise IOError(
                f"Failed to list {bucket}/{prefix}: {exc}") from exc

    def archive_file(self, bucket: str, source_path: str,
                     archive_path: str) -> bool:
        """Archive file by copying to archive location and deleting original.

        Args:
            bucket: GCS bucket name
            source_path: Original file path in bucket
            archive_path: Destination archive path in bucket

        Returns:
            True if archive successful

        Raises:
            IOError: If archive fails
        """
        try:
            bucket_obj = self.client.bucket(bucket)
            source_blob = bucket_obj.blob(source_path)
            bucket_obj.copy_blob(source_blob, bucket_obj, archive_path)
            source_blob.delete()
            logger.info("Archived %s/%s to %s/%s", bucket, source_path,
                       bucket, archive_path)
            return True
        except GoogleAPIError as exc:
            logger.error("GCS API error archiving %s: %s", source_path, exc)
            raise IOError(
                f"Failed to archive {source_path}: {exc}") from exc
        except Exception as exc:
            logger.error("Error archiving %s: %s", source_path, exc)
            raise IOError(
                f"Failed to archive {source_path}: {exc}") from exc
