"""You are an expert in the creating wide many types of documents. You use program libraries, systems, style guide, and industry best practices, to efficiently create and update documentation for the attune-ai framework.

Stages:
1. process - Process

Copyright 2025 Smart-AI-Memory
Licensed under the Apache License, Version 2.0
"""

import heapq
import logging
import warnings
from pathlib import Path
from typing import Any

from attune.workflows.base import BaseWorkflow, ModelTier
from attune.workflows.context import WorkflowContext
from attune.workflows.services import ParsingService, PromptService

logger = logging.getLogger(__name__)


class DocumentManagerWorkflow(BaseWorkflow):
    """You are an expert in the creating wide many types of documents. You use program libraries, systems, style guide, and industry best practices, to efficiently create and update documentation for the attune-ai framework.

    Supports composition via ``WorkflowContext`` -- use ``default_context()``
    to get a pre-configured context with prompt and parsing services.

    Usage:
        workflow = DocumentManagerWorkflow()
        result = await workflow.execute(
            # Add parameters here
        )
    """

    name = "document-manager"
    description = "You are an expert in the creating wide many types of documents. You use program libraries, systems, style guide, and industry best practices, to efficiently create and update documentation for the attune-ai framework."
    stages = ["process"]
    tier_map = {
        "process": ModelTier.CAPABLE,
    }

    def __init__(
        self,
        **kwargs: Any,
    ):
        """Initialize document-manager workflow.

        .. deprecated:: 4.0.0
            Use :class:`DocumentGenerationWorkflow` instead.
            Will be removed in v5.0.0.

        Args:
            **kwargs: Additional arguments passed to BaseWorkflow

        """
        warnings.warn(
            "DocumentManagerWorkflow is deprecated. Use DocumentGenerationWorkflow instead. "
            "Will be removed in v5.0.0.",
            DeprecationWarning,
            stacklevel=2,
        )
        super().__init__(**kwargs)

    @classmethod
    def default_context(cls, xml_config: dict | None = None) -> WorkflowContext:
        """Create a WorkflowContext pre-configured for document management.

        Args:
            xml_config: Optional XML prompt configuration dict.

        Returns:
            WorkflowContext with prompt and parsing services.

        """
        return WorkflowContext(
            prompt=PromptService("document-manager", xml_config=xml_config),
            parsing=ParsingService(xml_config=xml_config),
        )

    async def _process(
        self,
        input_data: Any,
        tier: ModelTier,
    ) -> tuple[Any, int, int]:
        """Process the input data.

        Args:
            input_data: Input data to process
            tier: Model tier to use

        Returns:
            Tuple of (result, input_tokens, output_tokens)

        """
        # Extract path from input
        path = input_data.get("path", ".") if isinstance(input_data, dict) else "."
        target_path = Path(path).resolve()

        # Scan the codebase structure
        code_context = self._scan_codebase(target_path)

        system_prompt = """You are an expert technical writer specializing in API documentation.
You create clear, comprehensive documentation for Python frameworks and libraries.
DO NOT ask questions or request clarification - use the information provided to create
complete, professional documentation immediately."""

        user_prompt = f"""Create comprehensive API documentation for the Attune AI based on this codebase analysis.

**Project Path:** {target_path}

**Codebase Information:**
{code_context}

**Generate the following documentation sections:**

# Attune AI API Documentation

## Overview
[Analyze the project structure and write a clear overview of what the framework does]

## Installation
[Based on pyproject.toml, provide installation instructions]

## Quick Start
[Create a simple getting-started example]

## Architecture
[Describe the key modules and how they interact]

## Core Components
[Document the main classes, methods, and their purposes based on the module structure]

## Workflows
[Document available workflows and how to use them]

## Usage Examples
[Provide practical code examples]

## Configuration
[Explain configuration options if apparent from the code]

Write the documentation now in complete Markdown format. Be specific and technical."""

        # Call LLM using the workflow's built-in method
        response, input_tokens, output_tokens = await self._call_llm(
            tier=tier,
            system=system_prompt,
            user_message=user_prompt,
            max_tokens=4000,
        )

        return response, input_tokens, output_tokens

    def _scan_codebase(self, path: Path) -> str:
        """Scan the codebase and return a summary of the structure.

        Args:
            path: Path to scan

        Returns:
            String representation of the codebase structure

        """
        if not path.exists():
            return f"Path does not exist: {path}"

        if path.is_file():
            # If it's a single file, read it
            try:
                content = path.read_text()[:5000]  # First 5000 chars
                return f"File: {path.name}\n\n```\n{content}\n```"
            except Exception as e:  # noqa: BLE001
                # INTENTIONAL: File reading is best-effort for doc generation
                return f"Error reading file: {e}"

        # If it's a directory, scan the structure
        structure = []
        try:
            # Read README if it exists
            readme_path = path / "README.md"
            if readme_path.exists():
                try:
                    readme_content = readme_path.read_text()[:3000]
                    structure.append("**README.md (excerpt):**\n```markdown")
                    structure.append(readme_content)
                    structure.append("```\n")
                except (OSError, UnicodeDecodeError):
                    pass

            # Read pyproject.toml if it exists
            pyproject_path = path / "pyproject.toml"
            if pyproject_path.exists():
                try:
                    pyproject_content = pyproject_path.read_text()[:2000]
                    structure.append("**pyproject.toml (excerpt):**\n```toml")
                    structure.append(pyproject_content)
                    structure.append("```\n")
                except (OSError, UnicodeDecodeError):
                    pass

            # Get Python files in src directory with sample content
            src_dir = path / "src"
            if src_dir.exists():
                py_files = list(src_dir.rglob("*.py"))[:10]  # Limit to 10 files
                structure.append("**Key Python Modules:**")
                for py_file in py_files:
                    rel_path = py_file.relative_to(path)
                    structure.append(f"\n- {rel_path}")
                    # Read docstring from file
                    try:
                        content = py_file.read_text()[:1000]
                        # Extract first docstring
                        if '"""' in content:
                            start = content.find('"""')
                            end = content.find('"""', start + 3)
                            if end != -1:
                                docstring = content[start + 3 : end].strip()
                                structure.append(f"  {docstring[:200]}")
                    except (OSError, UnicodeDecodeError):
                        pass

            # Get directory structure
            structure.append("\n**Directory Structure:**")
            for item in heapq.nsmallest(
                15,
                path.iterdir(),
                key=lambda x: str(x),
            ):  # Limit to 15 items
                if item.name.startswith("."):
                    continue
                if item.is_dir():
                    structure.append(f"- {item.name}/ (directory)")
                else:
                    structure.append(f"- {item.name}")

            return "\n".join(structure)
        except Exception as e:  # noqa: BLE001
            # INTENTIONAL: Directory scanning is best-effort for doc generation
            return f"Error scanning directory: {e}"
