# retoor <retoor@molodetz.nl>

from __future__ import annotations

import json
from typing import Any

from ..config import Settings
from ..errors import ToolInputError
from .store import get_store


class ChunkController:
    def __init__(self, settings: Settings) -> None:
        self._settings = settings

    async def dispatch(self, name: str, arguments: dict[str, Any]) -> str:
        if name != "read_more":
            raise ToolInputError(f"Unknown chunk tool: {name}")
        store = get_store()
        if store is None:
            return json.dumps(
                {
                    "status": "unavailable",
                    "message": "No chunk store is active for this session.",
                }
            )
        chunk_id = str(arguments.get("chunk_id", "")).strip()
        if not chunk_id:
            raise ToolInputError("read_more requires a chunk_id.")
        text = store.get(chunk_id)
        if text is None:
            return json.dumps(
                {
                    "status": "not_found",
                    "message": (
                        f"No stored content for chunk_id '{chunk_id}'. It may have expired; "
                        "re-run the original tool to get a fresh chunk_id."
                    ),
                }
            )

        offset = max(0, int(arguments.get("offset", 0) or 0))
        length = int(
            arguments.get("length", self._settings.max_response_chars)
            or self._settings.max_response_chars
        )
        length = max(1, min(length, self._settings.max_response_chars))

        total = len(text)
        piece = text[offset : offset + length]
        next_offset = offset + len(piece)
        has_more = next_offset < total
        return json.dumps(
            {
                "status": "success",
                "chunk_id": chunk_id,
                "offset": offset,
                "shown_chars": len(piece),
                "total_chars": total,
                "remaining_chars": max(0, total - next_offset),
                "next_offset": next_offset if has_more else None,
                "has_more": has_more,
                "content": piece,
            },
            ensure_ascii=False,
        )
