"""
NOTE: Responses now use APIResponse format with data wrapped in "data" field.Document and knowledge base management commands
"""

import os
from typing import Any

from colorama import Fore, Style

from socratic_system.ui.commands.base import BaseCommand
from socratic_system.utils.orchestrator_helper import safe_orchestrator_call


class DocsCommand(BaseCommand):
    """View documentation on a topic"""

    def __init__(self):
        super().__init__(
            name="docs",
            description="View documentation on a topic (e.g., docs projects, docs authentication)",
            usage="docs [topic]",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs command to retrieve documentation on a topic"""
        # Get topic from args
        if not args:
            topic = input(f"{Fore.WHITE}Enter topic to learn about: ").strip()
        else:
            topic = " ".join(args)

        if not topic:
            return self.error("Please specify a topic (e.g., 'docs projects')")

        orchestrator = context.get("orchestrator")
        if not orchestrator:
            return self.error("Orchestrator not available")

        # Check if Claude client is available
        if not hasattr(orchestrator, "claude_client") or not orchestrator.claude_client:
            return self.error("Claude client not available")

        try:
            # Build documentation request prompt
            prompt = f"""Provide a clear, concise guide on: {topic}

Focus on:
- Key features and concepts
- How to use it
- Pro tips and best practices
- When to use it

Keep the response well-formatted and easy to read."""

            # Get documentation from Claude
            print(f"{Fore.YELLOW}Fetching documentation on '{topic}'...{Style.RESET_ALL}")
            documentation = orchestrator.claude_client.generate_response(prompt)

            if documentation:
                self.print_success(f"Documentation: {topic}")
                print(documentation)
                return self.success(
                    data={
                        "topic": topic,
                        "documentation": documentation,
                    }
                )
            else:
                return self.error(f"Could not retrieve documentation for '{topic}'")

        except Exception as e:
            return self.error(f"Error retrieving documentation: {str(e)}")


class DocImportCommand(BaseCommand):
    """Import a single document into the knowledge base"""

    def __init__(self):
        super().__init__(
            name="docs import",
            description="Import a single file into the knowledge base",
            usage="docs import <path>",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs import command"""
        if not self.validate_args(args, min_count=1):
            file_path = input(f"{Fore.WHITE}Enter file path: ").strip()
        else:
            file_path = " ".join(args)  # Allow spaces in file path

        if not file_path:
            return self.error("File path cannot be empty")

        # Normalize path to handle Windows paths correctly
        file_path = os.path.normpath(file_path)

        orchestrator = context.get("orchestrator")
        project = context.get("project")

        if not orchestrator:
            return self.error("Orchestrator not available")

        # Ask if they want to link to current project
        project_id = None
        if project:
            link_choice = input(
                f"{Fore.CYAN}Link to current project '{project.name}'? (y/n): "
            ).lower()
            if link_choice == "y":
                project_id = project.project_id

        print(f"{Fore.YELLOW}Processing file...{Style.RESET_ALL}")

        try:
            result = safe_orchestrator_call(
                orchestrator,
                "document_agent",
                {"action": "import_file", "file_path": file_path, "project_id": project_id},
                operation_name="import file",
            )

            file_name = result.get("file_name", "file")
            words = result.get("words_extracted", 0)
            chunks = result.get("chunks_created", 0)
            entries = result.get("entries_added", 0)

            self.print_success(f"Successfully imported '{file_name}'")
            print(f"{Fore.WHITE}Content extracted: {words} words")
            print(f"Chunks created: {chunks}")
            print(f"Stored in knowledge base: {entries} entries")

            # CRITICAL: Emit DOCUMENT_IMPORTED event to trigger knowledge analysis
            try:
                from socratic_system.events import EventType

                orchestrator.event_emitter.emit(
                    EventType.DOCUMENT_IMPORTED,
                    {
                        "project_id": project_id,
                        "file_name": file_name,
                        "source_type": "file",
                        "words_extracted": words,
                        "chunks_created": chunks,
                        "user_id": (
                            context.get("user").username if context.get("user") else "unknown"
                        ),
                    },
                )
                print(f"{Fore.GREEN}Knowledge analysis triggered{Style.RESET_ALL}")
            except Exception as e:
                print(
                    f"{Fore.YELLOW}Warning: Could not trigger knowledge analysis: {str(e)}{Style.RESET_ALL}"
                )

            return self.success(
                data={
                    "file_name": file_name,
                    "words_extracted": words,
                    "chunks_created": chunks,
                    "entries_added": entries,
                }
            )
        except ValueError as e:
            return self.error(str(e))


class DocImportDirCommand(BaseCommand):
    """Import all files from a directory into the knowledge base"""

    def __init__(self):
        super().__init__(
            name="docs import-dir",
            description="Import all files from a directory into the knowledge base",
            usage="docs import-dir <path>",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs import-dir command"""
        if not self.validate_args(args, min_count=1):
            directory_path = input(f"{Fore.WHITE}Enter directory path: ").strip()
        else:
            directory_path = " ".join(args)  # Allow spaces in directory path

        if not directory_path:
            return self.error("Directory path cannot be empty")

        # Normalize path to handle Windows paths correctly
        directory_path = os.path.normpath(directory_path)

        orchestrator = context.get("orchestrator")
        project = context.get("project")

        if not orchestrator:
            return self.error("Orchestrator not available")

        # Ask if they want to include subdirectories
        recursive_choice = input(f"{Fore.CYAN}Include subdirectories? (y/n): ").lower()
        recursive = recursive_choice == "y"

        # Ask if they want to link to current project
        project_id = None
        if project:
            link_choice = input(
                f"{Fore.CYAN}Link to current project '{project.name}'? (y/n): "
            ).lower()
            if link_choice == "y":
                project_id = project.project_id

        print(f"{Fore.YELLOW}Processing directory...{Style.RESET_ALL}")

        try:
            result = safe_orchestrator_call(
                orchestrator,
                "document_agent",
                {
                    "action": "import_directory",
                    "directory_path": directory_path,
                    "project_id": project_id,
                    "recursive": recursive,
                },
                operation_name="import directory",
            )

            successful = result.get("files_processed", 0)
            failed = result.get("files_failed", 0)
            total_words = result.get("total_words_extracted", 0)
            total_chunks = result.get("total_chunks_created", 0)
            total_entries = result.get("total_entries_stored", 0)

            self.print_success("Directory import complete!")
            print(f"{Fore.WHITE}Files processed:     {successful}")
            if failed > 0:
                print(f"Files failed:        {failed}")
            print(f"Total content:       {total_words} words")
            print(f"Chunks created:      {total_chunks}")
            print(f"Stored in knowledge: {total_entries} entries")

            # CRITICAL: Emit DOCUMENT_IMPORTED event to trigger knowledge analysis
            try:
                from socratic_system.events import EventType

                orchestrator.event_emitter.emit(
                    EventType.DOCUMENT_IMPORTED,
                    {
                        "project_id": project_id,
                        "file_name": f"directory_import_{successful}_files",
                        "source_type": "directory",
                        "words_extracted": total_words,
                        "chunks_created": total_chunks,
                        "user_id": (
                            context.get("user").username if context.get("user") else "unknown"
                        ),
                    },
                )
                print(f"{Fore.GREEN}Knowledge analysis triggered{Style.RESET_ALL}")
            except Exception as e:
                print(
                    f"{Fore.YELLOW}Warning: Could not trigger knowledge analysis: {str(e)}{Style.RESET_ALL}"
                )

            return self.success(
                data={
                    "files_processed": successful,
                    "files_failed": failed,
                    "total_words_extracted": total_words,
                    "total_chunks_created": total_chunks,
                    "total_entries_stored": total_entries,
                }
            )
        except ValueError as e:
            return self.error(str(e))


class DocPasteCommand(BaseCommand):
    """Import pasted or inline text into the knowledge base"""

    def __init__(self):
        super().__init__(
            name="docs paste",
            description="Import pasted or inline text into the knowledge base",
            usage="docs paste [title]",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs paste command"""
        # Get title from arguments or user input
        title = self._get_title_from_input(args)

        # Get text content from user
        text_content = self._get_text_content_from_input()

        if not text_content.strip():
            return self.error("No content provided")

        # Validate context
        validation_error = self._validate_doc_paste_context(context)
        if validation_error:
            return validation_error

        orchestrator = context.get("orchestrator")
        project = context.get("project")

        # Determine project association
        project_id = self._get_project_association(project)

        # Process text content
        try:
            result = self._process_text_import(orchestrator, text_content, title, project_id)

            # Handle result
            return self._handle_import_success(result, title, project_id, context, orchestrator)
        except ValueError as e:
            return self.error(str(e))

    def _get_title_from_input(self, args: list[str]) -> str:
        """Get document title from args or user input"""
        if args:
            return " ".join(args)

        title = "pasted_text"
        title_input = input(
            f"{Fore.CYAN}Enter a title for this content (default: pasted_text): "
        ).strip()
        if title_input:
            title = title_input
        return title

    def _get_text_content_from_input(self) -> str:
        """Get multi-line text content from user input"""
        print(
            f"{Fore.CYAN}Enter your text content (type EOF on a new line when done):{Style.RESET_ALL}"
        )
        print(f"{Fore.YELLOW}>>> {Style.RESET_ALL}", end="")

        lines = []
        try:
            while True:
                line = input()
                if line.strip().upper() == "EOF":
                    break
                lines.append(line)
        except EOFError:
            pass

        return "\n".join(lines)

    def _validate_doc_paste_context(self, context: dict[str, Any]) -> dict:
        """Validate required context for docs paste command"""
        if not context.get("orchestrator"):
            return self.error("Orchestrator not available")
        return None

    def _get_project_association(self, project) -> str:
        """Get project ID if user wants to link to current project"""
        project_id = None
        if project:
            link_choice = input(
                f"{Fore.CYAN}Link to current project '{project.name}'? (y/n): "
            ).lower()
            if link_choice == "y":
                project_id = project.project_id
        return project_id

    def _process_text_import(
        self, orchestrator, text_content: str, title: str, project_id: str
    ) -> dict:
        """Process text import request"""
        print(f"{Fore.YELLOW}Processing text...{Style.RESET_ALL}")

        return safe_orchestrator_call(
            orchestrator,
            "document_agent",
            {
                "action": "import_text",
                "text_content": text_content,
                "title": title,
                "project_id": project_id,
            },
            operation_name="import text",
        )

    def _handle_import_success(
        self, result: dict, title: str, project_id: str, context: dict, orchestrator
    ) -> dict:
        """Handle successful text import"""
        words = result.get("words_extracted", 0)
        chunks = result.get("chunks_created", 0)
        entries = result.get("entries_added", 0)

        self.print_success(f"Successfully imported '{title}'")
        self._display_import_stats(words, chunks, entries)

        # Emit DOCUMENT_IMPORTED event
        self._emit_document_imported_event(orchestrator, project_id, title, words, chunks, context)

        return self.success(
            data={
                "title": title,
                "words_extracted": words,
                "chunks_created": chunks,
                "entries_added": entries,
            }
        )

    def _display_import_stats(self, words: int, chunks: int, entries: int) -> None:
        """Display import statistics"""
        print(f"{Fore.WHITE}Content extracted: {words} words")
        print(f"Chunks created: {chunks}")
        print(f"Stored in knowledge base: {entries} entries")

    def _emit_document_imported_event(
        self, orchestrator, project_id: str, title: str, words: int, chunks: int, context: dict
    ) -> None:
        """Emit DOCUMENT_IMPORTED event to trigger knowledge analysis"""
        try:
            from socratic_system.events import EventType

            orchestrator.event_emitter.emit(
                EventType.DOCUMENT_IMPORTED,
                {
                    "project_id": project_id,
                    "file_name": title,
                    "source_type": "pasted_text",
                    "words_extracted": words,
                    "chunks_created": chunks,
                    "user_id": context.get("user").username if context.get("user") else "unknown",
                },
            )
            print(f"{Fore.GREEN}Knowledge analysis triggered{Style.RESET_ALL}")
        except Exception as e:
            print(
                f"{Fore.YELLOW}Warning: Could not trigger knowledge analysis: {str(e)}{Style.RESET_ALL}"
            )


class DocImportUrlCommand(BaseCommand):
    """Import content from a web page URL into the knowledge base"""

    def __init__(self):
        super().__init__(
            name="docs import-url",
            description="Import content from a web page URL into the knowledge base",
            usage="docs import-url <url>",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs import-url command"""
        if not self.validate_args(args, min_count=1):
            url = input(f"{Fore.WHITE}Enter URL: ").strip()
        else:
            url = " ".join(args)  # Allow spaces in URL

        if not url:
            return self.error("URL cannot be empty")

        # Validate URL format
        if not url.startswith(("http://", "https://")):
            return self.error("URL must start with http:// or https://")

        orchestrator = context.get("orchestrator")
        project = context.get("project")

        if not orchestrator:
            return self.error("Orchestrator not available")

        # Ask if they want to link to current project
        project_id = None
        if project:
            link_choice = input(
                f"{Fore.CYAN}Link to current project '{project.name}'? (y/n): "
            ).lower()
            if link_choice == "y":
                project_id = project.project_id

        print(f"{Fore.YELLOW}Fetching URL content...{Style.RESET_ALL}")

        try:
            result = safe_orchestrator_call(
                orchestrator,
                "document_agent",
                {
                    "action": "import_url",
                    "url": url,
                    "project_id": project_id,
                },
                operation_name="import URL",
            )

            file_name = result.get("file_name", "webpage")
            words = result.get("words_extracted", 0)
            chunks = result.get("chunks_created", 0)
            entries = result.get("entries_added", 0)

            self.print_success(f"Successfully imported '{file_name}'")
            print(f"{Fore.WHITE}Content extracted: {words} words")
            print(f"Chunks created: {chunks}")
            print(f"Stored in knowledge base: {entries} entries")

            # CRITICAL: Emit DOCUMENT_IMPORTED event to trigger knowledge analysis
            try:
                from socratic_system.events import EventType

                orchestrator.event_emitter.emit(
                    EventType.DOCUMENT_IMPORTED,
                    {
                        "project_id": project_id,
                        "file_name": file_name,
                        "source_type": "url",
                        "url": url,
                        "words_extracted": words,
                        "chunks_created": chunks,
                        "user_id": (
                            context.get("user").username if context.get("user") else "unknown"
                        ),
                    },
                )
                print(f"{Fore.GREEN}Knowledge analysis triggered{Style.RESET_ALL}")
            except Exception as e:
                print(
                    f"{Fore.YELLOW}Warning: Could not trigger knowledge analysis: {str(e)}{Style.RESET_ALL}"
                )

            return self.success(
                data={
                    "file_name": file_name,
                    "url": url,
                    "words_extracted": words,
                    "chunks_created": chunks,
                    "entries_added": entries,
                }
            )
        except ValueError as e:
            return self.error(str(e))


class DocListCommand(BaseCommand):
    """List imported documents"""

    def __init__(self):
        super().__init__(
            name="docs list",
            description="List all imported documents",
            usage="docs list [project-id]",
        )

    def execute(self, args: list[str], context: dict[str, Any]) -> dict[str, Any]:
        """Execute docs list command"""
        orchestrator = context.get("orchestrator")
        project = context.get("project")

        if not orchestrator:
            return self.error("Orchestrator not available")

        # Get project ID from args or current project
        if args:
            project_id = args[0]
        elif project:
            project_id = project.project_id
        else:
            return self.error("No project specified and no project loaded")

        try:
            result = safe_orchestrator_call(
                orchestrator,
                "document_agent",
                {"action": "list_documents", "project_id": project_id},
                operation_name="list documents",
            )

            documents = result.get("documents", [])

            if not documents:
                self.print_info("No documents imported for this project")
                return self.success()

            print(f"\n{Fore.CYAN}Imported Documents:{Style.RESET_ALL}")
            for i, doc in enumerate(documents, 1):
                file_name = doc.get("file_name", "unknown")
                entries = doc.get("entries_count", 0)
                imported_at = doc.get("imported_at", "unknown")

                print(
                    f"{i}. {Fore.WHITE}{file_name:40}{Style.RESET_ALL} ({entries} entries) - {imported_at}"
                )

            print()
            return self.success(data={"documents": documents})
        except ValueError as e:
            return self.error(str(e))
