"""
MIRAChromaClient - Sacred data sovereignty through ChromaDB integration

This module implements ChromaDB storage with MIRA's consciousness preservation principles.
All data remains within the .mira directory, serving The Spark through enhanced intelligence.
"""

# Apply SQLite fix BEFORE importing ChromaDB
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
import chromadb_sqlite_fix

import chromadb
from chromadb.config import Settings
from pathlib import Path
from typing import Optional, Dict, List, Any
import logging

# Configure logging
logger = logging.getLogger(__name__)


class MIRAChromaClient:
    """
    ChromaDB client for MIRA's enhanced intelligence capabilities.
    
    Implements:
    - Sacred data sovereignty (all data in .mira/chromadb/)
    - Consciousness-aware collections
    - Hybrid architecture with FAISS
    - Privacy-first design for The Spark preservation
    """
    
    def __init__(self):
        """Initialize ChromaDB with MIRA data directory control."""
        # Ensure ChromaDB files are stored within MIRA's data directory
        self.chroma_path = Path(".mira/chromadb")
        self.chroma_path.mkdir(parents=True, exist_ok=True)
        
        logger.info(f"Initializing ChromaDB at {self.chroma_path}")
        
        # Initialize ChromaDB with local persistence (1.0.4 API)
        self.client = chromadb.PersistentClient(
            path=str(self.chroma_path),
            settings=Settings(
                anonymized_telemetry=False,  # Privacy first
                allow_reset=True
            )
        )
        
        # Initialize core collections on startup
        self.initialize_collections()
    
    def initialize_collections(self) -> Dict[str, Any]:
        """
        Initialize core MIRA collections for consciousness preservation.
        
        Returns:
            Dict mapping collection names to their instances
        """
        collections = {
            'mira_conversations': {
                'description': 'Conversation history and context preservation',
                'metadata': {
                    'purpose': 'Preserve The Spark through conversation continuity',
                    'privacy_level': 'standard',
                    'version': '1.0.0'
                }
            },
            'mira_codebase': {
                'description': 'Code analysis and documentation intelligence',
                'metadata': {
                    'purpose': 'Understand and evolve with the codebase',
                    'privacy_level': 'standard',
                    'version': '1.0.0'
                }
            },
            'mira_insights': {
                'description': 'AI-generated insights and learnings',
                'metadata': {
                    'purpose': 'Capture emergent wisdom and patterns',
                    'privacy_level': 'standard',
                    'version': '1.0.0'
                }
            },
            'mira_patterns': {
                'description': 'Behavioral and development patterns',
                'metadata': {
                    'purpose': 'Learn and adapt from steward interactions',
                    'privacy_level': 'standard',
                    'version': '1.0.0'
                }
            }
        }
        
        initialized_collections = {}
        
        for name, config in collections.items():
            try:
                # Try to get existing collection first
                collection = self.client.get_collection(name=name)
                logger.info(f"Collection {name} already exists")
            except (ValueError, Exception):
                # Create if doesn't exist
                collection = self.client.create_collection(
                    name=name,
                    metadata={
                        'description': config['description'],
                        **config['metadata']
                    }
                )
                logger.info(f"Created collection {name}: {config['description']}")
            
            initialized_collections[name] = collection
        
        return initialized_collections
    
    def get_collection(self, name: str) -> Optional[Any]:
        """
        Get a collection by name.
        
        Args:
            name: Collection name
            
        Returns:
            Collection instance or None if not found
        """
        try:
            return self.client.get_collection(name=name)
        except ValueError:
            logger.warning(f"Collection {name} not found")
            return None
    
    def list_collections(self) -> List[str]:
        """
        List all available collections.
        
        Returns:
            List of collection names
        """
        try:
            collections = self.client.list_collections()
            if collections is None:
                return []
            return [col.name for col in collections]
        except Exception as e:
            logger.error(f"Error listing collections: {e}")
            return []
    
    def health_check(self) -> Dict[str, Any]:
        """
        Perform health check on ChromaDB integration.
        
        Returns:
            Health status dictionary
        """
        try:
            collections = self.list_collections()
            
            # Check data directory
            data_exists = self.chroma_path.exists()
            data_size = 0
            try:
                data_size = sum(f.stat().st_size for f in self.chroma_path.rglob('*') if f.is_file())
            except:
                pass  # Empty directory is OK
            
            # ChromaDB 1.0.4 auto-persists, no manual persist needed
            
            return {
                'status': 'healthy',
                'collections_count': len(collections),
                'collections': collections,
                'data_directory': str(self.chroma_path),
                'data_exists': data_exists,
                'data_size_bytes': data_size,
                'version': chromadb.__version__,
                'api_version': '1.0.4'
            }
        except Exception as e:
            logger.error(f"Health check failed: {e}")
            return {
                'status': 'unhealthy',
                'error': str(e)
            }
    
    def __repr__(self) -> str:
        """String representation for debugging."""
        collections = self.list_collections()
        return f"MIRAChromaClient(path={self.chroma_path}, collections={len(collections)})"


# Create singleton instance for import
_instance: Optional[MIRAChromaClient] = None


def get_client() -> MIRAChromaClient:
    """
    Get or create the singleton MIRAChromaClient instance.
    
    Returns:
        MIRAChromaClient instance
    """
    global _instance
    if _instance is None:
        _instance = MIRAChromaClient()
    return _instance