"""BLCE Department Mapper — heuristic mapping from department to data domain.

Maps organizational departments to the data domains they typically consume,
assisting in access planning and dimension scoping.
"""
from __future__ import annotations

from typing import Any, Dict, List

from .contracts import DepartmentMapping, ExtractedDimension, ExtractedKPI


# ---------------------------------------------------------------------------
# Heuristic domain mapping
# ---------------------------------------------------------------------------

_DOMAIN_MAP: Dict[str, List[str]] = {
    "finance": ["revenue", "expense", "gl", "balance_sheet", "budgets"],
    "accounting": ["revenue", "expense", "gl", "balance_sheet", "accounts_payable", "accounts_receivable"],
    "operations": ["production", "well", "completions", "field_operations"],
    "engineering": ["well", "completions", "decline_curve", "reserves"],
    "land": ["owner", "tract", "interest", "lease"],
    "marketing": ["purchaser", "contract", "pricing", "midstream"],
    "executive": ["kpi_dashboard", "financial_summary", "production_summary"],
    "it": ["system_admin", "data_quality", "metadata"],
    "regulatory": ["compliance", "reporting", "environmental"],
    "hr": ["personnel", "payroll", "benefits"],
    "supply chain": ["vendor", "procurement", "inventory"],
    "midstream": ["midstream", "pipeline", "processing", "gathering"],
}


class DepartmentMapper:
    """Map departments to data domains using heuristics."""

    def map_departments(
        self,
        departments: List[str],
        kpis: List[ExtractedKPI] | None = None,
        dimensions: List[ExtractedDimension] | None = None,
    ) -> List[DepartmentMapping]:
        """Map department names to data domains.

        Args:
            departments: List of department name strings.
            kpis: Optional KPIs to enhance mapping via department tags.
            dimensions: Optional dimensions to enhance mapping.

        Returns:
            List of DepartmentMapping objects.
        """
        mappings: List[DepartmentMapping] = []

        # Build reverse map from KPIs: which departments own which KPIs
        dept_kpis: Dict[str, List[str]] = {}
        for kpi in (kpis or []):
            for dept in kpi.departments:
                dept_kpis.setdefault(dept.lower(), []).append(kpi.name)

        for dept in departments:
            domains = self._infer_domains(dept)

            # Enrich from KPIs tagged to this department
            kpi_domains = dept_kpis.get(dept.lower(), [])
            if kpi_domains:
                domains = list(set(domains + kpi_domains))

            mappings.append(
                DepartmentMapping(
                    department=dept,
                    data_domains=domains,
                )
            )

        return mappings

    @staticmethod
    def _infer_domains(dept_name: str) -> List[str]:
        """Heuristic: map department name to data domains."""
        lower = dept_name.lower().strip()

        for key, domains in _DOMAIN_MAP.items():
            if key in lower:
                return list(domains)

        # Fallback: try partial matches
        for key, domains in _DOMAIN_MAP.items():
            if any(word in lower for word in key.split()):
                return list(domains)

        return ["general"]
