"""
Utility functions for field matching.
"""

import re


# Pre-compiled regex patterns (module-level for efficiency)
DATE_PATTERN = re.compile(r'(\d{4})-(\d{2})-(\d{2})')
WHITESPACE_PATTERN = re.compile(r'\s+')
NON_DIGIT_PATTERN = re.compile(r'\D')
DASH_PATTERN = re.compile(r'[\u2013\u2014\u2212\u00b7]')  # en-dash, em-dash, minus sign, middle dot


def normalize_dashes(text: str) -> str:
    """Normalize different dash types and middle dots to standard hyphen-minus (ASCII 45)."""
    return DASH_PATTERN.sub('-', text)


def parse_amount(text: str | int | float) -> float | None:
    """Try to parse text as a monetary amount."""
    # Convert to string first
    text = str(text)

    # First, handle Swedish öre format: "239 00" means 239.00 (239 kr 00 öre)
    # Pattern: digits + space + exactly 2 digits at end
    ore_match = re.match(r'^(\d+)\s+(\d{2})$', text.strip())
    if ore_match:
        kronor = ore_match.group(1)
        ore = ore_match.group(2)
        try:
            return float(f"{kronor}.{ore}")
        except ValueError:
            pass

    # Remove everything after and including parentheses (e.g., "(inkl. moms)")
    text = re.sub(r'\s*\(.*\)', '', text)

    # Remove currency symbols and common suffixes (including trailing dots from "kr.")
    text = re.sub(r'\b(SEK|kr|kronor|öre)\b\.?', '', text, flags=re.IGNORECASE)
    text = re.sub(r'[:-]', '', text)

    # Remove spaces (thousand separators) but be careful with öre format
    text = text.replace(' ', '').replace('\xa0', '')

    # Handle comma as decimal separator
    # Swedish format: "500,00" means 500.00
    # Need to handle cases like "500,00." (after removing "kr.")
    if ',' in text:
        # Remove any trailing dots first (from "kr." removal)
        text = text.rstrip('.')
        # Now replace comma with dot
        if '.' not in text:
            text = text.replace(',', '.')

    # Remove any remaining non-numeric characters except dot
    text = re.sub(r'[^\d.]', '', text)

    try:
        return float(text)
    except ValueError:
        return None


def tokens_on_same_line(token1, token2) -> bool:
    """Check if two tokens are on the same line."""
    # Check vertical overlap
    y_overlap = min(token1.bbox[3], token2.bbox[3]) - max(token1.bbox[1], token2.bbox[1])
    min_height = min(token1.bbox[3] - token1.bbox[1], token2.bbox[3] - token2.bbox[1])
    return y_overlap > min_height * 0.5


def bbox_overlap(
    bbox1: tuple[float, float, float, float],
    bbox2: tuple[float, float, float, float]
) -> float:
    """Calculate IoU (Intersection over Union) of two bounding boxes."""
    x1 = max(bbox1[0], bbox2[0])
    y1 = max(bbox1[1], bbox2[1])
    x2 = min(bbox1[2], bbox2[2])
    y2 = min(bbox1[3], bbox2[3])

    if x2 <= x1 or y2 <= y1:
        return 0.0

    intersection = float(x2 - x1) * float(y2 - y1)
    area1 = float(bbox1[2] - bbox1[0]) * float(bbox1[3] - bbox1[1])
    area2 = float(bbox2[2] - bbox2[0]) * float(bbox2[3] - bbox2[1])
    union = area1 + area2 - intersection

    return intersection / union if union > 0 else 0.0
