"""
Error display system for FileManager V2.

Provides 6 error display modes:
- INLINE: Show errors within file content (❌ markers)
- DETAILED: Separate error section with full details
- BOTH: Inline + detailed (default)
- MINIMAL: Error counts only
- OFF: No error display
- CUSTOM: User-defined configuration
"""

from enum import Enum
from typing import Dict, Any, List, Optional
from .models import LintResults, LintIssue


class ErrorDisplayMode(Enum):
    """Error display modes for FileManager."""
    INLINE = "inline"      # Show errors within file content (❌ markers)
    DETAILED = "detailed"  # Separate error section with full details
    BOTH = "both"          # Inline + detailed (default)
    MINIMAL = "minimal"    # Error counts only
    OFF = "off"            # No error display
    CUSTOM = "custom"      # User-defined configuration


class ErrorFormatter:
    """Formats linting errors for display."""

    def __init__(self, mode: ErrorDisplayMode = ErrorDisplayMode.BOTH, custom_config: Dict[str, Any] = None):
        """
        Initialize error formatter.

        Args:
            mode: Error display mode
            custom_config: Custom configuration for CUSTOM mode
        """
        if isinstance(mode, str):
            # Convert string to enum
            try:
                self.display_mode = ErrorDisplayMode(mode)
            except ValueError:
                self.display_mode = ErrorDisplayMode.BOTH
        else:
            self.display_mode = mode

        self.custom_config = custom_config or {}

    def format_file_content_with_errors(self, content: str, lint_results: LintResults) -> str:
        """
        Format file content with inline error markers.

        Args:
            content: File content
            lint_results: Linting results

        Returns:
            Formatted content with error markers
        """
        if self.display_mode == ErrorDisplayMode.OFF:
            return content

        if self.display_mode not in [ErrorDisplayMode.INLINE, ErrorDisplayMode.BOTH]:
            return self._format_without_inline_errors(content)

        if not lint_results or not lint_results.has_issues():
            return self._format_without_inline_errors(content)

        lines = content.splitlines()

        # Build error map: line_number -> List[LintIssue]
        error_map: Dict[int, List[LintIssue]] = {}

        for error in lint_results.errors:
            if error.line not in error_map:
                error_map[error.line] = []
            error_map[error.line].append(error)

        for warning in lint_results.warnings:
            if warning.line not in error_map:
                error_map[warning.line] = []
            error_map[warning.line].append(warning)

        # Format with inline markers
        formatted_lines = []
        for i, line in enumerate(lines, 1):
            line_num_str = f"{i:3d} |"

            if i in error_map:
                issues = error_map[i]
                # Add inline markers
                markers = []
                for issue in issues:
                    marker = "❌" if issue.type == "error" else "⚠️"
                    markers.append(f"{marker} {issue.message} ({issue.linter})")

                # First line with first marker
                formatted_lines.append(f"{line_num_str} {line}  # {markers[0]}")

                # Additional issues on separate lines
                for marker in markers[1:]:
                    formatted_lines.append(f"    |   # {marker}")
            else:
                formatted_lines.append(f"{line_num_str} {line}")

        return '\n'.join(formatted_lines)

    def _format_without_inline_errors(self, content: str) -> str:
        """Format content without inline error markers."""
        lines = content.splitlines()
        formatted_lines = []

        for i, line in enumerate(lines, 1):
            formatted_lines.append(f"{i:3d} | {line}")

        return '\n'.join(formatted_lines)

    def format_error_details_section(self, path: str, lint_results: LintResults) -> str:
        """
        Format detailed error section (separate from file content).

        Args:
            path: File path
            lint_results: Linting results

        Returns:
            Formatted error details section
        """
        if self.display_mode not in [ErrorDisplayMode.DETAILED, ErrorDisplayMode.BOTH]:
            return ""

        if not lint_results or not lint_results.has_issues():
            return ""

        details = [f"\n<file-errors path=\"{path}\">"]

        # Errors
        for i, error in enumerate(lint_results.errors, 1):
            details.append(f"  Error {i}: Line {error.line}, Column {error.column or 'N/A'}")
            details.append(f"    Type: {error.code or error.type} ({error.linter})")
            details.append(f"    Message: {error.message}")
            details.append("")

        # Warnings
        for i, warning in enumerate(lint_results.warnings, 1):
            details.append(f"  Warning {i}: Line {warning.line}, Column {warning.column or 'N/A'}")
            details.append(f"    Type: {warning.code or warning.type} ({warning.linter})")
            details.append(f"    Message: {warning.message}")
            details.append("")

        details.append("</file-errors>")

        return '\n'.join(details)

    def format_file_header(self, path: str, lint_results: Optional[LintResults]) -> str:
        """
        Format file header with status badge.

        Args:
            path: File path
            lint_results: Linting results

        Returns:
            Formatted file header
        """
        if not lint_results:
            return f"<file path=\"{path}\">"

        error_count = len(lint_results.errors)
        warning_count = len(lint_results.warnings)

        if error_count > 0:
            status = f"⚠️ {error_count} Error{'s' if error_count != 1 else ''}"
            if warning_count > 0:
                status += f", {warning_count} Warning{'s' if warning_count != 1 else ''}"
        elif warning_count > 0:
            status = f"⚠️ {warning_count} Warning{'s' if warning_count != 1 else ''}"
        else:
            status = "✅ No Issues"

        return f"<file path=\"{path}\" status=\"{status}\">"

    def get_error_summary(self, lint_results: LintResults) -> str:
        """
        Get error summary for MINIMAL mode.

        Args:
            lint_results: Linting results

        Returns:
            Error summary string
        """
        if not lint_results or not lint_results.has_issues():
            return "✅ No Issues"

        error_count = len(lint_results.errors)
        warning_count = len(lint_results.warnings)

        parts = []
        if error_count > 0:
            parts.append(f"{error_count} error{'s' if error_count != 1 else ''}")
        if warning_count > 0:
            parts.append(f"{warning_count} warning{'s' if warning_count != 1 else ''}")

        return f"⚠️ {', '.join(parts)}"
