"""ERP config registry with auto-detection.

Registers pre-tuned InferenceConfig + FocusConfig per ERP system and
can auto-detect the ERP type from a list of table names by scoring
prefix matches against BUILTIN_MAPS.
"""

from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple

from ..focus_config import FocusConfig, InferenceConfig

logger = logging.getLogger(__name__)


@dataclass
class ERPConfigEntry:
    """Registered config for one ERP system."""
    inference: InferenceConfig
    focus: FocusConfig


# Global registry
_REGISTRY: Dict[str, ERPConfigEntry] = {}


def register_erp_config(
    erp_name: str,
    config: InferenceConfig,
    focus: FocusConfig,
) -> None:
    """Register an ERP configuration preset.

    Args:
        erp_name: Lowercase ERP identifier (e.g. 'enertia', 'sap').
        config: InferenceConfig with suffix/prefix patterns.
        focus: FocusConfig for transaction table handling.
    """
    _REGISTRY[erp_name.lower()] = ERPConfigEntry(inference=config, focus=focus)
    logger.debug("Registered ERP config: %s", erp_name)


def get_erp_config(erp_name: str) -> Optional[ERPConfigEntry]:
    """Get a registered ERP config by name.

    Returns None if not found.
    """
    _auto_register()
    return _REGISTRY.get(erp_name.lower())


def list_erp_configs() -> List[Dict[str, object]]:
    """List all registered ERP configs."""
    _auto_register()
    return [
        {
            "erp": name,
            "key_suffixes": entry.inference.key_suffixes,
            "strip_prefixes": entry.inference.strip_prefixes,
            "min_overlap": entry.inference.min_overlap,
            "focus_patterns": entry.focus.patterns,
        }
        for name, entry in _REGISTRY.items()
    ]


def detect_erp_type(table_names: List[str]) -> Optional[str]:
    """Auto-detect ERP type from table name prefixes.

    Uses BUILTIN_MAPS from the table grouping strategy to score
    how many tables match each ERP's prefix set.

    Args:
        table_names: List of table names to analyze.

    Returns:
        Best matching ERP name, or None if no match exceeds 20%.
    """
    try:
        from src.plugins.ce.table_grouping.strategy import BUILTIN_MAPS
    except ImportError:
        logger.warning("Table grouping strategy not available for ERP detection")
        return None

    if not table_names:
        return None

    scores: Dict[str, int] = {}
    for erp_name, prefix_map in BUILTIN_MAPS.items():
        prefixes = sorted(prefix_map.keys(), key=len, reverse=True)
        count = 0
        for table in table_names:
            upper = table.upper()
            for pfx in prefixes:
                if upper.startswith(pfx):
                    count += 1
                    break
        scores[erp_name] = count

    if not scores:
        return None

    best = max(scores, key=scores.get)  # type: ignore[arg-type]
    ratio = scores[best] / len(table_names)

    if ratio < 0.2:
        logger.info("No ERP matched >20%% of tables (best: %s at %.0f%%)", best, ratio * 100)
        return None

    logger.info("Detected ERP type: %s (%.0f%% match)", best, ratio * 100)
    return best


def detect_erp_type_detailed(table_names: List[str]) -> Dict:
    """Auto-detect ERP type with per-table prefix matches.

    Like ``detect_erp_type()`` but also returns which prefix matched
    each table and the domain label from BUILTIN_MAPS.

    Args:
        table_names: List of table names to analyze.

    Returns:
        Dict with keys:
            erp_type: Best matching ERP name (or "").
            confidence: Match ratio (0.0-1.0).
            per_table_matches: {table: {"prefix": str, "domain": str}} for matched tables.
    """
    try:
        from src.plugins.ce.table_grouping.strategy import BUILTIN_MAPS
    except ImportError:
        return {"erp_type": "", "confidence": 0.0, "per_table_matches": {}}

    if not table_names:
        return {"erp_type": "", "confidence": 0.0, "per_table_matches": {}}

    best_erp = ""
    best_ratio = 0.0
    best_matches: Dict[str, Dict[str, str]] = {}

    for erp_name, prefix_map in BUILTIN_MAPS.items():
        prefixes = sorted(prefix_map.keys(), key=len, reverse=True)
        matches: Dict[str, Dict[str, str]] = {}
        for table in table_names:
            upper = table.upper()
            for pfx in prefixes:
                if upper.startswith(pfx):
                    matches[table] = {"prefix": pfx, "domain": prefix_map[pfx]}
                    break

        ratio = len(matches) / len(table_names) if table_names else 0
        if ratio > best_ratio:
            best_ratio = ratio
            best_erp = erp_name
            best_matches = matches

    if best_ratio < 0.2:
        return {"erp_type": "", "confidence": round(best_ratio, 3), "per_table_matches": {}}

    logger.info("Detailed ERP detection: %s (%.0f%% match, %d tables)", best_erp, best_ratio * 100, len(best_matches))
    return {
        "erp_type": best_erp,
        "confidence": round(best_ratio, 3),
        "per_table_matches": best_matches,
    }


# ---------------------------------------------------------------------------
# Auto-registration of built-in configs
# ---------------------------------------------------------------------------

_REGISTERED = False


def _auto_register() -> None:
    """Lazily register built-in ERP configs on first access."""
    global _REGISTERED
    if _REGISTERED:
        return
    _REGISTERED = True

    # Enertia
    from .enertia import ENERTIA_CONFIG, ENERTIA_FOCUS
    register_erp_config("enertia", ENERTIA_CONFIG, ENERTIA_FOCUS)

    # WolfePak
    from .wolfepak import WOLFEPAK_CONFIG, WOLFEPAK_FOCUS
    register_erp_config("wolfepak", WOLFEPAK_CONFIG, WOLFEPAK_FOCUS)

    # SAP
    from .sap import SAP_CONFIG, SAP_FOCUS
    register_erp_config("sap", SAP_CONFIG, SAP_FOCUS)

    # NetSuite
    from .netsuite import NETSUITE_CONFIG, NETSUITE_FOCUS
    register_erp_config("netsuite", NETSUITE_CONFIG, NETSUITE_FOCUS)

    # QuickBooks
    from .quickbooks import QUICKBOOKS_CONFIG, QUICKBOOKS_FOCUS
    register_erp_config("quickbooks", QUICKBOOKS_CONFIG, QUICKBOOKS_FOCUS)
