"""
Scale Strategy Configuration.

Defines field-specific bbox expansion strategies for YOLO training data.
Each strategy controls how bboxes are expanded around field values to
capture contextual information like labels.
"""

from dataclasses import dataclass
from typing import Final


@dataclass(frozen=True)
class ScaleStrategy:
    """Immutable scale strategy for bbox expansion.

    Attributes:
        scale_x: Horizontal scale factor (1.0 = no scaling)
        scale_y: Vertical scale factor (1.0 = no scaling)
        extra_top_ratio: Additional expansion ratio towards top (for labels above)
        extra_bottom_ratio: Additional expansion ratio towards bottom
        extra_left_ratio: Additional expansion ratio towards left (for prefixes)
        extra_right_ratio: Additional expansion ratio towards right (for suffixes)
        max_pad_x: Maximum horizontal padding in pixels
        max_pad_y: Maximum vertical padding in pixels
    """

    scale_x: float = 1.15
    scale_y: float = 1.15
    extra_top_ratio: float = 0.0
    extra_bottom_ratio: float = 0.0
    extra_left_ratio: float = 0.0
    extra_right_ratio: float = 0.0
    max_pad_x: int = 50
    max_pad_y: int = 50


# Default strategy for unknown fields (auto-label mode)
DEFAULT_STRATEGY: Final[ScaleStrategy] = ScaleStrategy()

# Manual label strategy - minimal padding to prevent edge clipping
# No scaling, no directional compensation, just small uniform padding
MANUAL_LABEL_STRATEGY: Final[ScaleStrategy] = ScaleStrategy(
    scale_x=1.0,
    scale_y=1.0,
    extra_top_ratio=0.0,
    extra_bottom_ratio=0.0,
    extra_left_ratio=0.0,
    extra_right_ratio=0.0,
    max_pad_x=10,  # Small padding to prevent edge loss
    max_pad_y=10,
)


# Field-specific strategies based on Swedish invoice field characteristics
# Field labels typically appear above or to the left of values
FIELD_SCALE_STRATEGIES: Final[dict[str, ScaleStrategy]] = {
    # OCR number - label "OCR" or "Referens" typically above
    "ocr_number": ScaleStrategy(
        scale_x=1.15,
        scale_y=1.80,
        extra_top_ratio=0.60,
        max_pad_x=50,
        max_pad_y=140,
    ),
    # Bankgiro - prefix "Bankgiro:" or "BG:" typically to the left
    "bankgiro": ScaleStrategy(
        scale_x=1.45,
        scale_y=1.35,
        extra_left_ratio=0.80,
        max_pad_x=160,
        max_pad_y=90,
    ),
    # Plusgiro - prefix "Plusgiro:" or "PG:" typically to the left
    "plusgiro": ScaleStrategy(
        scale_x=1.45,
        scale_y=1.35,
        extra_left_ratio=0.80,
        max_pad_x=160,
        max_pad_y=90,
    ),
    # Invoice date - label "Fakturadatum" typically above
    "invoice_date": ScaleStrategy(
        scale_x=1.25,
        scale_y=1.55,
        extra_top_ratio=0.40,
        max_pad_x=80,
        max_pad_y=110,
    ),
    # Due date - label "Forfalldatum" typically above, sometimes left
    "invoice_due_date": ScaleStrategy(
        scale_x=1.30,
        scale_y=1.65,
        extra_top_ratio=0.45,
        extra_left_ratio=0.35,
        max_pad_x=100,
        max_pad_y=120,
    ),
    # Amount - currency symbol "SEK" or "kr" may be to the right
    "amount": ScaleStrategy(
        scale_x=1.20,
        scale_y=1.35,
        extra_right_ratio=0.30,
        max_pad_x=70,
        max_pad_y=80,
    ),
    # Invoice number - label "Fakturanummer" typically above
    "invoice_number": ScaleStrategy(
        scale_x=1.20,
        scale_y=1.50,
        extra_top_ratio=0.40,
        max_pad_x=80,
        max_pad_y=100,
    ),
    # Supplier org number - label "Org.nr" typically above or left
    "supplier_org_number": ScaleStrategy(
        scale_x=1.25,
        scale_y=1.40,
        extra_top_ratio=0.30,
        extra_left_ratio=0.20,
        max_pad_x=90,
        max_pad_y=90,
    ),
    # Customer number - label "Kundnummer" typically above or left
    "customer_number": ScaleStrategy(
        scale_x=1.25,
        scale_y=1.45,
        extra_top_ratio=0.35,
        extra_left_ratio=0.25,
        max_pad_x=90,
        max_pad_y=100,
    ),
    # Payment line - machine-readable code, minimal expansion needed
    "payment_line": ScaleStrategy(
        scale_x=1.10,
        scale_y=1.20,
        max_pad_x=40,
        max_pad_y=40,
    ),
}
