"""
Fluent builder classes for configuration.
"""
from typing import List, Dict, Any, Optional, Callable, Union
from .models import (
    Zone, Line, RegionCounterConfig, PPEConfig, RedactionConfig,
    ALPRConfig, AgeEmotionConfig, TimeInRegionConfig, EntryExitConfig,
    FallDetectionConfig
)
from dataclasses import asdict


class AnalysisBuilder:
    """Base builder class for analysis configuration."""
    
    def __init__(self, sdk, video_path: str):
        self.sdk = sdk
        self.video_path = video_path
        self.return_annotated = False
        self.progress_callback: Optional[Callable] = None
    
    def with_annotated_video(self, enabled: bool = True) -> 'AnalysisBuilder':
        """Request annotated video in response."""
        self.return_annotated = enabled
        return self
    
    def with_progress(self, callback: Callable[[int, int], None]) -> 'AnalysisBuilder':
        """Set progress callback for upload/download tracking."""
        self.progress_callback = callback
        return self
    
    def _get_config(self) -> Dict[str, Any]:
        """Get configuration dictionary. Override in subclasses."""
        raise NotImplementedError


class MovementInZoneBuilder(AnalysisBuilder):
    """Builder for movement in zone analysis."""
    
    def __init__(self, sdk, video_path: str):
        super().__init__(sdk, video_path)
        self.config = RegionCounterConfig()
    
    def with_zones(self, zones: List[Union[Zone, Dict[str, Any]]]) -> 'MovementInZoneBuilder':
        """Set detection zones."""
        self.config.zones = [z.dict() if isinstance(z, Zone) else z for z in zones]
        return self
    
    def with_classes(self, classes: List[str]) -> 'MovementInZoneBuilder':
        """Set object classes to detect."""
        self.config.classes = classes
        return self
    
    def with_confidence(self, confidence: float) -> 'MovementInZoneBuilder':
        """Set confidence threshold (0-1)."""
        self.config.confidence = confidence
        return self
    
    def with_model(self, model: str) -> 'MovementInZoneBuilder':
        """Set detection model."""
        self.config.model = model
        return self
    
    def with_immediate_return(self, enabled: bool = True) -> 'MovementInZoneBuilder':
        """Enable immediate return on first detection."""
        self.config.immediate_return = enabled
        return self
    
    def with_movement_required(self, enabled: bool = True) -> 'MovementInZoneBuilder':
        """Require movement for detection."""
        self.config.require_movement = enabled
        return self
    
    def with_movement_sensitivity(self, sensitivity: float) -> 'MovementInZoneBuilder':
        """Set movement sensitivity threshold."""
        self.config.movement_sensitivity = sensitivity
        return self
    
    def with_tracking_duration(self, duration: int) -> 'MovementInZoneBuilder':
        """Set tracking duration in frames."""
        self.config.tracking_duration = duration
        return self
    
    def execute(self):
        """Execute the analysis."""
        return self.sdk.analyze(
            self.video_path,
            [self.config],
            return_annotated=self.return_annotated,
            progress_callback=self.progress_callback
        )


class PPEDetectionBuilder(AnalysisBuilder):
    """Builder for PPE detection analysis."""
    
    def __init__(self, sdk, video_path: str):
        super().__init__(sdk, video_path)
        self.config = PPEConfig()
    
    def with_required_ppe(self, ppe_items: List[str]) -> 'PPEDetectionBuilder':
        """Set required PPE items."""
        self.config.required_ppe = ppe_items
        return self
    
    def with_confidence(self, confidence: float) -> 'PPEDetectionBuilder':
        """Set confidence threshold."""
        self.config.confidence = confidence
        return self
    
    def with_model(self, model_path: str) -> 'PPEDetectionBuilder':
        """Set custom model path."""
        self.config.model_path = model_path
        return self
    
    def execute(self):
        """Execute the analysis."""
        return self.sdk.analyze(
            self.video_path,
            [self.config],
            return_annotated=self.return_annotated,
            progress_callback=self.progress_callback
        )


class VideoRedactionBuilder(AnalysisBuilder):
    """Builder for video redaction."""
    
    def __init__(self, sdk, video_path: str):
        super().__init__(sdk, video_path)
        self.config = RedactionConfig()
        self.return_annotated = True  # Default to True for redaction
    
    def with_classes(self, classes: List[str]) -> 'VideoRedactionBuilder':
        """Set classes to redact (e.g., ['face', 'person', 'license_plate'])."""
        self.config.classes = classes
        return self
    
    def with_backend(self, backend: str) -> 'VideoRedactionBuilder':
        """Set redaction backend ('opencv' or 'deepface')."""
        self.config.backend = backend
        return self
    
    def with_blur_kernel(self, width: int, height: int) -> 'VideoRedactionBuilder':
        """Set blur kernel size."""
        self.config.blur_kernel_size = [width, height]
        return self
    
    def with_fps(self, fps: int) -> 'VideoRedactionBuilder':
        """Set processing frame rate."""
        self.config.fps = fps
        return self
    
    def execute(self):
        """Execute the analysis."""
        return self.sdk.analyze(
            self.video_path,
            [self.config],
            return_annotated=self.return_annotated,
            progress_callback=self.progress_callback
        )


class TimeInRegionBuilder(AnalysisBuilder):
    """Builder for time in region analysis."""
    
    def __init__(self, sdk, video_path: str):
        super().__init__(sdk, video_path)
        self.config = TimeInRegionConfig()
    
    def with_zones(self, zones: List[Union[Zone, Dict[str, Any]]]) -> 'TimeInRegionBuilder':
        """Set detection zones."""
        self.config.zones = [z.dict() if isinstance(z, Zone) else z for z in zones]
        return self
    
    def with_model(self, model: str) -> 'TimeInRegionBuilder':
        """Set detection model."""
        self.config.model = model
        return self
    
    def with_fps(self, fps: int) -> 'TimeInRegionBuilder':
        """Set processing frame rate."""
        self.config.fps = fps
        return self
    
    def execute(self):
        """Execute the analysis."""
        return self.sdk.analyze(
            self.video_path,
            [self.config],
            return_annotated=self.return_annotated,
            progress_callback=self.progress_callback
        )


class EntryExitBuilder(AnalysisBuilder):
    """Builder for entry/exit counting."""
    
    def __init__(self, sdk, video_path: str):
        super().__init__(sdk, video_path)
        self.config = EntryExitConfig()
    
    def with_zones(self, zones: List[Union[Zone, Dict[str, Any]]]) -> 'EntryExitBuilder':
        """Set detection zones."""
        self.config.zones = [z.dict() if isinstance(z, Zone) else z for z in zones]
        return self
    
    def with_lines(self, lines: List[Union[Line, Dict[str, Any]]]) -> 'EntryExitBuilder':
        """Set counting lines."""
        self.config.lines = [l.dict() if isinstance(l, Line) else l for l in lines]
        return self
    
    def with_classes(self, classes: List[str]) -> 'EntryExitBuilder':
        """Set object classes to count."""
        self.config.classes = classes
        return self
    
    def with_model(self, model: str) -> 'EntryExitBuilder':
        """Set detection model."""
        self.config.model = model
        return self
    
    def execute(self):
        """Execute the analysis."""
        return self.sdk.analyze(
            self.video_path,
            [self.config],
            return_annotated=self.return_annotated,
            progress_callback=self.progress_callback
        )
