"""
Background task handlers for CodeContext server.

These functions run periodically to process conflicts and consolidation.
"""

import asyncio
from typing import Dict, Optional, Callable

from ..memory_consolidator import find_clusters, run_consolidation
from .conflict_resolver import auto_resolve_conflicts, resolve_single_conflict

from .store_manager import list_projects, get_store


# Global state for background tasks (managed by server.py)
_server_config: Dict = {}
_periodic_task: Optional[asyncio.Task] = None
_auto_resolve_task: Optional[asyncio.Task] = None


def set_config(config: Dict):
    """Set the server configuration (called by server.py)."""
    global _server_config
    _server_config = config


def get_config() -> Dict:
    """Get current server configuration."""
    return _server_config


async def periodic_consolidation_loop(interval_minutes: int):
    """Background loop that runs consolidation periodically."""
    print(f"[Periodic] Started consolidation loop (every {interval_minutes} min)")
    while True:
        await asyncio.sleep(interval_minutes * 60)

        threshold = _server_config.get("auto_consolidation", {}).get("threshold", 0.5)

        # Scan all projects
        for project_name in list_projects():
            try:
                store = get_store(project_name)
                clusters = find_clusters(store, threshold)

                if clusters:
                    print(f"[Periodic] Found {len(clusters)} clusters in {project_name}")
                    # Run consolidation (will use AI only if needed)
                    report = await run_consolidation(
                        store=store,
                        project=project_name,
                        distance_threshold=threshold,
                        max_clusters=10,
                        preview=False
                    )
                    print(f"[Periodic] {project_name}: processed {report.clusters_processed}, deleted {report.deleted}")

            except Exception as e:
                print(f"[Periodic] Error scanning {project_name}: {e}")


def start_periodic_consolidation(interval_minutes: int):
    """Start the periodic consolidation background task."""
    global _periodic_task
    stop_periodic_consolidation()  # Stop any existing task
    _periodic_task = asyncio.create_task(
        periodic_consolidation_loop(interval_minutes)
    )
    print(f"[Server] Started periodic consolidation (every {interval_minutes} min)")


def stop_periodic_consolidation():
    """Stop the periodic consolidation background task."""
    global _periodic_task
    if _periodic_task:
        _periodic_task.cancel()
        _periodic_task = None
        print("[Server] Stopped periodic consolidation")


async def process_existing_conflicts_background():
    """Background task to auto-resolve all existing pending conflicts."""
    try:
        # Gather pending conflicts from all projects
        all_conflicts = []
        for project_name in list_projects():
            store = get_store(project_name)
            conflicts = store.list_conflicts(status="pending")
            for c in conflicts:
                c["project"] = project_name
            all_conflicts.extend(conflicts)

        if not all_conflicts:
            print("[AutoResolve] No existing pending conflicts to process")
            return

        print(f"[AutoResolve] Processing {len(all_conflicts)} existing pending conflicts...")

        # Process in batches using existing auto_resolve_conflicts
        result = await auto_resolve_conflicts(all_conflicts)

        # Apply resolutions
        applied = 0
        for resolution in result.get("resolutions", []):
            conflict_id = resolution.get("conflict_id")
            decision = resolution.get("decision")
            merged_fact = resolution.get("merged_fact")

            # Find the conflict to get its project
            conflict = next((c for c in all_conflicts if c["id"] == conflict_id), None)
            if not conflict:
                continue

            project = conflict.get("project")
            store = get_store(project)

            try:
                store.resolve_conflict(
                    conflict_id=conflict_id,
                    decision=decision,
                    merged_fact=merged_fact,
                    reasoning=resolution.get("reasoning", "Auto-resolved by background task")
                )
                applied += 1
            except Exception as e:
                print(f"[AutoResolve] Failed to apply resolution for {conflict_id}: {e}")

        print(f"[AutoResolve] Applied {applied}/{len(result.get('resolutions', []))} resolutions")

    except Exception as e:
        print(f"[AutoResolve] Background task error: {e}")


async def auto_resolve_loop():
    """Background loop that processes pending conflicts periodically."""
    print("[AutoResolve] Started background loop (every 30s)")
    await asyncio.sleep(10)  # Initial delay for server warmup
    while True:
        try:
            if _server_config.get("auto_resolve_enabled", False):
                await process_existing_conflicts_background()
        except Exception as e:
            print(f"[AutoResolve] Loop error: {e}")
        await asyncio.sleep(30)


def start_auto_resolve_loop():
    """Start the periodic auto-resolve background task."""
    global _auto_resolve_task
    stop_auto_resolve_loop()
    _auto_resolve_task = asyncio.create_task(auto_resolve_loop())


def stop_auto_resolve_loop():
    """Stop the periodic auto-resolve background task."""
    global _auto_resolve_task
    if _auto_resolve_task:
        _auto_resolve_task.cancel()
        _auto_resolve_task = None
        print("[Server] Stopped auto-resolve loop")


async def auto_resolve_and_log(conflict: Dict, store, project: str):
    """Background task to auto-resolve a conflict when detected."""
    try:
        result = await resolve_single_conflict(conflict, store)
        decision = result.get("decision", "unknown")
        reasoning = result.get("reasoning", "")[:50]
        print(f"[AutoResolve] {conflict.get('id')}: {decision} - {reasoning}")
    except Exception as e:
        print(f"[AutoResolve] Error resolving {conflict.get('id')}: {e}")
