"""
Helper service for billing period and drop ID operations.

Single Responsibility: Convert between date formats and generate drop IDs.
"""

from datetime import datetime
from dateutil.relativedelta import relativedelta


class BillingPeriodHelper:
    """
    Helper for billing period and drop ID operations.

    Handles conversion between month format (YYYY-MM) and billing period
    format (YYYYMMDD-YYYYMMDD), plus drop ID generation.
    """

    def month_to_billing_period(self, month: str) -> str:
        """
        Convert month to billing period.

        Billing period is first day of month to first day of next month.

        Args:
            month: Month in YYYY-MM format (e.g., "2025-01")

        Returns:
            Billing period in YYYYMMDD-YYYYMMDD format (e.g., "20250101-20250201")

        Raises:
            ValueError: If month format is invalid
        """
        try:
            # Parse month
            date = datetime.strptime(month, "%Y-%m")

            # First day of month
            start_date = date.replace(day=1)

            # First day of next month
            end_date = start_date + relativedelta(months=1)

            # Format as YYYYMMDD-YYYYMMDD
            return f"{start_date.strftime('%Y%m%d')}-{end_date.strftime('%Y%m%d')}"

        except ValueError as e:
            raise ValueError(
                f"Invalid month format '{month}'. Expected YYYY-MM format."
            ) from e

    def generate_drop_id(self) -> str:
        """
        Generate drop ID in CloudZero format.

        Format: YYYYMMDDTHHMMSSZ (ISO 8601 UTC timestamp)
        Example: "20260115T143022Z"

        Returns:
            Drop ID string
        """
        return datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")

    def build_drop_prefix(
        self,
        s3_root: str,
        org: str,
        provider: str,
        billing_period: str,
        drop_id: str
    ) -> str:
        """
        Build S3 prefix for drop folder.

        Args:
            s3_root: S3 root folder
            org: Organization name
            provider: Provider name
            billing_period: Billing period (YYYYMMDD-YYYYMMDD)
            drop_id: Drop ID

        Returns:
            Complete S3 prefix ending with '/'
        """
        return f"{s3_root}/{org}/{provider}/{billing_period}/{drop_id}/"

    def build_manifest_key(
        self,
        s3_root: str,
        org: str,
        provider: str,
        billing_period: str
    ) -> str:
        """
        Build S3 key for manifest.json.

        Args:
            s3_root: S3 root folder
            org: Organization name
            provider: Provider name
            billing_period: Billing period (YYYYMMDD-YYYYMMDD)

        Returns:
            Complete S3 key for manifest.json
        """
        return f"{s3_root}/{org}/{provider}/{billing_period}/manifest.json"
