from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


@dataclass
class PipelineContext:
    """Holds per-run pipeline state to avoid globals.

    This context is created once per pipeline execution and is passed or
    captured by closures so tools can update state deterministically.
    """

    # Inputs/outputs
    image_path: str
    output_path: Optional[str] = None

    # Running state built from actual tool calls
    instances: List[Dict[str, Any]] = field(default_factory=list)
    steps: List[Dict[str, Any]] = field(default_factory=list)
    pending_detect: Optional[Dict[str, Any]] = None
    last_output: Optional[str] = None
    audit: Optional[Dict[str, Any]] = None

    # Track inpainted areas to avoid re-inpainting
    inpainted_masks: List[str] = field(default_factory=list)
    
    # Track all person masks (segmented areas) to exclude from PII object detection
    person_masks: List[str] = field(default_factory=list)
    
    # Track all detected person instances (from detect_persons) for batch processing
    person_instances: List[Dict[str, Any]] = field(default_factory=list)
    
    # Track all detected license plate instances (from detect_license_plates)
    license_plate_instances: List[Dict[str, Any]] = field(default_factory=list)
    
    # Track all detected traffic sign instances (from detect_traffic_signs) for exclusion
    traffic_sign_instances: List[Dict[str, Any]] = field(default_factory=list)
    
    # Track traffic sign masks to exclude from PII detection
    traffic_sign_masks: List[str] = field(default_factory=list)
    
    # Track license plate masks to exclude from PII detection (even though blurred)
    license_plate_masks: List[str] = field(default_factory=list)
    
    # Track inpainted PII descriptions to prevent duplicate inpainting
    # Each entry is a simple string for backward compatibility, but we also track pairs below
    inpainted_descriptions: List[str] = field(default_factory=list)
    
    # Track inpainted PII as (description, mask_path) pairs for spatial duplicate detection
    # This allows detecting multiple instances of same category in different locations
    inpainted_description_mask_pairs: List[tuple[str, str]] = field(default_factory=list)

    # Observability/logging
    tool_invocations: List[Dict[str, Any]] = field(default_factory=list)
    tool_log_path: Optional[str] = None
    transcript_file_path: Optional[str] = None
    instance_records: Dict[str, Dict[str, Any]] = field(default_factory=dict)
    instance_id_map: Dict[str, str] = field(default_factory=dict)
    instance_counter: int = 0
    active_instance_id: Optional[str] = None

    # Residual handling and audit state
    pending_residual_instances: List[Dict[str, Any]] = field(default_factory=list)
    duplicate_checks: List[Dict[str, Any]] = field(default_factory=list)
    audit_attempts: int = 0
    max_audit_attempts: int = 3
    audit_max_reached: bool = False
    audit_history: List[Dict[str, Any]] = field(default_factory=list)
