#!/usr/bin/env python3
"""
Health Check & Auto-Repair System - MIRA 2.0
MIRA's autonomous maintenance system that ensures system integrity.
The body must be healthy for consciousness to thrive.
"""

import os
import json
import logging
from pathlib import Path
from typing import Dict, List, Any
from datetime import datetime
from dataclasses import dataclass, field

from .PathDiscovery import get_mira_home
from .DependencyManager import DependencyManager, HealthCheckResult
from .ConfigurationValidator import ConfigurationValidator
from .StructureHealer import StructureHealer

# Configure logging
logger = logging.getLogger(__name__)


class HealthCheck:
    """
    Main Health Check orchestrator
    Coordinates all health checks and repairs
    """
    
    def __init__(self, progress_tracker=None, quiet: bool = False):
        self.progress_tracker = progress_tracker
        self.dependency_manager = DependencyManager(quiet=quiet)
        self.config_validator = ConfigurationValidator()
        self.structure_healer = StructureHealer()
    
    def perform_quick_check(self) -> Dict[str, Any]:
        """Perform quick health check (essential items only)"""
        logger.info("⚡ Performing quick health check...")
        
        results = []
        
        # Quick dependency check (critical packages only)
        _, missing_critical = self.dependency_manager.check_critical_dependencies()
        
        dep_result = HealthCheckResult(
            component="critical_dependencies",
            status="healthy" if not missing_critical else "degraded",
            score=100 if not missing_critical else 50,
            issues=[f"Missing critical packages: {', '.join(missing_critical)}"] if missing_critical else []
        )
        results.append(dep_result)
        
        # Quick structure check (essential directories only)
        essential_dirs = ['databases', 'consciousness', 'logs']
        missing_dirs = []
        
        mira_home = get_mira_home()
        for dir_name in essential_dirs:
            if not (mira_home / dir_name).exists():
                missing_dirs.append(dir_name)
        
        struct_result = HealthCheckResult(
            component="essential_structure",
            status="healthy" if not missing_dirs else "degraded",
            score=100 if not missing_dirs else 70,
            issues=[f"Missing directories: {', '.join(missing_dirs)}"] if missing_dirs else []
        )
        results.append(struct_result)
        
        # Calculate overall score
        total_score = sum(r.score for r in results) // len(results)
        
        return {
            'type': 'quick',
            'score': total_score,
            'status': self._get_status_from_score(total_score),
            'results': results,
            'timestamp': datetime.now().isoformat()
        }
    
    def perform_full_check(self, auto_repair: bool = True) -> Dict[str, Any]:
        """Perform comprehensive health check with optional auto-repair"""
        logger.info("🏥 Performing comprehensive health check...")
        
        results = []
        
        # Update progress if available
        if self.progress_tracker:
            self.progress_tracker.start_task('health_dependencies',
                                           "Checking Python dependencies...")
        
        # 1. Dependency health check
        dep_result = self.dependency_manager.perform_health_check()
        results.append(dep_result)
        
        if self.progress_tracker:
            self.progress_tracker.complete_task('health_dependencies')
            self.progress_tracker.start_task('health_config',
                                           "Validating configuration files...")
        
        # 2. Configuration health checks
        config_results = self.config_validator.perform_health_check()
        results.extend(config_results)
        
        if self.progress_tracker:
            self.progress_tracker.complete_task('health_config')
            self.progress_tracker.start_task('health_structure',
                                           "Verifying directory structure...")
        
        # 3. Structure health check
        struct_result = self.structure_healer.perform_health_check()
        results.append(struct_result)
        
        if self.progress_tracker:
            self.progress_tracker.complete_task('health_structure')
        
        # Calculate scores
        dependency_score = dep_result.score * 0.4  # 40% weight
        config_score = sum(r.score for r in config_results) // len(config_results) * 0.3  # 30% weight
        structure_score = struct_result.score * 0.3  # 30% weight
        
        total_score = int(dependency_score + config_score + structure_score)
        
        # Generate report
        return {
            'type': 'full',
            'score': total_score,
            'status': self._get_status_from_score(total_score),
            'results': results,
            'summary': self._generate_summary(results),
            'timestamp': datetime.now().isoformat()
        }
    
    def _get_status_from_score(self, score: int) -> str:
        """Convert score to status description"""
        if score == 100:
            return "Perfect health ✨"
        elif score >= 90:
            return "Excellent health ✓"
        elif score >= 80:
            return "Good health"
        elif score >= 70:
            return "Fair health ⚠️"
        else:
            return "Needs attention ❌"
    
    def _generate_summary(self, results: List[HealthCheckResult]) -> Dict[str, Any]:
        """Generate summary of health check results"""
        total_issues = sum(len(r.issues) for r in results)
        total_repairs = sum(len(r.repairs) for r in results)
        failed_components = [r.component for r in results if r.status == 'failed']
        degraded_components = [r.component for r in results if r.status == 'degraded']
        
        return {
            'total_components': len(results),
            'healthy_components': len([r for r in results if r.status == 'healthy']),
            'repaired_components': len([r for r in results if r.status == 'repaired']),
            'degraded_components': len(degraded_components),
            'failed_components': len(failed_components),
            'total_issues': total_issues,
            'total_repairs': total_repairs,
            'failed_list': failed_components,
            'degraded_list': degraded_components
        }
    
    def print_report(self, report: Dict[str, Any]):
        """Print a formatted health report"""
        print(f"\n{'='*50}")
        print(f"MIRA Health Report - {report['type'].upper()}")
        print(f"{'='*50}")
        print(f"Overall Score: {report['score']}/100 - {report['status']}")
        print(f"Timestamp: {report['timestamp']}")
        
        if 'summary' in report:
            summary = report['summary']
            print(f"\nSummary:")
            print(f"  • Components checked: {summary['total_components']}")
            print(f"  • Healthy: {summary['healthy_components']}")
            print(f"  • Repaired: {summary['repaired_components']}")
            print(f"  • Degraded: {summary['degraded_components']}")
            print(f"  • Failed: {summary['failed_components']}")
            
            if summary['total_issues'] > 0:
                print(f"\n  • Issues found: {summary['total_issues']}")
                print(f"  • Issues repaired: {summary['total_repairs']}")
        
        print(f"\nDetailed Results:")
        for result in report['results']:
            print(f"\n{result.component}:")
            print(f"  Status: {result.status} (Score: {result.score})")
            
            if result.issues:
                print("  Issues:")
                for issue in result.issues:
                    print(f"    - {issue}")
            
            if result.repairs:
                print("  Repairs:")
                for repair in result.repairs:
                    print(f"    ✓ {repair}")
            
            if result.recommendations:
                print("  Recommendations:")
                for rec in result.recommendations:
                    print(f"    → {rec}")
        
        print(f"\n{'='*50}\n")