"""
Configuration management CLI commands.

Provides commands for configuration validation, display, and troubleshooting.
"""

import os
import sys
from pathlib import Path
from typing import Dict, Any, List, Tuple, Optional

from config import (
    get_unified_config, get_config_status, MarkitectConfig,
    ConfigurationError, ConfigValidationError, load_env_file
)
from ..presenters.config import ConfigPresenter


class ConfigCommands:
    """Configuration management command handlers."""

    def __init__(self) -> None:
        self.presenter = ConfigPresenter()

    def show_config(self, show_sensitive: bool = False) -> None:
        """Display current configuration values."""
        try:
            config = get_unified_config()
            status = get_config_status()

            self.presenter.show_configuration(config, status, show_sensitive)

        except ConfigurationError as e:
            self.presenter.show_error(f"Configuration error: {e}")
            sys.exit(1)
        except Exception as e:
            self.presenter.show_error(f"Unexpected error: {e}")
            sys.exit(1)

    def validate_config(self, verbose: bool = False) -> None:
        """Validate current configuration and show any issues."""
        try:
            config = get_unified_config()
            validation_results = self._perform_validation_checks(config)

            self.presenter.show_validation_results(validation_results, verbose)

            # Exit with non-zero code if there are errors
            if any(result['status'] == 'error' for result in validation_results):
                sys.exit(1)

        except ConfigurationError as e:
            self.presenter.show_error(f"Configuration error: {e}")
            sys.exit(1)
        except Exception as e:
            self.presenter.show_error(f"Unexpected error: {e}")
            sys.exit(1)

    def troubleshoot_config(self) -> None:
        """Run comprehensive configuration troubleshooting."""
        try:
            config = get_unified_config()
            status = get_config_status()

            # Perform all diagnostic checks
            diagnostics = self._run_diagnostics(config)

            self.presenter.show_troubleshooting_results(config, status, diagnostics)

        except Exception as e:
            # Even if config loading fails, we can still provide diagnostics
            diagnostics = self._run_basic_diagnostics()
            self.presenter.show_troubleshooting_results(None, None, diagnostics)

    def check_config_files(self) -> None:
        """Check for configuration files and their status."""
        file_checks = self._check_configuration_files()
        self.presenter.show_config_file_status(file_checks)

    def _perform_validation_checks(self, config: MarkitectConfig) -> List[Dict[str, Any]]:
        """Perform comprehensive configuration validation."""
        results = []

        # Check required fields
        required_fields = [
            ('gitea_url', 'Gitea/Git platform URL'),
            ('repo_owner', 'Repository owner'),
            ('repo_name', 'Repository name'),
        ]

        for field, description in required_fields:
            value = getattr(config, field, None)
            if not value or (isinstance(value, str) and not value.strip()):
                results.append({
                    'check': f'Required field: {description}',
                    'status': 'error',
                    'message': f'{description} is required but not set',
                    'suggestion': f'Set {field.upper()} in environment or .env.tddai file'
                })
            else:
                results.append({
                    'check': f'Required field: {description}',
                    'status': 'success',
                    'message': f'{description} is properly configured'
                })

        # Check URL format
        if config.gitea_url:
            if not (config.gitea_url.startswith('http://') or config.gitea_url.startswith('https://')):
                results.append({
                    'check': 'URL format validation',
                    'status': 'error',
                    'message': 'Gitea URL must start with http:// or https://',
                    'suggestion': 'Update gitea_url to include protocol (e.g., https://github.com)'
                })
            else:
                results.append({
                    'check': 'URL format validation',
                    'status': 'success',
                    'message': 'Gitea URL format is valid'
                })

        # Check workspace directory
        workspace_path = Path(config.workspace_dir)
        if workspace_path.exists() and not workspace_path.is_dir():
            results.append({
                'check': 'Workspace directory',
                'status': 'error',
                'message': f'Workspace path exists but is not a directory: {workspace_path}',
                'suggestion': 'Remove the file or choose a different workspace directory'
            })
        else:
            results.append({
                'check': 'Workspace directory',
                'status': 'success',
                'message': f'Workspace directory is valid: {workspace_path}'
            })

        # Check authentication token
        auth_token = os.getenv('GITEA_API_TOKEN') or os.getenv('GITHUB_TOKEN')
        if not auth_token:
            results.append({
                'check': 'Authentication token',
                'status': 'warning',
                'message': 'No authentication token found',
                'suggestion': 'Set GITEA_API_TOKEN or GITHUB_TOKEN environment variable for API access'
            })
        else:
            results.append({
                'check': 'Authentication token',
                'status': 'success',
                'message': 'Authentication token is configured'
            })

        return results

    def _run_diagnostics(self, config: Optional[MarkitectConfig]) -> Dict[str, Any]:
        """Run comprehensive diagnostics."""
        diagnostics = {}

        # Environment diagnostics
        diagnostics['environment'] = self._check_environment()

        # File system diagnostics
        diagnostics['filesystem'] = self._check_filesystem()

        # Configuration files diagnostics
        diagnostics['config_files'] = self._check_configuration_files()

        # Git repository diagnostics
        diagnostics['git_repository'] = self._check_git_repository()

        # Network diagnostics (if config available)
        if config:
            diagnostics['network'] = self._check_network_connectivity(config)

        return diagnostics

    def _run_basic_diagnostics(self) -> Dict[str, Any]:
        """Run basic diagnostics when config loading fails."""
        return {
            'environment': self._check_environment(),
            'filesystem': self._check_filesystem(),
            'config_files': self._check_configuration_files(),
            'git_repository': self._check_git_repository(),
        }

    def _check_environment(self) -> Dict[str, Any]:
        """Check environment variables and settings."""
        relevant_vars = [
            'TDDAI_GITEA_URL', 'TDDAI_REPO_OWNER', 'TDDAI_REPO_NAME',
            'TDDAI_WORKSPACE_DIR', 'GITEA_API_TOKEN', 'GITHUB_TOKEN',
            'PYTHONPATH', 'PATH'
        ]

        env_status = {}
        for var in relevant_vars:
            value = os.getenv(var)
            env_status[var] = {
                'set': value is not None,
                'value': '***HIDDEN***' if 'TOKEN' in var and value else value,
                'length': len(value) if value else 0
            }

        return {
            'python_version': sys.version,
            'python_executable': sys.executable,
            'current_directory': str(Path.cwd()),
            'environment_variables': env_status
        }

    def _check_filesystem(self) -> Dict[str, Any]:
        """Check file system permissions and paths."""
        current_dir = Path.cwd()

        return {
            'current_directory': {
                'path': str(current_dir),
                'exists': current_dir.exists(),
                'readable': os.access(current_dir, os.R_OK),
                'writable': os.access(current_dir, os.W_OK),
            },
            'home_directory': {
                'path': str(Path.home()),
                'exists': Path.home().exists(),
                'readable': os.access(Path.home(), os.R_OK),
                'writable': os.access(Path.home(), os.W_OK),
            }
        }

    def _check_configuration_files(self) -> Dict[str, Any]:
        """Check for configuration files and their status."""
        config_files = {
            '.env.tddai': Path('.env.tddai'),
            '.env': Path('.env'),
            'pyproject.toml': Path('pyproject.toml'),
            'tddai-setup.sh': Path('tddai-setup.sh'),
        }

        file_status = {}
        for name, path in config_files.items():
            file_status[name] = {
                'path': str(path),
                'exists': path.exists(),
                'readable': path.exists() and os.access(path, os.R_OK),
                'size': path.stat().st_size if path.exists() else 0,
                'modified': path.stat().st_mtime if path.exists() else None
            }

            # Try to parse .env files
            if name.startswith('.env') and path.exists():
                try:
                    env_vars = load_env_file(path)
                    file_status[name]['parsed_variables'] = len(env_vars)
                    file_status[name]['parse_error'] = None
                except Exception as e:
                    file_status[name]['parsed_variables'] = 0
                    file_status[name]['parse_error'] = str(e)

        return file_status

    def _check_git_repository(self) -> Dict[str, Any]:
        """Check git repository status."""
        git_dir = Path('.git')

        status = {
            'is_git_repository': git_dir.exists(),
            'git_directory': str(git_dir),
        }

        if git_dir.exists():
            try:
                import subprocess

                # Get remote origin URL
                result = subprocess.run(
                    ['git', 'remote', 'get-url', 'origin'],
                    capture_output=True, text=True, timeout=5
                )
                if result.returncode == 0:
                    status['remote_origin'] = result.stdout.strip()

                # Get current branch
                result = subprocess.run(
                    ['git', 'branch', '--show-current'],
                    capture_output=True, text=True, timeout=5
                )
                if result.returncode == 0:
                    status['current_branch'] = result.stdout.strip()

            except (subprocess.TimeoutExpired, FileNotFoundError):
                status['git_command_available'] = False

        return status

    def _check_network_connectivity(self, config: MarkitectConfig) -> Dict[str, Any]:
        """Check network connectivity to configured services."""
        status = {}

        if config.gitea_url:
            try:
                import urllib.request
                import urllib.parse

                parsed_url = urllib.parse.urlparse(config.gitea_url)
                base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"

                req = urllib.request.Request(base_url)
                req.add_header('User-Agent', 'tddai-config-check/1.0')

                with urllib.request.urlopen(req, timeout=10) as response:
                    status['gitea_connectivity'] = {
                        'url': base_url,
                        'status_code': response.getcode(),
                        'reachable': True
                    }

            except Exception as e:
                status['gitea_connectivity'] = {
                    'url': config.gitea_url,
                    'reachable': False,
                    'error': str(e)
                }

        return status