# File: src/noveler/infrastructure/services/content_cleaner.py
# Purpose: Content sanitization and cleaning utilities for unified session outputs.
# Context: Extracted from unified_session_executor to reduce complexity and improve testability.
"""Content cleaner for removing system artifacts and cleaning stage outputs."""

from __future__ import annotations

import re


class ContentCleaner:
    """Removes system artifacts, JSON metadata, and prompt contamination from content."""

    @staticmethod
    def remove_json_metadata(content: str) -> str:
        """Remove inline JSON metadata blocks from content.

        Args:
            content: The content to clean.

        Returns:
            Content with JSON blocks removed.
        """
        cleaned = content
        json_block_patterns = [
            ("```json", "```"),
            ("```", "```"),
        ]
        for start_marker, end_marker in json_block_patterns:
            search_start = 0
            while True:
                start = cleaned.lower().find(start_marker, search_start)
                if start == -1:
                    break
                end = cleaned.find(end_marker, start + len(start_marker))
                if end == -1:
                    cleaned = cleaned[:start]
                    break
                cleaned = cleaned[:start] + cleaned[end + len(end_marker) :]
                search_start = start

        lines = []
        for line in cleaned.splitlines():
            stripped = line.strip()
            if stripped.startswith("{") and stripped.endswith("}"):
                continue
            if stripped.startswith("[") and stripped.endswith("]"):
                continue
            lines.append(line)
        return "\n".join(lines)

    @staticmethod
    def remove_prompt_contamination(content: str) -> str:
        """Remove prompt scaffolding that leaks into model output.

        Args:
            content: The content to clean.

        Returns:
            Content with prompt markers removed.
        """
        forbidden_keywords = [
            "## ",
            "入力してください",
            "Claude",
            "含めます",
            "チェック",
        ]
        cleaned_lines: list[str] = []
        for line in content.splitlines():
            if any(keyword in line for keyword in forbidden_keywords):
                continue
            cleaned_lines.append(line)
        return "\n".join(cleaned_lines)

    @staticmethod
    def remove_system_messages(content: str) -> str:
        """Remove obvious system log markers.

        Args:
            content: The content to clean.

        Returns:
            Content with system markers removed.
        """
        prefixes = ["[System]", "[Error]", "[Warning]", "DEBUG:", "INFO:", "WARNING:"]
        return "\n".join(line for line in content.splitlines() if not any(prefix in line for prefix in prefixes))

    @staticmethod
    def extract_manuscript_text(content: str) -> str:
        """Extract narrative text starting from the first numbered section.

        Args:
            content: The content to extract from.

        Returns:
            Extracted manuscript text or original content if no section found.
        """
        lines = content.splitlines()
        for idx, line in enumerate(lines):
            stripped = line.strip()
            if stripped.startswith("第") and "話" in stripped:
                return "\n".join(lines[idx:]).strip()
        return content.strip()

    @staticmethod
    def normalize_whitespace(content: str) -> str:
        """Collapse excessive whitespace while preserving sentence order.

        Args:
            content: The content to normalize.

        Returns:
            Content with normalized whitespace.
        """
        normalized_lines = [
            re.sub(r"\s+", " ", line).strip() for line in content.splitlines()
        ]
        return "\n".join(line for line in normalized_lines if line)

    @staticmethod
    def clean_all(content: str) -> str:
        """Apply all cleaning operations in order.

        Args:
            content: The content to clean.

        Returns:
            Fully cleaned content.
        """
        cleaned = ContentCleaner.remove_system_messages(content)
        cleaned = ContentCleaner.remove_prompt_contamination(cleaned)
        cleaned = ContentCleaner.remove_json_metadata(cleaned)
        return cleaned.strip()
