"""
Data lifecycle manager for S3 data operations.

Manages S3 folder operations independently from connection lifecycle.
"""

from typing import Optional
import boto3
from botocore.exceptions import ClientError


class DataLifecycleManager:
    """
    Manages S3 data lifecycle operations.

    Single Responsibility: S3 folder CRUD operations only.
    Does NOT manage CloudZero connections.
    """

    def __init__(self, s3_bucket: str, s3_root_folder: str = "piedpiper-custom-billing"):
        """
        Initialize data lifecycle manager.

        Args:
            s3_bucket: S3 bucket name
            s3_root_folder: Root folder for billing data
        """
        self.s3_bucket = s3_bucket
        self.s3_root_folder = s3_root_folder
        self.s3_client = boto3.client('s3')

    def check_data_exists(
        self,
        org: str,
        provider: str,
        suffix: Optional[str] = None
    ) -> bool:
        """
        Check if S3 data exists for organization/provider.

        Args:
            org: Organization name
            provider: Provider name (AWS, Azure, GCP)
            suffix: Optional connection suffix

        Returns:
            True if any objects exist in the S3 folder
        """
        s3_folder = self._get_provider_folder(provider, suffix)
        s3_prefix = f"{self.s3_root_folder}/{org}/{s3_folder}/"

        try:
            # List objects with prefix limit=1 for efficiency
            response = self.s3_client.list_objects_v2(
                Bucket=self.s3_bucket,
                Prefix=s3_prefix,
                MaxKeys=1
            )

            # KeyCount > 0 means objects exist
            return response.get('KeyCount', 0) > 0

        except ClientError:
            # If listing fails, assume no data exists
            return False

    def delete_data(
        self,
        org: str,
        provider: str,
        suffix: Optional[str] = None
    ) -> int:
        """
        Delete all S3 data for organization/provider.

        Args:
            org: Organization name
            provider: Provider name (AWS, Azure, GCP)
            suffix: Optional connection suffix

        Returns:
            Number of objects deleted

        Raises:
            RuntimeError: If deletion fails
        """
        s3_folder = self._get_provider_folder(provider, suffix)
        s3_prefix = f"{self.s3_root_folder}/{org}/{s3_folder}/"

        print(f"   🗑️  Deleting S3 data: s3://{self.s3_bucket}/{s3_prefix}")

        try:
            # List all objects
            paginator = self.s3_client.get_paginator('list_objects_v2')
            pages = paginator.paginate(Bucket=self.s3_bucket, Prefix=s3_prefix)

            delete_count = 0
            for page in pages:
                objects = page.get('Contents', [])
                if not objects:
                    continue

                # Batch delete objects (max 1000 per batch)
                delete_keys = [{'Key': obj['Key']} for obj in objects]
                self.s3_client.delete_objects(
                    Bucket=self.s3_bucket,
                    Delete={'Objects': delete_keys}
                )
                delete_count += len(delete_keys)

            print(f"   ✅ Deleted {delete_count} objects")
            return delete_count

        except ClientError as e:
            raise RuntimeError(f"Failed to delete S3 data: {str(e)}")

    def _get_provider_folder(
        self,
        provider: str,
        suffix: Optional[str] = None
    ) -> str:
        """
        Get S3 provider folder name with optional suffix.

        Args:
            provider: Provider name
            suffix: Optional connection suffix

        Returns:
            Provider folder: "AWS" or "AWS-Anomalies"
        """
        if suffix:
            return f"{provider}-{suffix}"
        return provider
