"""Mock agent for debug server."""

from __future__ import annotations

import time
from typing import TYPE_CHECKING, Any
import uuid

from fastapi import HTTPException
import structlog

from acp.agent.implementations.debug_server.models import DebugSession
from acp.agent.protocol import Agent
from acp.schema import (
    AuthenticateResponse,
    CreateTerminalResponse,
    # CurrentModelUpdate,
    ForkSessionResponse,
    InitializeResponse,
    ListSessionsResponse,
    LoadSessionResponse,
    NewSessionResponse,
    PromptResponse,
    ReadTextFileResponse,
    ResumeSessionResponse,
    SessionInfo,
    WriteTextFileResponse,
)


if TYPE_CHECKING:
    from acp import SetSessionModelRequest, SetSessionModeRequest
    from acp.agent.implementations.debug_server.models import DebugState
    from acp.schema import (
        AuthenticateRequest,
        CancelNotification,
        CreateTerminalRequest,
        ForkSessionRequest,
        InitializeRequest,
        ListSessionsRequest,
        LoadSessionRequest,
        NewSessionRequest,
        PromptRequest,
        ReadTextFileRequest,
        ResumeSessionRequest,
        SetSessionConfigOptionRequest,
        WriteTextFileRequest,
    )


logger = structlog.get_logger(__name__)
MOCK_FILE = """\
# Mock file: {path}
# Generated by ACP Debug Server

def example_function():
return "This is mock content for testing"

# Line count: 10 lines
"""


class MockAgent(Agent):
    """Mock ACP agent for debug server."""

    def __init__(self, debug_state: DebugState) -> None:
        """Initialize with debug state."""
        self.debug_state = debug_state

    async def initialize(self, params: InitializeRequest) -> InitializeResponse:
        """Handle initialize request with mock capabilities."""
        return InitializeResponse.create(
            title="MockAgent",
            name="MockAgent",
            version="1.0",
            protocol_version=1,
            load_session=True,
        )

    async def new_session(self, params: NewSessionRequest) -> NewSessionResponse:
        """Create new debug session."""
        session_id = str(uuid.uuid4())
        created = time.perf_counter()
        session = DebugSession(session_id=session_id, created_at=created, cwd=params.cwd)
        self.debug_state.sessions[session_id] = session
        self.debug_state.active_session_id = session_id
        return NewSessionResponse(session_id=session_id)

    async def load_session(self, params: LoadSessionRequest) -> LoadSessionResponse:
        """Load existing debug session."""
        if params.session_id in self.debug_state.sessions:
            self.debug_state.active_session_id = params.session_id
            return LoadSessionResponse()
        raise HTTPException(status_code=404, detail="Session not found")

    async def prompt(self, params: PromptRequest) -> PromptResponse:
        """Handle prompt with mock response."""
        logger.info("Received prompt", session_id=params.session_id)
        return PromptResponse(stop_reason="end_turn")

    async def cancel(self, params: CancelNotification) -> None:
        """Handle cancellation."""
        logger.info("Received cancellation request")

    async def authenticate(self, params: AuthenticateRequest) -> AuthenticateResponse | None:
        """Mock authentication - always succeeds."""
        return AuthenticateResponse()

    async def read_text_file(self, params: ReadTextFileRequest) -> ReadTextFileResponse:
        """Mock file reading."""
        mock_content = MOCK_FILE.format(path=params.path)
        return ReadTextFileResponse(content=mock_content)

    async def write_text_file(self, params: WriteTextFileRequest) -> WriteTextFileResponse:
        """Mock file writing."""
        logger.info("Mock write", path=params.path, content_length=len(params.content))
        return WriteTextFileResponse()

    async def create_terminal(self, params: CreateTerminalRequest) -> CreateTerminalResponse:
        """Mock terminal creation."""
        terminal_id = str(uuid.uuid4())
        return CreateTerminalResponse(terminal_id=terminal_id)

    async def set_session_mode(self, params: SetSessionModeRequest) -> None:
        """Mock session mode change."""
        logger.info("Mock session mode change")

    async def set_session_model(self, params: SetSessionModelRequest) -> None:
        """Mock session model change."""
        logger.info("Mock session model change")

    async def set_session_config_option(self, params: SetSessionConfigOptionRequest) -> None:
        """Mock session config option change."""
        logger.info("Mock session config option change")

    async def ext_notification(self, method: str, params: dict[str, Any]) -> None:
        """Mock extensibility notification."""
        logger.info("Mock ext notification", method=method)

    async def ext_method(self, method: str, params: dict[str, Any]) -> Any:
        """Mock extensibility method."""
        logger.info("Mock ext method", method=method)
        return {"result": "mock response"}

    async def list_sessions(self, params: ListSessionsRequest) -> ListSessionsResponse:
        """Mock list sessions."""
        session_ids = list(self.debug_state.sessions.keys())
        sessions = [SessionInfo(session_id=sid, cwd="/mock/cwd") for sid in session_ids]
        return ListSessionsResponse(sessions=sessions)

    async def fork_session(self, params: ForkSessionRequest) -> ForkSessionResponse:
        """Mock fork session."""
        session_id = str(uuid.uuid4())
        if params.session_id in self.debug_state.sessions:
            old_session = self.debug_state.sessions[params.session_id]
            created = time.perf_counter()
            session = DebugSession(session_id=session_id, created_at=created, cwd=old_session.cwd)
            self.debug_state.sessions[session_id] = session
        return ForkSessionResponse(session_id=session_id)

    async def resume_session(self, params: ResumeSessionRequest) -> ResumeSessionResponse:
        """Mock resume session."""
        if params.session_id in self.debug_state.sessions:
            self.debug_state.active_session_id = params.session_id
        return ResumeSessionResponse()
