"""
Service combination extraction service following Single Responsibility Principle.
"""

from typing import List
import polars as pl


class CombinationExtractor:
    """
    Single responsibility: Extract unique service combinations from export data.

    Handles Operation 1 of export processing: identifying new service/resource
    combinations for expanding CZBG's service catalog knowledge.
    """

    # 7 key fields for unique combinations (updated to include instance_type)
    COMBINATION_FIELDS = [
        "cloud_provider",
        "service",
        "usage_family",
        "resource_type",
        "operation",
        "usage_type",
        "instance_type"
    ]

    def extract_combinations(self, export_df: pl.DataFrame) -> pl.DataFrame:
        """
        Extract unique service combinations from normalized export data.

        Args:
            export_df: Normalized export DataFrame

        Returns:
            DataFrame with unique combinations and has_pricing flag
        """
        # Get available combination fields
        available_fields = self._get_available_fields(export_df)

        # Select combination fields plus metadata
        select_columns = available_fields.copy()
        if "has_pricing" in export_df.columns:
            select_columns.append("has_pricing")
        if "pricing_unit" in export_df.columns:
            select_columns.append("pricing_unit")

        # Extract unique combinations
        combinations = export_df.select(select_columns).unique()

        return combinations

    def _get_available_fields(self, df: pl.DataFrame) -> List[str]:
        """Get combination fields that exist in the DataFrame."""
        return [
            field for field in self.COMBINATION_FIELDS
            if field in df.columns
        ]

    def count_unique_combinations(self, export_df: pl.DataFrame) -> int:
        """Count unique combinations in export data."""
        available_fields = self._get_available_fields(export_df)
        if not available_fields:
            return 0

        return export_df.select(available_fields).unique().height

    def validate_combination_completeness(self, export_df: pl.DataFrame) -> dict:
        """
        Validate combination data completeness.

        Returns:
            Dictionary with validation statistics
        """
        available_fields = self._get_available_fields(export_df)
        missing_fields = [
            field for field in self.COMBINATION_FIELDS
            if field not in available_fields
        ]

        total_combinations = self.count_unique_combinations(export_df)

        return {
            "total_combinations": total_combinations,
            "available_fields": len(available_fields),
            "missing_fields": missing_fields,
            "completeness_ratio": len(available_fields) / len(self.COMBINATION_FIELDS)
        }