import os
import sys
from importlib.util import find_spec
from pathlib import Path
from dotenv import load_dotenv
from analogai.deepthink.infrastructure.gateways.llm.enums.llm_gateway_type import LlmGatewayType

def _find_project_root(start: Path) -> Path | None:
    current = start
    while True:
        if (current / "pyproject.toml").exists() or (current / ".env").exists():
            return current
        if current.parent == current:
            return None
        current = current.parent


def _find_module_root(module_name: str) -> Path | None:
    spec = find_spec(module_name)
    if spec and spec.origin:
        return _find_project_root(Path(spec.origin).resolve())
    return None


def _ordered_env_roots() -> list[Path]:
    roots: list[Path] = []
    env_file = os.getenv("ENV_FILE")
    if env_file:
        env_path = Path(env_file).expanduser().resolve()
        roots.append(env_path.parent)

    argv0 = Path(sys.argv[0]).expanduser().resolve() if sys.argv and sys.argv[0] else None
    if argv0 and argv0.exists():
        entry_root = _find_project_root(argv0.parent)
        if entry_root:
            roots.append(entry_root)

    deepthink_root = _find_module_root("deepthink")
    if deepthink_root:
        roots.append(deepthink_root)

    analogai_root = _find_module_root("analogai")
    if analogai_root:
        roots.append(analogai_root)

    seen: set[Path] = set()
    ordered: list[Path] = []
    for root in roots:
        if root not in seen:
            ordered.append(root)
            seen.add(root)
    return ordered


def _load_envs_in_order() -> None:
    for root in _ordered_env_roots():
        env_path = root / ".env"
        if env_path.exists():
            load_dotenv(env_path, override=False)


_load_envs_in_order()

ENVIRONMENT = os.getenv('ENVIRONMENT', 'development')

if ENVIRONMENT not in ['development', 'production']:
    raise ValueError(f"Environment variable ENVIRONMENT must be one of: development or production")

QUICK_TESTING = os.getenv('QUICK_TESTING', 'false').lower() == 'true'
FINAL_APPLICATION_TESTING = os.getenv('FINAL_APPLICATION_TESTING', 'false').lower() == 'true'
if FINAL_APPLICATION_TESTING:
    QUICK_TESTING = False

DEBUG = os.getenv('DEBUG', 'false').lower() == 'true'

if QUICK_TESTING:
    LLM_PROCESSING_ENABLED = False
    NOTION_ENRICHMENT_ENABLED = False
    # NOTION_ENRICHMENT_ENABLED = False
    # STATEMENT_DECOMPOSITION_ENABLED = False
    print(f"QUICK_TESTING mode enabled - LLM_PROCESSING_ENABLED={LLM_PROCESSING_ENABLED}")
else:
    LLM_PROCESSING_ENABLED = os.getenv('LLM_PROCESSING_ENABLED', 'true').lower() == 'true'
    NOTION_ENRICHMENT_ENABLED = os.getenv('NOTION_ENRICHMENT_ENABLED', 'true').lower() == 'true'

    # NOTION_ENRICHMENT_ENABLED = os.getenv('NOTION_ENRICHMENT_ENABLED', 'true').lower() == 'true'
    # STATEMENT_DECOMPOSITION_ENABLED = os.getenv('STATEMENT_DECOMPOSITION_ENABLED', 'false').lower() == 'true'
    print(f"QUICK_TESTING mode disabled LLM_PROCESSING_ENABLED={LLM_PROCESSING_ENABLED}")

TIME_SENSITIVE_TRANSFORMATIONS_ENABLED = os.getenv('TIME_SENSITIVE_TRANSFORMATIONS_ENABLED', 'false').lower() == 'true'

PROBABILITY_THRESHOLD = 0.4

ENRICHMENT_LIMIT = 10


def _parse_int(value: str | None, default: int) -> int:
    try:
        return int(str(value).strip())
    except Exception:
        return default


def _parse_optional_float(value: str | None, default: float | None = None) -> float | None:
    if value is None:
        return default
    text = str(value).strip()
    if not text:
        return default
    try:
        return float(text)
    except Exception:
        return default


def _parse_bool(value: str | None, default: bool) -> bool:
    if value is None:
        return default
    text = str(value).strip().lower()
    if text in {"1", "true", "yes", "y", "on"}:
        return True
    if text in {"0", "false", "no", "n", "off"}:
        return False
    return default


QUESTION_ANSWERING_MAX_BELIEFS = _parse_int(
    os.getenv("QUESTION_ANSWERING_MAX_BELIEFS", "12"),
    12,
)

QUESTION_ANSWERING_MAX_ENTITY_DEPTH = _parse_int(
    os.getenv("QUESTION_ANSWERING_MAX_ENTITY_DEPTH", "3"),
    3,
)

USE_VECTOR_SEARCH = _parse_bool(os.getenv("USE_VECTOR_SEARCH"), True)
SIMILARITY_CUTOFF = _parse_optional_float(os.getenv("SIMILARITY_CUTOFF"), 0.4)


def _resolve_llm_gateway_type(value: str) -> LlmGatewayType:
    normalized = (value or "").strip().lower().replace("-", "_")
    mapping = {
        "anthropic": LlmGatewayType.ANTHROPIC,
        "claude": LlmGatewayType.ANTHROPIC,
        "openai": LlmGatewayType.OPENAI,
        "azure": LlmGatewayType.AZURE,
        "azure_openai": LlmGatewayType.AZURE_OPENAI,
        "azureopenai": LlmGatewayType.AZURE_OPENAI,
        "grok": LlmGatewayType.GROK,
        "xai": LlmGatewayType.GROK,
        "grok3": LlmGatewayType.GROK,
        "grok4_fast_non_reasoning": LlmGatewayType.GROK,
        "bedrock": LlmGatewayType.BEDROCK,

        # Backward-compatible keys mapped to Azure
        "azure_gpt4o_mini": LlmGatewayType.AZURE,
        "azure_gpt4o": LlmGatewayType.AZURE,
        "azure_gpt4_1_nano": LlmGatewayType.AZURE,
        "azure_openai_gpt5_1_chat": LlmGatewayType.AZURE_OPENAI,
        "azure_openai_gpt5_2_chat": LlmGatewayType.AZURE_OPENAI,
        "azure_openai_codex_mini": LlmGatewayType.AZURE_OPENAI,
        "azure_deepseek_r1": LlmGatewayType.AZURE,
        "azure_deepseek_v3_2": LlmGatewayType.AZURE,
        "gpt4o_mini": LlmGatewayType.AZURE,
        "gpt4o": LlmGatewayType.AZURE,
        "gpt4_1_nano": LlmGatewayType.AZURE,
        "gpt5_1_chat": LlmGatewayType.AZURE,
        "gpt5_2_chat": LlmGatewayType.AZURE,
        "codex_mini": LlmGatewayType.AZURE,
        "deepseek_r1": LlmGatewayType.AZURE,
        "deepseek_v3_2": LlmGatewayType.AZURE,
    }
    if normalized in mapping:
        return mapping[normalized]
    raise ValueError(
        "Unknown DEFAULT_LLM_GATEWAY_TYPE value: "
        f"'{value}'. Please provide a valid gateway type."
    )


_DEFAULT_LLM_GATEWAY_TYPE_VALUE = os.getenv("DEFAULT_LLM_GATEWAY_TYPE")
DEFAULT_LLM_GATEWAY_TYPE = (
    _resolve_llm_gateway_type(_DEFAULT_LLM_GATEWAY_TYPE_VALUE)
    if _DEFAULT_LLM_GATEWAY_TYPE_VALUE
    else None
)




# STATEMENT_DECOMPOSITION_ENABLED = os.getenv('STATEMENT_DECOMPOSITION_ENABLED', 'true').lower() == 'true'

print(f"Environment is set to {ENVIRONMENT} at Thinker")
