"""
Summary API Routes for CodeContext server.

Handles project summary generation, history, and injection.
"""

from fastapi import APIRouter, Request, Query, HTTPException

from ..services.store_manager import get_store
from ..utils.formatting import error_response
from ..services.summary_generator import SummaryManager, calculate_total_tokens, estimate_tokens
from ..services.summary_replay import generate_replay_summary
from ..services.progressive_summary import generate_progressive_summary


router = APIRouter()


def get_config(request: Request):
    """Get server config from app state."""
    return request.app.state.server_config


def get_default_config(request: Request):
    """Get default config from app state."""
    return request.app.state.default_config


def get_base_path(request: Request):
    """Get base path from app state."""
    return request.app.state.base_path


def get_summary_manager(request: Request, project: str) -> SummaryManager:
    """Get or create a SummaryManager for the given project."""
    base_path = get_base_path(request)
    store = get_store(project)
    manager = SummaryManager(base_path, project, store)
    return manager


@router.get("/api/summary")
async def get_summary(request: Request, project: str = Query(...)):
    """Get the current summary for a project."""
    manager = get_summary_manager(request, project)
    current = manager.load_current()

    if not current:
        return {
            "project": project,
            "has_summary": False,
            "summary": None
        }

    return {
        "project": project,
        "has_summary": True,
        "summary": current
    }


@router.post("/api/summary/regenerate")
async def regenerate_summary(
    request: Request,
    project: str = Query(...),
    force_full: bool = Query(default=False),
    progressive: bool = Query(default=False)
):
    """
    Trigger summary regeneration for a project.

    Args:
        project: Project name
        force_full: If True, regenerate from all memories in fixed chunks
        progressive: If True, use time-based chunking (best for fixing stale priorities)
    """
    manager = get_summary_manager(request, project)

    if progressive:
        # Progressive: time-based chunking that keeps sessions together
        result = await generate_progressive_summary(
            manager,
            target_chunk_size=30,
            gap_hours=8.0,
            trigger="progressive"
        )
    elif force_full:
        # Force full: fixed-size chunks from oldest to newest
        result = await generate_replay_summary(manager, trigger="manual_full")
    else:
        # Default: incremental update
        result = await manager.generate_and_save(
            trigger="manual",
            force_full=False
        )

    if result:
        response = {
            "project": project,
            "success": True,
            "version": result.get("version"),
            "new_memories_count": result.get("new_memories_count", 0)
        }
        # Include chunk info for progressive mode
        if progressive and result.get("chunks"):
            response["chunks"] = result.get("chunks")
        return response
    else:
        return error_response(
            detail="No new memories to summarize or generation failed",
            code="SUMMARY_GENERATION_FAILED",
            status_code=400
        )


@router.get("/api/summary/history")
async def get_summary_history(
    request: Request,
    project: str = Query(...),
    limit: int = Query(default=50)
):
    """Get summary version history for a project."""
    manager = get_summary_manager(request, project)
    history = manager.get_history(limit)

    return {
        "project": project,
        "history": history,
        "count": len(history)
    }


@router.get("/api/summary/history/{version}")
async def get_summary_version(
    request: Request,
    version: int,
    project: str = Query(...)
):
    """Get a specific summary version."""
    manager = get_summary_manager(request, project)
    summary_version = manager.get_version(version)

    if not summary_version:
        raise HTTPException(status_code=404, detail=f"Version {version} not found")

    return {
        "project": project,
        "version": summary_version
    }


@router.post("/api/summary/use/{version}")
async def use_summary_version(
    request: Request,
    version: int,
    project: str = Query(...)
):
    """Set an old version as the current summary."""
    manager = get_summary_manager(request, project)
    success = manager.use_version(version)

    if not success:
        raise HTTPException(status_code=404, detail=f"Version {version} not found or could not be used")

    return {
        "project": project,
        "success": True,
        "message": f"Version {version} is now the current summary"
    }


@router.get("/api/summary/stats")
async def get_summary_stats(request: Request, project: str = Query(...)):
    """Get summary statistics including token counts."""
    manager = get_summary_manager(request, project)
    stats = manager.get_stats()

    # Also get memory token count
    store = get_store(project)
    memories = store.list_all(limit=10000)  # Get all for token count
    memory_token_count = calculate_total_tokens(memories)

    return {
        "project": project,
        "summary": stats,
        "memories": {
            "count": store.count(),
            "token_count": memory_token_count
        }
    }


@router.get("/api/summary/injection")
async def get_summary_injection(request: Request, project: str = Query(...)):
    """Get the full injection text (summary + timeline) for session start."""
    server_config = get_config(request)
    default_config = get_default_config(request)
    manager = get_summary_manager(request, project)
    summary_settings = server_config.get("summary", default_config["summary"])
    timeline_items = summary_settings.get("timeline_items", 10)

    injection_text = manager.format_injection(timeline_limit=timeline_items)

    # Get stats for descriptive session messages
    stats = manager.get_stats()

    # Get total memory count from store (may differ from summary's memory_count)
    store = get_store(project)
    total_memory_count = store.count()

    return {
        "project": project,
        "injection": injection_text,
        "token_estimate": estimate_tokens(injection_text),
        "has_summary": stats.get("has_summary", False),
        "version": stats.get("version", 0),
        "memory_count": total_memory_count
    }
