"""Configuration loading + layered parameter resolution for CLI commands."""

from __future__ import annotations

from typing import Any

import click

from ace_lite.cli_app.config import (
    resolve_memory_config,
    resolve_quality_config,
    resolve_retrieval_and_lsp_config,
)
from ace_lite.cli_app.config_resolve_helpers import (
    _apply_plan_namespace_overlays,
    _load_command_config,
    _parameter_is_default,
    _resolve_from_config,
    _resolve_from_layers,
)


def _resolve_shared_plan_config(
    *,
    ctx: click.Context,
    config: dict[str, Any],
    namespace: str,
    config_pack: str | None,
    runtime_profile: str | None,
    retrieval_preset: str,
    adaptive_router_enabled: bool,
    adaptive_router_mode: str,
    adaptive_router_model_path: str,
    adaptive_router_state_path: str,
    adaptive_router_arm_set: str,
    top_k_files: int,
    min_candidate_score: int,
    candidate_relative_threshold: float,
    candidate_ranker: str,
    exact_search_enabled: bool,
    deterministic_refine_enabled: bool,
    exact_search_time_budget_ms: int,
    exact_search_max_paths: int,
    hybrid_re2_fusion_mode: str,
    hybrid_re2_rrf_k: int,
    hybrid_re2_bm25_weight: float = 0.0,
    hybrid_re2_heuristic_weight: float = 0.0,
    hybrid_re2_coverage_weight: float = 0.0,
    hybrid_re2_combined_scale: float = 0.0,
    embedding_enabled: bool,
    embedding_provider: str,
    embedding_model: str,
    embedding_dimension: int,
    embedding_index_path: str,
    embedding_rerank_pool: int,
    embedding_lexical_weight: float,
    embedding_semantic_weight: float,
    embedding_min_similarity: float,
    embedding_fail_open: bool,
    languages: str,
    index_cache_path: str,
    index_incremental: bool,
    conventions_files: tuple[str, ...],
    plugins_enabled: bool,
    remote_slot_policy_mode: str,
    remote_slot_allowlist: str,
    repomap_enabled: bool,
    repomap_top_k: int,
    repomap_neighbor_limit: int,
    repomap_budget_tokens: int,
    repomap_ranking_profile: str,
    repomap_signal_weights: dict[str, float] | None,
    lsp_enabled: bool,
    lsp_top_n: int,
    lsp_cmds: tuple[str, ...],
    lsp_xref_enabled: bool,
    lsp_xref_top_n: int,
    lsp_time_budget_ms: int,
    lsp_xref_cmds: tuple[str, ...],
    memory_disclosure_mode: str,
    memory_preview_max_chars: int,
    memory_strategy: str,
    memory_gate_enabled: bool,
    memory_gate_mode: str,
    memory_cache_enabled: bool,
    memory_cache_path: str,
    memory_cache_ttl_seconds: int,
    memory_cache_max_entries: int,
    memory_timeline_enabled: bool,
    memory_container_tag: str | None,
    memory_auto_tag_mode: str | None,
    memory_profile_enabled: bool,
    memory_profile_path: str,
    memory_profile_top_n: int,
    memory_profile_token_budget: int,
    memory_profile_expiry_enabled: bool,
    memory_profile_ttl_days: int,
    memory_profile_max_age_days: int,
    memory_feedback_enabled: bool,
    memory_feedback_path: str,
    memory_feedback_max_entries: int,
    memory_feedback_boost_per_select: float,
    memory_feedback_max_boost: float,
    memory_feedback_decay_days: float,
    memory_capture_enabled: bool,
    memory_capture_notes_path: str,
    memory_capture_min_query_length: int,
    memory_capture_keywords: list[str] | tuple[str, ...] | str,
    memory_notes_enabled: bool,
    memory_notes_path: str,
    memory_notes_limit: int,
    memory_notes_mode: str,
    memory_notes_expiry_enabled: bool,
    memory_notes_ttl_days: int,
    memory_notes_max_age_days: int,
    memory_postprocess_enabled: bool,
    memory_postprocess_noise_filter_enabled: bool,
    memory_postprocess_length_norm_anchor_chars: int,
    memory_postprocess_time_decay_half_life_days: float,
    memory_postprocess_hard_min_score: float,
    memory_postprocess_diversity_enabled: bool,
    memory_postprocess_diversity_similarity_threshold: float,
    precomputed_skills_routing_enabled: bool,
    plan_replay_cache_enabled: bool,
    plan_replay_cache_path: str,
    memory_hybrid_limit: int,
    chunk_top_k: int,
    chunk_per_file_limit: int,
    chunk_disclosure: str,
    chunk_signature: bool,
    chunk_snippet_max_lines: int,
    chunk_snippet_max_chars: int,
    chunk_token_budget: int,
    chunk_guard_enabled: bool,
    chunk_guard_mode: str,
    chunk_guard_lambda_penalty: float,
    chunk_guard_min_pool: int,
    chunk_guard_max_pool: int,
    chunk_guard_min_marginal_utility: float,
    chunk_guard_compatibility_min_overlap: float,
    chunk_diversity_enabled: bool,
    chunk_diversity_path_penalty: float,
    chunk_diversity_symbol_family_penalty: float,
    chunk_diversity_kind_penalty: float,
    chunk_diversity_locality_penalty: float,
    chunk_diversity_locality_window: int,
    tokenizer_model: str,
    cochange_enabled: bool,
    cochange_cache_path: str,
    cochange_lookback_commits: int,
    cochange_half_life_days: float,
    cochange_top_neighbors: int,
    cochange_boost_weight: float,
    retrieval_policy: str,
    policy_version: str,
    junit_xml: str | None,
    coverage_json: str | None,
    sbfl_json: str | None,
    sbfl_metric: str,
    scip_enabled: bool,
    scip_index_path: str,
    scip_provider: str,
    scip_generate_fallback: bool,
    trace_export_enabled: bool,
    trace_export_path: str,
    trace_otlp_enabled: bool,
    trace_otlp_endpoint: str,
    trace_otlp_timeout_seconds: float,
) -> dict[str, Any]:
    selected_runtime_profile = _resolve_from_config(
        ctx=ctx,
        param_name="runtime_profile",
        current=runtime_profile,
        config=config,
        paths=[(namespace, "runtime_profile")],
        transform=lambda value: str(value or "").strip().lower() or None,
    )
    resolved_profile_name = _apply_plan_namespace_overlays(
        config=config,
        namespace=namespace,
        runtime_profile=selected_runtime_profile,
        retrieval_preset=retrieval_preset,
        config_pack=config_pack,
    )

    retrieval_payload = resolve_retrieval_and_lsp_config(
        ctx=ctx,
        config=config,
        namespace=namespace,
        retrieval_preset="none",
        adaptive_router_enabled=adaptive_router_enabled,
        adaptive_router_mode=adaptive_router_mode,
        adaptive_router_model_path=adaptive_router_model_path,
        adaptive_router_state_path=adaptive_router_state_path,
        adaptive_router_arm_set=adaptive_router_arm_set,
        top_k_files=top_k_files,
        min_candidate_score=min_candidate_score,
        candidate_relative_threshold=candidate_relative_threshold,
        candidate_ranker=candidate_ranker,
        exact_search_enabled=exact_search_enabled,
        deterministic_refine_enabled=deterministic_refine_enabled,
        exact_search_time_budget_ms=exact_search_time_budget_ms,
        exact_search_max_paths=exact_search_max_paths,
        hybrid_re2_fusion_mode=hybrid_re2_fusion_mode,
        hybrid_re2_rrf_k=hybrid_re2_rrf_k,
        hybrid_re2_bm25_weight=hybrid_re2_bm25_weight,
        hybrid_re2_heuristic_weight=hybrid_re2_heuristic_weight,
        hybrid_re2_coverage_weight=hybrid_re2_coverage_weight,
        hybrid_re2_combined_scale=hybrid_re2_combined_scale,
        embedding_enabled=embedding_enabled,
        embedding_provider=embedding_provider,
        embedding_model=embedding_model,
        embedding_dimension=embedding_dimension,
        embedding_index_path=embedding_index_path,
        embedding_rerank_pool=embedding_rerank_pool,
        embedding_lexical_weight=embedding_lexical_weight,
        embedding_semantic_weight=embedding_semantic_weight,
        embedding_min_similarity=embedding_min_similarity,
        embedding_fail_open=embedding_fail_open,
        languages=languages,
        index_cache_path=index_cache_path,
        index_incremental=index_incremental,
        conventions_files=conventions_files,
        plugins_enabled=plugins_enabled,
        remote_slot_policy_mode=remote_slot_policy_mode,
        remote_slot_allowlist=remote_slot_allowlist,
        repomap_enabled=repomap_enabled,
        repomap_top_k=repomap_top_k,
        repomap_neighbor_limit=repomap_neighbor_limit,
        repomap_budget_tokens=repomap_budget_tokens,
        repomap_ranking_profile=repomap_ranking_profile,
        repomap_signal_weights=repomap_signal_weights,
        lsp_enabled=lsp_enabled,
        lsp_top_n=lsp_top_n,
        lsp_cmds=lsp_cmds,
        lsp_xref_enabled=lsp_xref_enabled,
        lsp_xref_top_n=lsp_xref_top_n,
        lsp_time_budget_ms=lsp_time_budget_ms,
        lsp_xref_cmds=lsp_xref_cmds,
    )
    memory_payload = resolve_memory_config(
        ctx=ctx,
        config=config,
        namespace=namespace,
        memory_disclosure_mode=memory_disclosure_mode,
        memory_preview_max_chars=memory_preview_max_chars,
        memory_strategy=memory_strategy,
        memory_gate_enabled=memory_gate_enabled,
        memory_gate_mode=memory_gate_mode,
        memory_cache_enabled=memory_cache_enabled,
        memory_cache_path=memory_cache_path,
        memory_cache_ttl_seconds=memory_cache_ttl_seconds,
        memory_cache_max_entries=memory_cache_max_entries,
        memory_timeline_enabled=memory_timeline_enabled,
        memory_container_tag=memory_container_tag,
        memory_auto_tag_mode=memory_auto_tag_mode,
        memory_profile_enabled=memory_profile_enabled,
        memory_profile_path=memory_profile_path,
        memory_profile_top_n=memory_profile_top_n,
        memory_profile_token_budget=memory_profile_token_budget,
        memory_profile_expiry_enabled=memory_profile_expiry_enabled,
        memory_profile_ttl_days=memory_profile_ttl_days,
        memory_profile_max_age_days=memory_profile_max_age_days,
        memory_feedback_enabled=memory_feedback_enabled,
        memory_feedback_path=memory_feedback_path,
        memory_feedback_max_entries=memory_feedback_max_entries,
        memory_feedback_boost_per_select=memory_feedback_boost_per_select,
        memory_feedback_max_boost=memory_feedback_max_boost,
        memory_feedback_decay_days=memory_feedback_decay_days,
        memory_capture_enabled=memory_capture_enabled,
        memory_capture_notes_path=memory_capture_notes_path,
        memory_capture_min_query_length=memory_capture_min_query_length,
        memory_capture_keywords=memory_capture_keywords,
        memory_notes_enabled=memory_notes_enabled,
        memory_notes_path=memory_notes_path,
        memory_notes_limit=memory_notes_limit,
        memory_notes_mode=memory_notes_mode,
        memory_notes_expiry_enabled=memory_notes_expiry_enabled,
        memory_notes_ttl_days=memory_notes_ttl_days,
        memory_notes_max_age_days=memory_notes_max_age_days,
        memory_postprocess_enabled=memory_postprocess_enabled,
        memory_postprocess_noise_filter_enabled=memory_postprocess_noise_filter_enabled,
        memory_postprocess_length_norm_anchor_chars=memory_postprocess_length_norm_anchor_chars,
        memory_postprocess_time_decay_half_life_days=memory_postprocess_time_decay_half_life_days,
        memory_postprocess_hard_min_score=memory_postprocess_hard_min_score,
        memory_postprocess_diversity_enabled=memory_postprocess_diversity_enabled,
        memory_postprocess_diversity_similarity_threshold=memory_postprocess_diversity_similarity_threshold,
        memory_hybrid_limit=memory_hybrid_limit,
        tokenizer_model=tokenizer_model,
    )
    quality_payload = resolve_quality_config(
        ctx=ctx,
        config=config,
        namespace=namespace,
        chunk_top_k=chunk_top_k,
        chunk_per_file_limit=chunk_per_file_limit,
        chunk_disclosure=chunk_disclosure,
        chunk_signature=chunk_signature,
        chunk_snippet_max_lines=chunk_snippet_max_lines,
        chunk_snippet_max_chars=chunk_snippet_max_chars,
        chunk_token_budget=chunk_token_budget,
        chunk_guard_enabled=chunk_guard_enabled,
        chunk_guard_mode=chunk_guard_mode,
        chunk_guard_lambda_penalty=chunk_guard_lambda_penalty,
        chunk_guard_min_pool=chunk_guard_min_pool,
        chunk_guard_max_pool=chunk_guard_max_pool,
        chunk_guard_min_marginal_utility=chunk_guard_min_marginal_utility,
        chunk_guard_compatibility_min_overlap=chunk_guard_compatibility_min_overlap,
        chunk_diversity_enabled=chunk_diversity_enabled,
        chunk_diversity_path_penalty=chunk_diversity_path_penalty,
        chunk_diversity_symbol_family_penalty=chunk_diversity_symbol_family_penalty,
        chunk_diversity_kind_penalty=chunk_diversity_kind_penalty,
        chunk_diversity_locality_penalty=chunk_diversity_locality_penalty,
        chunk_diversity_locality_window=chunk_diversity_locality_window,
        cochange_enabled=cochange_enabled,
        cochange_cache_path=cochange_cache_path,
        cochange_lookback_commits=cochange_lookback_commits,
        cochange_half_life_days=cochange_half_life_days,
        cochange_top_neighbors=cochange_top_neighbors,
        cochange_boost_weight=cochange_boost_weight,
        retrieval_policy=retrieval_policy,
        policy_version=policy_version,
        junit_xml=junit_xml,
        coverage_json=coverage_json,
        sbfl_json=sbfl_json,
        sbfl_metric=sbfl_metric,
        scip_enabled=scip_enabled,
        scip_index_path=scip_index_path,
        scip_provider=scip_provider,
        scip_generate_fallback=scip_generate_fallback,
        trace_export_enabled=trace_export_enabled,
        trace_export_path=trace_export_path,
        trace_otlp_enabled=trace_otlp_enabled,
        trace_otlp_endpoint=trace_otlp_endpoint,
        trace_otlp_timeout_seconds=trace_otlp_timeout_seconds,
    )
    precomputed_skills_routing_enabled = _resolve_from_config(
        ctx=ctx,
        param_name="precomputed_skills_routing_enabled",
        current=precomputed_skills_routing_enabled,
        config=config,
        paths=[
            (namespace, "skills", "precomputed_routing_enabled"),
            (namespace, "precomputed_skills_routing_enabled"),
        ],
    )
    plan_replay_cache_enabled = _resolve_from_config(
        ctx=ctx,
        param_name="plan_replay_cache_enabled",
        current=plan_replay_cache_enabled,
        config=config,
        paths=[
            (namespace, "plan_replay_cache", "enabled"),
            (namespace, "plan_replay_cache_enabled"),
        ],
    )
    plan_replay_cache_path = _resolve_from_config(
        ctx=ctx,
        param_name="plan_replay_cache_path",
        current=plan_replay_cache_path,
        config=config,
        paths=[
            (namespace, "plan_replay_cache", "cache_path"),
            (namespace, "plan_replay_cache_path"),
        ],
        transform=lambda value: str(value or "").strip()
        or "context-map/plan-replay/cache.json",
    )
    plan_replay_cache_payload = {
        "enabled": bool(plan_replay_cache_enabled),
        "cache_path": str(plan_replay_cache_path).strip()
        or "context-map/plan-replay/cache.json",
    }
    skills_payload = {
        "precomputed_routing_enabled": bool(precomputed_skills_routing_enabled),
    }
    return {
        **retrieval_payload,
        **memory_payload,
        **quality_payload,
        "runtime_profile": resolved_profile_name,
        "precomputed_skills_routing_enabled": bool(
            precomputed_skills_routing_enabled
        ),
        "skills": skills_payload,
        "plan_replay_cache_enabled": plan_replay_cache_payload["enabled"],
        "plan_replay_cache_path": plan_replay_cache_payload["cache_path"],
        "plan_replay_cache": plan_replay_cache_payload,
    }


__all__ = [
    "_load_command_config",
    "_parameter_is_default",
    "_resolve_from_config",
    "_resolve_from_layers",
    "_resolve_shared_plan_config",
]
