"""Configuration loading for privacy mask engine."""

import json
import os
from dataclasses import dataclass, field
from typing import Any


DEFAULT_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "data", "config.json")


@dataclass
class MaskingConfig:
    method: str = "blur"
    blur_radius: int = 20
    fill_color: tuple = (0, 0, 0)
    padding: int = 4


@dataclass
class OcrConfig:
    engine: str = "combined"  # "tesseract", "rapidocr", or "combined"
    languages: str = "eng+chi_sim"
    min_confidence: int = 30
    multi_preprocess: bool = True  # run OCR with multiple preprocessing strategies


@dataclass
class OutputConfig:
    suffix: str = "_masked"
    format: str = "png"


@dataclass
class DetectionRule:
    name: str
    pattern: str
    description: str
    enabled: bool = True


@dataclass
class NerConfig:
    model_name: str = "gliner-community/gliner_small-v2.5"
    entity_types: list[str] = field(default_factory=lambda: [
        "person name", "street address",
        "date of birth", "medical condition",
    ])
    confidence_threshold: float = 0.7
    max_text_length: int = 512
    min_word_count: int = 2  # minimum words for person name to reduce single-word false positives


@dataclass
class DetectionConfig:
    engine: str = "ner"  # "regex" or "ner"


@dataclass
class Config:
    detection_rules: list[DetectionRule] = field(default_factory=list)
    masking: MaskingConfig = field(default_factory=MaskingConfig)
    ocr: OcrConfig = field(default_factory=OcrConfig)
    output: OutputConfig = field(default_factory=OutputConfig)
    detection: DetectionConfig = field(default_factory=DetectionConfig)
    ner: NerConfig = field(default_factory=NerConfig)


def load_config(config_path: str | None = None) -> Config:
    """Load configuration from JSON file."""
    path = config_path or DEFAULT_CONFIG_PATH
    with open(path, "r") as f:
        data = json.load(f)

    rules = []
    for name, rule_data in data.get("detection_rules", {}).items():
        rules.append(DetectionRule(
            name=name,
            pattern=rule_data["pattern"],
            description=rule_data.get("description", ""),
            enabled=rule_data.get("enabled", True),
        ))

    masking_data = data.get("masking", {})
    masking = MaskingConfig(
        method=masking_data.get("method", "blur"),
        blur_radius=masking_data.get("blur_radius", 20),
        fill_color=tuple(masking_data.get("fill_color", [0, 0, 0])),
        padding=masking_data.get("padding", 4),
    )

    ocr_data = data.get("ocr", {})
    ocr = OcrConfig(
        engine=ocr_data.get("engine", "combined"),
        languages=ocr_data.get("languages", "eng+chi_sim"),
        min_confidence=ocr_data.get("min_confidence", 30),
        multi_preprocess=ocr_data.get("multi_preprocess", True),
    )

    output_data = data.get("output", {})
    output = OutputConfig(
        suffix=output_data.get("suffix", "_masked"),
        format=output_data.get("format", "png"),
    )

    detection_data = data.get("detection", {})
    detection = DetectionConfig(
        engine=detection_data.get("engine", "ner"),
    )

    ner_data = data.get("ner", {})
    ner = NerConfig(
        model_name=ner_data.get("model_name", "gliner-community/gliner_small-v2.5"),
        entity_types=ner_data.get("entity_types", NerConfig().entity_types),
        confidence_threshold=ner_data.get("confidence_threshold", 0.5),
        max_text_length=ner_data.get("max_text_length", 512),
    )

    return Config(
        detection_rules=rules,
        masking=masking,
        ocr=ocr,
        output=output,
        detection=detection,
        ner=ner,
    )
