"""
Pyright type checker plugin for FileManager V2.

Provides Python type checking via Pyright.
"""

import os
import json
import logging
import tempfile
import subprocess
from pathlib import Path
from typing import Optional, Dict

from ..base import LinterPlugin
from ...models import LintResults, LintIssue

logger = logging.getLogger(__name__)


class PyrightLinterPlugin(LinterPlugin):
    """Pyright type checker plugin - direct LinterPlugin inheritance."""

    def __init__(self, config: Optional[Dict] = None):
        """
        Initialize Pyright linter with optional configuration.

        Config options:
        - timeout: Seconds before timeout (default: 10)
        - strict: Enable strict mode (default: False)

        Args:
            config: Optional configuration dict
        """
        self.config = config or {}
        self.timeout = self.config.get('timeout', 10)
        self.strict = self.config.get('strict', False)

    @property
    def name(self) -> str:
        """Plugin name."""
        return "pyright"

    def on_plugin_enabled(self, manager) -> None:
        """Called when pyright is enabled."""
        logger.info("Pyright type checker enabled")

    def can_handle_file(self, path: str) -> bool:
        """
        Pyright only handles Python files.

        Args:
            path: File path

        Returns:
            True if file is a Python file (.py)
        """
        return Path(path).suffix == '.py'

    def lint_content(self, path: str, content: str) -> LintResults:
        """
        Run pyright on file content and return results.

        Args:
            path: File path
            content: File content

        Returns:
            LintResults with errors and warnings
        """
        results = LintResults()

        # Write content to temp file for linting
        temp_file = None
        try:
            with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
                f.write(content)
                temp_file = f.name

            # Build pyright command
            cmd = ['pyright', temp_file, '--outputjson']
            if self.strict:
                cmd.append('--strict')

            # Run pyright
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=self.timeout
            )

            # Parse JSON output
            if result.stdout:
                try:
                    output = json.loads(result.stdout)

                    for diagnostic in output.get('generalDiagnostics', []):
                        severity = diagnostic.get('severity', 'warning')

                        issue = LintIssue(
                            line=diagnostic['range']['start']['line'] + 1,
                            column=diagnostic['range']['start']['character'] + 1,
                            type='error' if severity == 'error' else 'warning',
                            message=diagnostic['message'],
                            linter='pyright',
                            code=diagnostic.get('rule')
                        )

                        if issue.type == 'error':
                            results.errors.append(issue)
                        else:
                            results.warnings.append(issue)

                except json.JSONDecodeError:
                    logger.warning("Failed to parse pyright JSON output")
                    results.linter_runs['pyright'] = False
                    return results

            results.linter_runs['pyright'] = True

        except FileNotFoundError:
            logger.warning("Pyright not installed - install with: npm install -g pyright")
            results.linter_runs['pyright'] = False

        except subprocess.TimeoutExpired:
            logger.warning(f"Pyright timeout after {self.timeout}s")
            results.linter_runs['pyright'] = False

        except Exception as e:
            logger.error(f"Pyright execution failed: {e}")
            results.linter_runs['pyright'] = False

        finally:
            # Clean up temp file
            if temp_file and os.path.exists(temp_file):
                try:
                    os.unlink(temp_file)
                except Exception:
                    pass

        return results

    def generate_hint(self, path: str, results: LintResults) -> str:
        """
        Generate pyright-specific hints.

        Args:
            path: File path
            results: Linting results

        Returns:
            Custom hint string
        """
        if not results.has_issues():
            return ""

        hints = []

        # Check for common error patterns
        error_messages = [err.message.lower() for err in results.errors]

        if any('not defined' in msg for msg in error_messages):
            hints.append("Check for undefined variables or missing imports")

        if any('type' in msg for msg in error_messages):
            hints.append("Consider adding type annotations for better type safety")

        if any('incompatible' in msg for msg in error_messages):
            hints.append("Check type compatibility between assignments")

        return "; ".join(hints) if hints else ""
