"""Avatar execution-plan and security-baseline feature flags (default OFF)."""

from __future__ import annotations

import os


def _env_bool(name: str, *, default: bool = False) -> bool:
    raw = os.getenv(name)
    if raw is None:
        return default
    return raw.strip().lower() in {"1", "true", "yes", "on"}


def avatar_execution_plan_enabled() -> bool:
    return _env_bool("AVATAR_EXECUTION_PLAN_ENABLED", default=True)


def avatar_plan_audit_extended() -> bool:
    return _env_bool("AVATAR_PLAN_AUDIT_EXTENDED", default=False)


def avatar_compound_intent_defer() -> bool:
    raw = os.getenv("AVATAR_COMPOUND_INTENT_DEFER")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_execution_plan_enabled()


def avatar_planner_rules_only() -> bool:
    raw = os.getenv("AVATAR_PLANNER_RULES_ONLY")
    if raw is None:
        return True
    return raw.strip().lower() in {"1", "true", "yes", "on"}


def avatar_llm_planner_enabled() -> bool:
    return _env_bool("AVATAR_LLM_PLANNER_ENABLED", default=True)


def avatar_web_fetch_enabled() -> bool:
    raw = os.getenv("AVATAR_WEB_FETCH_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_execution_plan_enabled()


def avatar_web_fetch_device_local() -> bool:
    return _env_bool("AVATAR_WEB_FETCH_DEVICE_LOCAL", default=False)


def avatar_summarize_cloud_enabled() -> bool:
    raw = os.getenv("AVATAR_SUMMARIZE_CLOUD_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_execution_plan_enabled()


def avatar_plan_executor_enabled() -> bool:
    raw = os.getenv("AVATAR_PLAN_EXECUTOR_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_execution_plan_enabled()


def avatar_plan_max_steps() -> int:
    """Max steps a desktop avatar plan may execute.

    Default 60 covers multi-tab CMS inspect plans (e.g. Genesis Travel ~54 steps).
    Override with AVATAR_PLAN_MAX_STEPS. Hard ceiling 120.
    """
    raw = os.getenv("AVATAR_PLAN_MAX_STEPS")
    if raw is None:
        return 60
    try:
        return max(1, min(120, int(raw)))
    except ValueError:
        return 60


def avatar_plan_stop_on_failure() -> bool:
    return _env_bool("AVATAR_PLAN_STOP_ON_FAILURE", default=True)


def replanning_enabled() -> bool:
    """When true, plan executor may request orchestra revise_plan on step failure hints."""
    return _env_bool("REPLANNING_ENABLED", default=True)


def autonomous_replan_enabled() -> bool:
    """When true, desktop may continue with server-side autonomous revise_plan without user trigger."""
    return _env_bool("AUTONOMOUS_REPLAN_ENABLED", default=True)


def confidence_execution_enabled() -> bool:
    """When true, orchestra confidence posture gates plan execution confirmations."""
    return _env_bool("CONFIDENCE_EXECUTION_ENABLED", default=True)


def avatar_policy_judge_enabled() -> bool:
    raw = os.getenv("AVATAR_POLICY_JUDGE_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_plan_executor_enabled()


def avatar_stop_zones_enabled() -> bool:
    raw = os.getenv("AVATAR_STOP_ZONES_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_policy_judge_enabled()


def avatar_double_confirm_enabled() -> bool:
    raw = os.getenv("AVATAR_DOUBLE_CONFIRM_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_policy_judge_enabled()


def avatar_learning_enrichment_enabled() -> bool:
    return _env_bool("AVATAR_LEARNING_ENRICHMENT_ENABLED", default=False)


def avatar_provider_orchestra_enabled() -> bool:
    return _env_bool("AVATAR_PROVIDER_ORCHESTRA_ENABLED", default=False)


def avatar_local_ollama_fallback_enabled() -> bool:
    """Optional local Ollama fallback when cloud orchestra is unavailable."""
    raw = os.getenv("AVATAR_LOCAL_OLLAMA_FALLBACK_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return _env_bool("AVATAR_LOCAL_OLLAMA_ENABLED", default=False)


def avatar_local_ollama_reachable() -> bool:
    """True when a local Ollama daemon responds on the configured base URL."""
    try:
        from urllib.request import Request, urlopen

        from iuve_connect_agents.shared.avatar_llm_advisory import advisory_ollama_base_url

        request = Request(f"{advisory_ollama_base_url().rstrip('/')}/api/tags", method="GET")
        with urlopen(request, timeout=2):
            return True
    except Exception:
        return False


def avatar_cloud_llm_available() -> bool:
    """True when the desktop agent can call iuve.eu cloud orchestra."""
    try:
        from iuve_connect_agents.shared.avatar_llm_cloud import cloud_llm_credentials_available

        return cloud_llm_credentials_available()
    except Exception:
        return False


def avatar_llm_intent_enabled(*, trust_state: str = "") -> bool:
    raw = os.getenv("AVATAR_LLM_INTENT_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return str(trust_state or "").strip().lower() == "trusted"


def avatar_llm_backend_available() -> bool:
    """True when cloud orchestra or local Ollama can serve LLM intent/advisory."""
    if avatar_cloud_llm_available():
        return True

    if avatar_provider_orchestra_enabled():
        try:
            from app.provider_orchestra.orchestra_service import orchestra_service

            if orchestra_service.is_enabled():
                return True
        except Exception:
            pass

    if avatar_local_ollama_fallback_enabled() and avatar_local_ollama_reachable():
        return True

    try:
        from app.core.config import settings

        if str(getattr(settings, "OPENAI_API_KEY", "") or "").strip():
            return True
    except Exception:
        pass

    return False


def avatar_llm_intent_first_enabled(*, trust_state: str = "") -> bool:
    """LLM-first intent routing; default on when a backend is reachable."""
    raw = os.getenv("AVATAR_LLM_INTENT_FIRST_ENABLED")
    if raw is not None:
        enabled = raw.strip().lower() in {"1", "true", "yes", "on"}
    else:
        enabled = avatar_llm_backend_available()
    if not enabled:
        return False
    return avatar_llm_intent_enabled(trust_state=trust_state)


def avatar_llm_advisory_enabled(*, trust_state: str = "") -> bool:
    raw = os.getenv("AVATAR_LLM_ADVISORY_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return str(trust_state or "").strip().lower() == "trusted"


def avatar_verifier_enabled() -> bool:
    return _env_bool("AVATAR_VERIFIER_ENABLED", default=False)


def avatar_desktop_vision_enabled(*, screen_vision_granted: bool | None = None) -> bool:
    from iuve_connect_agents.shared.screen_vision_gate import desktop_vision_enabled

    return desktop_vision_enabled(screen_vision_granted=screen_vision_granted)


def avatar_desktop_vision_local_enabled(*, screen_vision_granted: bool | None = None) -> bool:
    if not avatar_desktop_vision_enabled(screen_vision_granted=screen_vision_granted):
        return False
    return _env_bool("AVATAR_DESKTOP_VISION_LOCAL_ENABLED", default=False)


def avatar_desktop_vision_cloud_enabled(*, screen_vision_granted: bool | None = None) -> bool:
    if not avatar_desktop_vision_enabled(screen_vision_granted=screen_vision_granted):
        return False
    return _env_bool("AVATAR_DESKTOP_VISION_CLOUD_ENABLED", default=False)


def cloud_vision_verify_available(*, screen_vision_granted: bool | None = None) -> bool:
    """True when cloud orchestra verify may be attempted (explicit flag or paired + orchestra)."""
    if avatar_desktop_vision_cloud_enabled(screen_vision_granted=screen_vision_granted):
        return True
    if not avatar_desktop_vision_enabled(screen_vision_granted=screen_vision_granted):
        return False
    try:
        from iuve_connect_agents.shared.avatar_llm_cloud import cloud_llm_credentials_available

        if not cloud_llm_credentials_available():
            return False
    except Exception:
        return False
    try:
        from iuve_connect_agents.desktop.orchestra_status_service import probe_orchestra_status

        snap = probe_orchestra_status()
        return bool(snap.cloud_credentials and snap.cloud_reachable and snap.orchestra_available)
    except Exception:
        return False


def avatar_desktop_vision_fail_closed() -> bool:
    return _env_bool("AVATAR_DESKTOP_VISION_FAIL_CLOSED", default=True)


def avatar_chat_file_drop_enabled() -> bool:
    return _env_bool("AVATAR_CHAT_FILE_DROP_ENABLED", default=True)


def voice_presence_enabled() -> bool:
    return _env_bool("VOICE_PRESENCE_ENABLED", default=False)


def voice_wake_word_enabled() -> bool:
    return _env_bool("VOICE_WAKE_WORD_ENABLED", default=False)


def avatar_evidence_collector_enabled() -> bool:
    raw = os.getenv("AVATAR_EVIDENCE_COLLECTOR_ENABLED")
    if raw is not None:
        return raw.strip().lower() in {"1", "true", "yes", "on"}
    return avatar_desktop_vision_enabled()


# --- Security baseline flags (0.2.2.3 audit; default OFF, not enforced yet) ---


def iuve_release_signature_required() -> bool:
    """When enabled (future), block in-place upgrade unless release signature is valid."""
    return _env_bool("IUVE_RELEASE_SIGNATURE_REQUIRED", default=False)


def iuve_update_checksum_required() -> bool:
    """When enabled (future), require checksum verification before any update install."""
    return _env_bool("IUVE_UPDATE_CHECKSUM_REQUIRED", default=False)


def iuve_package_allowlist_strict() -> bool:
    """When enabled (future), fail package build if allowlist drifts from policy."""
    return _env_bool("IUVE_PACKAGE_ALLOWLIST_STRICT", default=False)


def iuve_device_capability_enforcement_strict() -> bool:
    """When enabled (future), deny commands when device capability profile is stale."""
    return _env_bool("IUVE_DEVICE_CAPABILITY_ENFORCEMENT_STRICT", default=False)
