from __future__ import annotations

import os
import re
import logging
from typing import Any, Dict

# Lazy import for LLM provider to avoid GCP credential discovery at startup
_llm_provider_getter = None

def _get_llm_provider():
    """Lazy loader for get_llm_provider to avoid startup hang."""
    global _llm_provider_getter
    if _llm_provider_getter is None:
        from ..providers import get_llm_provider as _glp
        _llm_provider_getter = _glp
    return _llm_provider_getter()

from fmatch.core.heuristics import TITLE_SENIORITY_RULES, TITLE_DEPT_RULES

logger = logging.getLogger(__name__)


_WS = re.compile(r"\s+")


def _clean_title(s: str) -> str:
    t = (s or "").strip()
    t = (
        t.replace("/", " ")
        .replace("-", " ")
        .replace("(", " ")
        .replace(")", " ")
        .replace(",", " ")
    )
    t = _WS.sub(" ", t)
    return t


def _title_case_core(s: str) -> str:
    parts = [p for p in s.split(" ") if p]
    out = []
    for p in parts:
        up = p.upper()
        if up in {
            "VP",
            "SVP",
            "EVP",
            "CEO",
            "CTO",
            "CFO",
            "COO",
            "CMO",
            "CIO",
            "CPO",
            "CSO",
        }:
            out.append(up)
        else:
            out.append(p[:1].upper() + p[1:].lower())
    return " ".join(out)


def normalize_title(text: str) -> Dict[str, Any]:
    raw = _clean_title(text)
    title = _title_case_core(raw)

    seniority = None
    for rx, label in TITLE_SENIORITY_RULES:
        if rx.search(raw):
            seniority = label
            break

    department = None
    for rx, dept in TITLE_DEPT_RULES:
        if rx.search(raw):
            department = dept
            break

    llm_metrics = None
    # Use LLM if either department is missing OR if we want to improve the result
    enable_llm = os.getenv("TRANSFORM_ENABLE_LLM_FALLBACK", "true").lower() == "true"
    if logger.isEnabledFor(logging.DEBUG):
        logger.debug(
            "Title %r: dept=%s seniority=%s enable_llm=%s",
            text,
            department,
            seniority,
            enable_llm,
        )

    if not department and enable_llm:
        provider = _get_llm_provider()
        if logger.isEnabledFor(logging.DEBUG):
            logger.debug("LLM provider: %r", provider)
        if provider:
            schema = {
                "type": "object",
                "properties": {
                    "title": {"type": "string"},
                    "department": {"type": "string"},
                    "seniority": {
                        "type": "string",
                        "enum": ["IC", "Manager", "Director", "VP", "CXO", "Owner"],
                    },
                },
                "required": ["title", "department", "seniority"],
            }
            prompt = (
                f'Normalize the job title; derive department and seniority from: "{text}". '
                "Return JSON with keys: title, department, seniority."
            )
            try:
                out = provider.generate_json(prompt, schema=schema, num_predict=64)
                val = out.get("value") or {}
                title = val.get("title") or title
                department = val.get("department") or department
                seniority = val.get("seniority") or seniority
                # Capture metrics if available
                if "metrics" in out:
                    llm_metrics = out["metrics"]
            except Exception:
                pass

    if not title:
        title = ""
    if not department:
        department = ""
    if not seniority:
        seniority = "IC"

    result = {
        "value": {"title": title, "department": department, "seniority": seniority}
    }

    # Pass through metrics if LLM was used
    if llm_metrics:
        result["metrics"] = llm_metrics

    return result
