"""Common error handling utilities for CLI controllers."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, TypeVar

if TYPE_CHECKING:
    from collections.abc import Awaitable, Callable

    from portal.interfaces.cli.presenters.output_presenter import OutputPresenter

T = TypeVar("T")


class ErrorHandler:
    """Common error handling for CLI operations."""

    def __init__(self, output_presenter: OutputPresenter) -> None:
        """Initialize error handler.

        Args:
            output_presenter: Presenter for showing errors
        """
        self.output_presenter = output_presenter

    async def handle_operation(
        self,
        operation: Callable[[], Awaitable[T]],
        operation_name: str,
        show_success: bool = False,
        success_message: str | None = None,
    ) -> T | None:
        """Handle an async operation with common error handling.

        Args:
            operation: Async operation to execute
            operation_name: Name for error messages
            show_success: Whether to show success message
            success_message: Custom success message

        Returns:
            Operation result or None if failed
        """
        try:
            result = await operation()

            if show_success and success_message:
                self.output_presenter.show_success(success_message)

            return result

        except Exception as e:
            # Sanitize error message to avoid exposing system internals
            safe_message = self._sanitize_error_message(str(e))
            self.output_presenter.show_error(f"Failed to {operation_name}: {safe_message}")
            return None

    def handle_service_result(self, result: Any, success_message: str | None = None) -> bool:
        """Handle service result with standard success/error pattern.

        Args:
            result: Service result object with success, errors, warnings attributes
            success_message: Optional success message to show

        Returns:
            True if operation succeeded
        """
        if not hasattr(result, "success"):
            return False

        if result.success:
            if success_message:
                self.output_presenter.show_success(success_message)
            return True
        else:
            if hasattr(result, "errors") and result.errors:
                # Sanitize error messages
                safe_errors = [self._sanitize_error_message(err) for err in result.errors]
                self.output_presenter.show_errors(safe_errors)

            if hasattr(result, "warnings") and result.warnings:
                self.output_presenter.show_warnings(result.warnings)

            return False

    def _sanitize_error_message(self, message: str) -> str:
        """Sanitize error messages to avoid exposing sensitive information.

        Args:
            message: Original error message

        Returns:
            Sanitized error message
        """
        # Remove file paths that might contain sensitive information
        if "/Users/" in message or "/home/" in message:
            # Replace with generic path
            import re

            message = re.sub(r"/(?:Users|home)/[^/\s]+", "/path/to/user", message)

        # Remove potential stack trace information
        if "Traceback" in message:
            lines = message.split("\n")
            # Keep only the last meaningful line
            for line in reversed(lines):
                if line.strip() and not line.startswith(" ") and "Error:" in line:
                    return line.strip()
            return "An internal error occurred"

        return message
