"""Auto-verify loop API routes."""

import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel, Field

from ieum.server.auth import get_request_user_id

logger = logging.getLogger(__name__)

router = APIRouter()


def get_session_service(request: Request) -> Any:
    """Dependency to get the session service."""
    return request.app.state.session_service


class VerifyStatus(BaseModel):
    """Verify loop status response."""

    enabled: bool
    test_command: str | None = None
    lint_command: str | None = None
    max_retries: int = 3


class VerifyToggle(BaseModel):
    """Verify toggle response."""

    enabled: bool
    test_command: str | None = None
    lint_command: str | None = None


class VerifyConfigUpdate(BaseModel):
    """Request to update verify configuration."""

    test_command: str | None = Field(default=None, description="Custom test command")
    lint_command: str | None = Field(default=None, description="Custom lint command")


class VerifyRunResult(BaseModel):
    """Result of running verification."""

    all_passed: bool
    summary: str
    errors: list[str] = []


@router.get("/{session_id}/verify", response_model=VerifyStatus)
async def get_verify_status(
    session_id: str,
    request: Request,
    session_service: Any = Depends(get_session_service),
) -> VerifyStatus:
    """Get verify loop status for a session."""
    user_id = get_request_user_id(request)
    session = session_service.get_session(session_id, user_id=user_id)
    if session is None:
        raise HTTPException(status_code=404, detail="Session not found")

    cfg = getattr(session, "verify_config", None)
    return VerifyStatus(
        enabled=getattr(session, "verify_enabled", False),
        test_command=cfg.test_command if cfg else None,
        lint_command=cfg.lint_command if cfg else None,
        max_retries=cfg.max_retries if cfg else 3,
    )


@router.post("/{session_id}/verify/toggle", response_model=VerifyToggle)
async def toggle_verify(
    session_id: str,
    request: Request,
    session_service: Any = Depends(get_session_service),
) -> VerifyToggle:
    """Toggle auto-verify for a session."""
    user_id = get_request_user_id(request)
    session = session_service.get_session(session_id, user_id=user_id)
    if session is None:
        raise HTTPException(status_code=404, detail="Session not found")

    session.verify_enabled = not getattr(session, "verify_enabled", False)

    # Auto-detect commands if enabling for the first time
    if session.verify_enabled and session.verify_config is None:
        from ieum.verify_loop import detect_verify_commands
        session.verify_config = detect_verify_commands(session.working_directory)

    cfg = session.verify_config
    return VerifyToggle(
        enabled=session.verify_enabled,
        test_command=cfg.test_command if cfg else None,
        lint_command=cfg.lint_command if cfg else None,
    )


@router.patch("/{session_id}/verify", response_model=VerifyStatus)
async def update_verify_config(
    session_id: str,
    body: VerifyConfigUpdate,
    request: Request,
    session_service: Any = Depends(get_session_service),
) -> VerifyStatus:
    """Update verify configuration for a session."""
    user_id = get_request_user_id(request)
    session = session_service.get_session(session_id, user_id=user_id)
    if session is None:
        raise HTTPException(status_code=404, detail="Session not found")

    from ieum.verify_loop import VerifyConfig

    if session.verify_config is None:
        session.verify_config = VerifyConfig()

    if body.test_command is not None:
        session.verify_config.test_command = body.test_command
    if body.lint_command is not None:
        session.verify_config.lint_command = body.lint_command

    cfg = session.verify_config
    return VerifyStatus(
        enabled=session.verify_enabled,
        test_command=cfg.test_command,
        lint_command=cfg.lint_command,
        max_retries=cfg.max_retries,
    )


@router.post("/{session_id}/verify/run", response_model=VerifyRunResult)
async def run_verify(
    session_id: str,
    request: Request,
    session_service: Any = Depends(get_session_service),
) -> VerifyRunResult:
    """Run verification (test + lint) now."""
    user_id = get_request_user_id(request)
    session = session_service.get_session(session_id, user_id=user_id)
    if session is None:
        raise HTTPException(status_code=404, detail="Session not found")

    from ieum.verify_loop import VerifyConfig, detect_verify_commands
    from ieum.verify_loop import run_verify as _run_verify

    cfg = session.verify_config
    if cfg is None:
        cfg = detect_verify_commands(session.working_directory)
        session.verify_config = cfg

    if not cfg.test_command and not cfg.lint_command:
        return VerifyRunResult(
            all_passed=False,
            summary="No test or lint commands detected.",
        )

    result = await _run_verify(cfg, cwd=session.working_directory)
    return VerifyRunResult(
        all_passed=result.all_passed,
        summary=result.summary,
        errors=result.errors[:10] if result.errors else [],
    )
