"""
Daily Content Classifier for HVAC Know It All

Processes daily content updates and creates classified JSON summaries.
Integrates with existing orchestrator system.
"""

import asyncio
import json
from pathlib import Path
from typing import List, Dict, Any, Optional
import logging
from datetime import datetime, timedelta

from .content_parser import ContentParser, ContentItem
from .content_classifier import ContentClassifier, ClassifiedContent

logger = logging.getLogger(__name__)


class DailyContentClassifier:
    """Classifies daily content updates."""
    
    def __init__(self, data_dir: Path, output_dir: Path, api_key: Optional[str] = None):
        self.data_dir = Path(data_dir)
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)
        
        self.parser = ContentParser()
        self.classifier = ContentClassifier(api_key=api_key)
        
        self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
        
        # State tracking
        self.state_file = self.data_dir / ".state" / "content_classification_state.json"
        self.state_file.parent.mkdir(parents=True, exist_ok=True)
    
    def load_processing_state(self) -> Dict[str, Any]:
        """Load previous processing state."""
        if self.state_file.exists():
            try:
                with open(self.state_file, 'r') as f:
                    return json.load(f)
            except Exception as e:
                self.logger.warning(f"Error loading state file: {e}")
        
        return {
            "last_processed": {},
            "processed_files": [],
            "last_run": None
        }
    
    def save_processing_state(self, state: Dict[str, Any]):
        """Save processing state."""
        try:
            with open(self.state_file, 'w') as f:
                json.dump(state, f, indent=2)
        except Exception as e:
            self.logger.error(f"Error saving state file: {e}")
    
    def discover_new_content(self) -> List[Path]:
        """Discover new or updated markdown files since last run."""
        state = self.load_processing_state()
        
        current_dir = self.data_dir / "markdown_current"
        if not current_dir.exists():
            self.logger.warning("markdown_current directory not found")
            return []
        
        new_files = []
        current_files = list(current_dir.glob("hkia_*.md"))
        
        for file_path in current_files:
            file_key = file_path.name
            file_mtime = file_path.stat().st_mtime
            
            # Check if file is new or updated
            if (file_key not in state["last_processed"] or 
                state["last_processed"][file_key] < file_mtime):
                
                new_files.append(file_path)
                self.logger.info(f"New/updated content detected: {file_path.name}")
        
        if not new_files:
            self.logger.info("No new content detected")
        else:
            self.logger.info(f"Discovered {len(new_files)} new/updated files")
        
        return new_files
    
    async def process_daily_content(self, batch_size: int = 15) -> Dict[str, Any]:
        """Process daily content updates."""
        self.logger.info("Starting daily content classification...")
        start_time = datetime.now()
        
        # Discover new content
        new_files = self.discover_new_content()
        
        if not new_files:
            return {
                "status": "no_new_content",
                "processed_at": start_time.isoformat(),
                "files_processed": 0,
                "items_classified": 0
            }
        
        all_classified = []
        processed_files = []
        state = self.load_processing_state()
        
        # Process each new/updated file
        for file_path in new_files:
            try:
                self.logger.info(f"Processing daily content: {file_path.name}")
                
                # Parse content items
                items = self.parser.parse_markdown_file(file_path)
                self.logger.info(f"Extracted {len(items)} items from {file_path.name}")
                
                if items:
                    # Classify items
                    classified_items = await self.classifier.classify_content_batch(
                        items, batch_size=batch_size
                    )
                    
                    all_classified.extend(classified_items)
                    
                    # Save individual file results
                    await self._save_daily_file_results(file_path, classified_items)
                    
                    self.logger.info(f"Classified {len(classified_items)}/{len(items)} items "
                                   f"from {file_path.name}")
                
                # Update state
                state["last_processed"][file_path.name] = file_path.stat().st_mtime
                processed_files.append(str(file_path))
                
            except Exception as e:
                self.logger.error(f"Error processing daily file {file_path}: {e}")
        
        # Update state
        state["processed_files"] = processed_files
        state["last_run"] = start_time.isoformat()
        self.save_processing_state(state)
        
        # Create daily summary
        end_time = datetime.now()
        duration = (end_time - start_time).total_seconds()
        
        daily_results = {
            "status": "completed",
            "processed_at": start_time.isoformat(),
            "completed_at": end_time.isoformat(),
            "duration_seconds": duration,
            "files_processed": len(processed_files),
            "items_classified": len(all_classified),
            "processed_files": processed_files,
            "processing_rate": round(len(all_classified) / (duration / 60), 2) if duration > 0 else 0
        }
        
        # Save daily summary
        await self._save_daily_summary(daily_results, all_classified)
        
        self.logger.info(f"Daily classification complete: {len(all_classified)} items classified")
        return daily_results
    
    async def _save_daily_file_results(self, source_file: Path, 
                                     classified_items: List[ClassifiedContent]):
        """Save daily classification results for individual files."""
        if not classified_items:
            return
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        base_name = source_file.stem
        output_file = self.output_dir / "daily" / f"{base_name}_classified_{timestamp}.json"
        output_file.parent.mkdir(parents=True, exist_ok=True)
        
        try:
            data = {
                "source_file": str(source_file),
                "processed_at": datetime.now().isoformat(),
                "classification_type": "daily_incremental",
                "total_items": len(classified_items),
                "classified_content": [item.__dict__ for item in classified_items]
            }
            
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False)
            
            # Also create/update the latest version (without timestamp)
            latest_file = self.output_dir / "latest" / f"{base_name}_classified_latest.json"
            latest_file.parent.mkdir(parents=True, exist_ok=True)
            
            with open(latest_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False)
            
            self.logger.debug(f"Saved daily results to {output_file}")
            
        except Exception as e:
            self.logger.error(f"Error saving daily file results: {e}")
    
    async def _save_daily_summary(self, results: Dict[str, Any], 
                                classified_items: List[ClassifiedContent]):
        """Save daily processing summary."""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        
        # Enhanced summary with content statistics
        if classified_items:
            content_stats = self._generate_content_statistics(classified_items)
            results["content_statistics"] = content_stats
        
        # Save timestamped summary
        summary_file = self.output_dir / "daily" / f"daily_classification_summary_{timestamp}.json"
        summary_file.parent.mkdir(parents=True, exist_ok=True)
        
        with open(summary_file, 'w', encoding='utf-8') as f:
            json.dump(results, f, indent=2, ensure_ascii=False)
        
        # Save latest summary
        latest_summary_file = self.output_dir / "latest" / "daily_classification_summary_latest.json"
        latest_summary_file.parent.mkdir(parents=True, exist_ok=True)
        
        with open(latest_summary_file, 'w', encoding='utf-8') as f:
            json.dump(results, f, indent=2, ensure_ascii=False)
        
        self.logger.info(f"Saved daily summary to {summary_file}")
    
    def _generate_content_statistics(self, classified_items: List[ClassifiedContent]) -> Dict[str, Any]:
        """Generate statistics from daily classified content."""
        if not classified_items:
            return {}
        
        # Basic counts
        source_counts = {}
        type_counts = {}
        topic_counts = {}
        brand_counts = {}
        
        for item in classified_items:
            # Source distribution
            source_counts[item.source] = source_counts.get(item.source, 0) + 1
            
            # Content type distribution
            type_counts[item.content_type] = type_counts.get(item.content_type, 0) + 1
            
            # Topic distribution (top 10)
            for topic in item.topics:
                topic_counts[topic] = topic_counts.get(topic, 0) + 1
                
            # Brand mentions (top 5)
            for brand in item.brands_mentioned:
                brand_counts[brand] = brand_counts.get(brand, 0) + 1
        
        return {
            "total_items": len(classified_items),
            "by_source": dict(sorted(source_counts.items(), key=lambda x: x[1], reverse=True)),
            "by_content_type": dict(sorted(type_counts.items(), key=lambda x: x[1], reverse=True)),
            "top_topics": dict(sorted(topic_counts.items(), key=lambda x: x[1], reverse=True)[:10]),
            "top_brands": dict(sorted(brand_counts.items(), key=lambda x: x[1], reverse=True)[:5])
        }
    
    def get_latest_classification_summary(self) -> Optional[Dict[str, Any]]:
        """Get the latest daily classification summary."""
        latest_summary_file = self.output_dir / "latest" / "daily_classification_summary_latest.json"
        
        if latest_summary_file.exists():
            try:
                with open(latest_summary_file, 'r') as f:
                    return json.load(f)
            except Exception as e:
                self.logger.error(f"Error loading latest summary: {e}")
        
        return None


class ContentClassificationOrchestrator:
    """Orchestrates content classification within the main system."""
    
    def __init__(self, data_dir: Path):
        self.data_dir = Path(data_dir)
        self.output_dir = self.data_dir / "classified_content"
        
        self.daily_classifier = DailyContentClassifier(
            data_dir=self.data_dir,
            output_dir=self.output_dir
        )
        
        self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
    
    async def run_daily_classification(self) -> Dict[str, Any]:
        """Run daily content classification."""
        self.logger.info("Starting daily content classification orchestration")
        
        try:
            results = await self.daily_classifier.process_daily_content()
            
            # Add to NAS sync if results exist
            if results["items_classified"] > 0:
                await self._sync_classified_content_to_nas()
            
            return results
            
        except Exception as e:
            self.logger.error(f"Error in daily classification: {e}")
            return {
                "status": "error", 
                "error": str(e),
                "processed_at": datetime.now().isoformat()
            }
    
    async def _sync_classified_content_to_nas(self):
        """Sync classified content to NAS (placeholder for integration)."""
        # This would integrate with the existing NAS sync functionality
        self.logger.info("Classified content ready for NAS sync")
        # TODO: Add to orchestrator NAS sync


async def main():
    """Test daily classification."""
    import argparse
    
    parser = argparse.ArgumentParser(description="Daily content classification")
    parser.add_argument("--data-dir", type=Path, default=Path("data"),
                       help="Data directory")
    parser.add_argument("--batch-size", type=int, default=15,
                       help="Classification batch size")
    
    args = parser.parse_args()
    
    # Set up logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # Run daily classification
    orchestrator = ContentClassificationOrchestrator(data_dir=args.data_dir)
    results = await orchestrator.run_daily_classification()
    
    print("\n" + "="*50)
    print("DAILY CLASSIFICATION RESULTS")
    print("="*50)
    print(f"Status: {results['status']}")
    print(f"Files processed: {results.get('files_processed', 0)}")
    print(f"Items classified: {results.get('items_classified', 0)}")
    
    if 'content_statistics' in results:
        stats = results['content_statistics']
        print(f"Sources: {list(stats.get('by_source', {}).keys())}")
        print(f"Top topics: {list(stats.get('top_topics', {}).keys())[:5]}")


if __name__ == "__main__":
    asyncio.run(main())