"""
VitalExtractor Agent - Extracts vital information from files
"""

import re
import logging
from pathlib import Path
from typing import Dict, Any, List

from . import EventDrivenAgent
from ..core.config import Config
from ..core.state import StateManager
from ..core.utils import extract_text_from_file


class VitalExtractorAgent(EventDrivenAgent):
    """Agent responsible for extracting vital information from changed files"""

    def __init__(self, config: Config, state_manager: StateManager):
        super().__init__('vital_extractor', config, state_manager)

    def process_event(self, event: Dict[str, Any]) -> Dict[str, Any]:
        """Process file change events and extract vital information"""
        if event['type'] != 'files_changed':
            return {'processed': False}

        changed_files = event.get('changed_files', [])
        vital_info = {}

        for file_path in changed_files:
            file_info = self.extract_vital_info(file_path)
            if file_info:
                vital_info[file_path] = file_info

        if vital_info:
            # Create new event for context updater
            update_event = {
                'type': 'vital_info_extracted',
                'vital_info': vital_info,
                'timestamp': event.get('timestamp')
            }
            self.add_event(update_event)

        return {
            'files_processed': len(changed_files),
            'vital_info_extracted': len(vital_info),
            'vital_info': vital_info
        }

    def extract_vital_info(self, file_path: str) -> Dict[str, Any]:
        """Extract vital information from a specific file"""
        file_path_obj = Path(self.config.workspace_path) / file_path

        if not file_path_obj.exists():
            return None

        # Extract based on file type
        if file_path.endswith('.md'):
            return self.extract_from_markdown(file_path_obj)
        elif file_path.endswith('.yml') or file_path.endswith('.yaml'):
            return self.extract_from_yaml(file_path_obj)
        elif file_path.endswith('.py'):
            return self.extract_from_python(file_path_obj)
        elif file_path.endswith('.env'):
            return self.extract_from_env(file_path_obj)
        elif file_path.endswith('.json'):
            return self.extract_from_json(file_path_obj)
        else:
            return self.extract_generic(file_path_obj)

    def extract_from_markdown(self, file_path: Path) -> Dict[str, Any]:
        """Extract vital info from Markdown files"""
        content = extract_text_from_file(file_path, 200)

        info = {
            'type': 'markdown',
            'sections': []
        }

        # Extract headers
        headers = re.findall(r'^#{1,6}\s+(.+)$', content, re.MULTILINE)
        info['sections'] = headers[:10]  # First 10 headers

        # Special handling for copilot instructions
        if 'copilot-instructions' in str(file_path):
            # Extract golden rules
            golden_match = re.search(r'### Golden Rules Summary(.*?)(?=###|$)', content, re.DOTALL)
            if golden_match:
                info['golden_rules'] = golden_match.group(1).strip()[:500]

            # Extract project overview
            overview_match = re.search(r'## 🧩 Project Overview(.*?)(?=## 🧠)', content, re.DOTALL)
            if overview_match:
                info['project_overview'] = overview_match.group(1).strip()[:300]

        return info

    def extract_from_yaml(self, file_path: Path) -> Dict[str, Any]:
        """Extract vital info from YAML files (like docker-compose)"""
        content = extract_text_from_file(file_path, 100)

        info = {
            'type': 'yaml',
            'services': []
        }

        # Extract service names from docker-compose
        if 'docker-compose' in str(file_path):
            services = re.findall(r'^  (\w+):', content, re.MULTILINE)
            info['services'] = services
            info['service_count'] = len(services)

        return info

    def extract_from_python(self, file_path: Path) -> Dict[str, Any]:
        """Extract vital info from Python files"""
        content = extract_text_from_file(file_path, 100)

        info = {
            'type': 'python',
            'classes': [],
            'functions': []
        }

        # Extract classes and functions
        classes = re.findall(r'^class (\w+)', content, re.MULTILINE)
        functions = re.findall(r'^def (\w+)', content, re.MULTILINE)

        info['classes'] = classes[:5]
        info['functions'] = functions[:10]

        return info

    def extract_from_env(self, file_path: Path) -> Dict[str, Any]:
        """Extract vital info from .env files (safely)"""
        content = extract_text_from_file(file_path, 50)

        info = {
            'type': 'env',
            'variables': []
        }

        # Extract variable names (mask values)
        lines = content.split('\n')
        for line in lines:
            if '=' in line and not line.startswith('#'):
                var_name = line.split('=')[0].strip()
                # Don't extract sensitive values
                if not any(sensitive in var_name.upper() for sensitive in ['KEY', 'SECRET', 'PASSWORD', 'TOKEN']):
                    info['variables'].append(var_name)

        return info

    def extract_from_json(self, file_path: Path) -> Dict[str, Any]:
        """Extract vital info from JSON files"""
        try:
            import json
            with open(file_path, 'r') as f:
                data = json.load(f)

            info = {
                'type': 'json',
                'keys': list(data.keys()) if isinstance(data, dict) else []
            }

            return info
        except:
            return {'type': 'json', 'error': 'Could not parse JSON'}

    def extract_generic(self, file_path: Path) -> Dict[str, Any]:
        """Generic extraction for other file types"""
        content = extract_text_from_file(file_path, 50)

        return {
            'type': 'generic',
            'size': file_path.stat().st_size if file_path.exists() else 0,
            'sample_content': content[:200]
        }