from __future__ import annotations

from collections.abc import Callable
from pathlib import Path
from typing import Any

from ace_lite.index_stage.candidate_fusion import (
    CandidateFusionDeps,
    CandidateFusionResult,
)


def run_index_candidate_fusion(
    *,
    root: str,
    repo: str,
    query: str,
    terms: list[str],
    files_map: dict[str, Any],
    candidates: list[dict[str, Any]],
    memory_paths: list[str],
    docs_payload: dict[str, Any],
    policy: dict[str, Any],
    selected_ranker: str,
    top_k_files: int,
    candidate_relative_threshold: float,
    refine_enabled: bool,
    rank_candidates: Callable[..., list[dict[str, Any]]],
    index_hash: str,
    cochange_enabled: bool,
    cochange_cache_path: str,
    cochange_lookback_commits: int,
    cochange_half_life_days: float,
    cochange_neighbor_cap: int,
    cochange_top_neighbors: int,
    cochange_boost_weight: float,
    cochange_min_neighbor_score: float,
    cochange_max_boost: float,
    scip_enabled: bool,
    scip_index_path: str,
    scip_provider: str,
    scip_generate_fallback: bool,
    scip_base_weight: float,
    embedding_index_path: str | Path,
    embedding_enabled: bool,
    embedding_provider: str,
    embedding_model: str,
    embedding_dimension: int,
    embedding_rerank_pool: int,
    embedding_lexical_weight: float,
    embedding_semantic_weight: float,
    embedding_min_similarity: float,
    embedding_fail_open: bool,
    feedback_enabled: bool,
    feedback_path: str,
    feedback_max_entries: int,
    feedback_boost_per_select: float,
    feedback_max_boost: float,
    feedback_decay_days: float,
    multi_channel_rrf_enabled: bool,
    multi_channel_rrf_k: int,
    multi_channel_rrf_pool_cap: int,
    multi_channel_rrf_code_cap: int,
    multi_channel_rrf_docs_cap: int,
    multi_channel_rrf_memory_cap: int,
    refine_candidate_pool_fn: Callable[..., CandidateFusionResult],
    postprocess_candidates_fn: Callable[..., Any],
    apply_structural_rerank_fn: Callable[..., Any],
    apply_semantic_candidate_rerank_fn: Callable[..., Any],
    apply_feedback_boost_fn: Callable[..., tuple[list[dict[str, Any]], dict[str, Any]]],
    apply_multi_channel_rrf_fusion_fn: Callable[
        ..., tuple[list[dict[str, Any]], dict[str, Any]]
    ],
    merge_candidate_lists_fn: Callable[..., list[dict[str, Any]]],
    resolve_embedding_runtime_config_fn: Callable[..., Any],
    build_embedding_stats_fn: Callable[..., dict[str, Any]],
    rerank_cross_encoder_with_time_budget_fn: Callable[
        ..., tuple[list[dict[str, Any]], Any]
    ],
    mark_timing_fn: Callable[[str, float], None],
    retrieval_refinement: dict[str, Any] | None = None,
) -> CandidateFusionResult:
    return refine_candidate_pool_fn(
        root=root,
        repo=repo,
        query=query,
        terms=terms,
        files_map=files_map,
        candidates=candidates,
        memory_paths=memory_paths,
        docs_payload=docs_payload,
        policy=policy,
        selected_ranker=selected_ranker,
        top_k_files=int(top_k_files),
        candidate_relative_threshold=float(candidate_relative_threshold),
        refine_enabled=bool(refine_enabled),
        rank_candidates=rank_candidates,
        index_hash=index_hash,
        cochange_enabled=bool(cochange_enabled),
        cochange_cache_path=str(cochange_cache_path),
        cochange_lookback_commits=int(cochange_lookback_commits),
        cochange_half_life_days=float(cochange_half_life_days),
        cochange_neighbor_cap=int(cochange_neighbor_cap),
        cochange_top_neighbors=int(cochange_top_neighbors),
        cochange_boost_weight=float(cochange_boost_weight),
        cochange_min_neighbor_score=float(cochange_min_neighbor_score),
        cochange_max_boost=float(cochange_max_boost),
        scip_enabled=bool(scip_enabled),
        scip_index_path=str(scip_index_path),
        scip_provider=str(scip_provider),
        scip_generate_fallback=bool(scip_generate_fallback),
        scip_base_weight=float(scip_base_weight),
        embedding_index_path=embedding_index_path,
        embedding_enabled=bool(embedding_enabled),
        embedding_provider=str(embedding_provider),
        embedding_model=str(embedding_model),
        embedding_dimension=int(embedding_dimension),
        embedding_rerank_pool=int(embedding_rerank_pool),
        embedding_lexical_weight=float(embedding_lexical_weight),
        embedding_semantic_weight=float(embedding_semantic_weight),
        embedding_min_similarity=float(embedding_min_similarity),
        embedding_fail_open=bool(embedding_fail_open),
        feedback_enabled=bool(feedback_enabled),
        feedback_path=str(feedback_path),
        feedback_max_entries=int(feedback_max_entries),
        feedback_boost_per_select=float(feedback_boost_per_select),
        feedback_max_boost=float(feedback_max_boost),
        feedback_decay_days=float(feedback_decay_days),
        multi_channel_rrf_enabled=bool(multi_channel_rrf_enabled),
        multi_channel_rrf_k=int(multi_channel_rrf_k),
        multi_channel_rrf_pool_cap=int(multi_channel_rrf_pool_cap),
        multi_channel_rrf_code_cap=int(multi_channel_rrf_code_cap),
        multi_channel_rrf_docs_cap=int(multi_channel_rrf_docs_cap),
        multi_channel_rrf_memory_cap=int(multi_channel_rrf_memory_cap),
        retrieval_refinement=retrieval_refinement,
        deps=CandidateFusionDeps(
            postprocess_candidates=postprocess_candidates_fn,
            apply_structural_rerank=apply_structural_rerank_fn,
            apply_semantic_candidate_rerank=apply_semantic_candidate_rerank_fn,
            apply_feedback_boost=apply_feedback_boost_fn,
            apply_multi_channel_rrf_fusion=apply_multi_channel_rrf_fusion_fn,
            merge_candidate_lists=merge_candidate_lists_fn,
            resolve_embedding_runtime_config=resolve_embedding_runtime_config_fn,
            build_embedding_stats=build_embedding_stats_fn,
            rerank_cross_encoder_with_time_budget=(
                rerank_cross_encoder_with_time_budget_fn
            ),
            mark_timing=mark_timing_fn,
        ),
    )


__all__ = ["run_index_candidate_fusion"]
