# <PLUGIN_DIR>/api_docs_generator.py
import os
from typing import Any
from datetime import datetime
import inspect
from bedrock_server_manager import Settings, PluginBase, __version__


class APIDocsGenerator(PluginBase):
    """
    A utility plugin that automatically generates Markdown documentation
    for all registered plugin API functions.
    """

    version = "1.1.0"

    def on_load(self):
        self.logger.info(
            "API Docs Generator plugin loaded. Will generate docs on manager startup."
        )

    def on_manager_startup(self, **kwargs: Any):
        """
        Triggered once when the application is fully started.
        This is the perfect time to inspect and document the API.
        """
        self.logger.info("Generating API documentation...")
        self.settings = self.api.app_context.settings

        try:
            # 1. Get the detailed API list
            api_list = self.api.list_available_apis()

            # 2. Format the list into a Markdown document
            markdown_content = self._format_as_markdown(api_list)

            # 3. Save the document to a file
            # Save it in the main config directory for easy access.
            output_path = os.path.join(
                self.settings.config_dir, "PLUGIN_API_REFERENCE.md"
            )
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(markdown_content)

            self.logger.info(
                f"Successfully generated API documentation at: {output_path}"
            )

        except Exception as e:
            self.logger.error(
                f"Failed to generate API documentation: {e}", exc_info=True
            )

    def _format_type_hint(self, annotation: Any) -> str:
        """
        Cleans up the string representation of a type hint for display.
        """
        if annotation == inspect.Parameter.empty:
            return "Any"

        # Get the string representation
        s = str(annotation)

        # Clean up common Python cruft
        s = s.replace("typing.", "")
        s = s.replace("<class '", "").replace("'>", "")

        return s

    def _format_as_markdown(self, api_list: list) -> str:
        """
        Takes the list of API details and converts it into a formatted Markdown string.
        """
        # --- Document Header ---
        lines = [
            f"> _This was auto-generated by the `api_docs_generator` plugin on {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')}._",
            f"> _Application Version: {__version__}_",
            "\n---",
            "This lists contains all functions available to plugins via the `self.api` object.",
            "For an updated list of available APIs, please download and run the [api_docs_generator](https://github.com/DMedina559/bedrock-server-manager/blob/main/plugins/api_docs_generator.py) plugin.",
        ]

        # --- API Functions Loop ---
        for api_func in api_list:
            name = api_func.get("name", "Unknown Function")
            docstring = api_func.get("docstring", "No description.")
            params = api_func.get("parameters", [])

            # Create the function signature string
            param_parts = []
            for param in params:
                p_name = param["name"]
                p_type = self._format_type_hint(param.get("type_obj"))
                p_default = param.get("default")

                if p_default == "REQUIRED":
                    param_parts.append(f"{p_name}: {p_type}")
                else:
                    # Format default values nicely for display
                    default_str = f" = {repr(p_default)}"
                    param_parts.append(f"{p_name}: {p_type}{default_str}")

            signature = f"self.api.{name}({', '.join(param_parts)})"

            # Add the section for this function
            lines.append(f"\n## `{name}`")
            lines.append(f"```python\n{signature}\n```")
            lines.append(f"**Description:** {docstring}\n")

            if params:
                lines.append("**Parameters:**\n")
                lines.append("| Name | Type | Default |")
                lines.append("|------|------|---------|")
                for param in params:
                    p_name = f"`{param['name']}`"
                    p_type = f"`{self._format_type_hint(param.get('type_obj'))}`"
                    p_default = f"`{repr(param.get('default'))}`"
                    if param.get("default") == "REQUIRED":
                        p_default = "`REQUIRED`"
                    lines.append(f"| {p_name} | {p_type} | {p_default} |")

            lines.append("\n---\n")

        return "\n".join(lines)
