"""Export handler for content list results.

Routes formatted content to various destinations:
- console: Print to stdout
- clipboard: Copy using pyperclip
- file: Write to specified path
"""

import sys
from pathlib import Path
from typing import Any

from alloy_runtime_types.dtos.content import ContentPartItemResponse

from cli.commands.content.list.export_formatters import (
    EXPORT_FORMATTERS,
    get_available_formats,
)
from cli.infrastructure.output import OutputService

# Import pyperclip at module level for easier mocking in tests
pyperclip: Any | None = None
try:
    import pyperclip as _pyperclip
except ImportError:
    pass
else:
    pyperclip = _pyperclip

PYPERCLIP_AVAILABLE = pyperclip is not None


def export_content(
    items: list[ContentPartItemResponse],
    export_format: str,
    output_mode: str,
    output_file: str | None,
    group_by: str | None,
) -> bool:
    """Export content items to specified destination.

    Args:
        items: List of content part items to export
        export_format: Format name (markdown, xml, numbered, plain, json)
        output_mode: Destination (console, clipboard, file)
        output_file: File path for file output mode
        group_by: Optional tag prefix to group items by

    Returns:
        True on success, False on failure
    """
    output = OutputService.get()

    # Validate format
    formatter_cls = EXPORT_FORMATTERS.get(export_format)
    if not formatter_cls:
        available = ", ".join(get_available_formats())
        output.warning(
            f"Unknown export format: '{export_format}'. Available: {available}"
        )
        return False

    # Check for empty items
    if not items:
        output.info("No content items to export")
        return True

    # Format the content
    formatter = formatter_cls()
    formatted_content = formatter.format(items, group_by)

    # Route to destination
    if output_mode == "clipboard":
        return _copy_to_clipboard(formatted_content, len(items), output)
    elif output_mode == "file":
        return _save_to_file(formatted_content, output_file, len(items), output)
    else:  # console (default)
        return _print_to_console(formatted_content, output)


def _print_to_console(content: str, _output: OutputService) -> bool:
    """Print formatted content to stdout.

    Args:
        content: Formatted content string
        output: Output service for messages

    Returns:
        True on success
    """
    try:
        print(content, file=sys.stdout)
        return True
    except (BrokenPipeError, IOError):
        # Pipe was closed (e.g., piping to head)
        return True


def _copy_to_clipboard(content: str, item_count: int, output: OutputService) -> bool:
    """Copy formatted content to clipboard.

    Args:
        content: Formatted content string
        item_count: Number of items exported (for status message)
        output: Output service for messages

    Returns:
        True on success, False on failure
    """
    if not PYPERCLIP_AVAILABLE or pyperclip is None:
        output.warning("pyperclip not installed. Install with: pip install pyperclip")
        output.info("Falling back to console output...")
        print(content, file=sys.stdout)
        return False

    try:
        pyperclip.copy(content)
        output.success(
            f"Exported {item_count} item(s) to clipboard ({len(content):,} characters)"
        )
        return True
    except Exception as e:
        output.warning(f"Failed to copy to clipboard: {e}")
        output.info("Falling back to console output...")
        print(content, file=sys.stdout)
        return False


def _save_to_file(
    content: str, output_file: str | None, item_count: int, output: OutputService
) -> bool:
    """Save formatted content to a file.

    Args:
        content: Formatted content string
        output_file: Target file path
        item_count: Number of items exported (for status message)
        output: Output service for messages

    Returns:
        True on success, False on failure
    """
    if not output_file:
        output.warning("No output file specified (use --output-file)")
        return False

    try:
        file_path = Path(output_file).expanduser().resolve()

        # Ensure parent directory exists
        file_path.parent.mkdir(parents=True, exist_ok=True)

        # Write the content
        file_path.write_text(content, encoding="utf-8")

        output.success(
            f"Exported {item_count} item(s) to {file_path} ({len(content):,} characters)"
        )
        return True
    except PermissionError:
        output.warning(f"Permission denied: Cannot write to '{output_file}'")
        return False
    except OSError as e:
        output.warning(f"Failed to save file: {e}")
        return False
