from PySide6.QtCore import QAbstractListModel, Qt, Slot
from PySide6.QtQml import QmlElement
from pathlib import Path

QML_IMPORT_NAME = "DuneWeaver"
QML_IMPORT_MAJOR_VERSION = 1

@QmlElement
class PatternModel(QAbstractListModel):
    """Model for pattern list with direct file system access"""
    
    NameRole = Qt.UserRole + 1
    PathRole = Qt.UserRole + 2
    PreviewRole = Qt.UserRole + 3
    
    def __init__(self):
        super().__init__()
        self._patterns = []
        self._filtered_patterns = []
        # Look for patterns in the parent directory (main dune-weaver folder)
        self.patterns_dir = Path("../patterns")
        self.cache_dir = Path("../patterns/cached_images")
        self.refresh()
    
    def roleNames(self):
        return {
            self.NameRole: b"name",
            self.PathRole: b"path", 
            self.PreviewRole: b"preview"
        }
    
    def rowCount(self, parent=None):
        return len(self._filtered_patterns)
    
    def data(self, index, role):
        if not index.isValid() or index.row() >= len(self._filtered_patterns):
            return None
        
        pattern = self._filtered_patterns[index.row()]
        
        if role == self.NameRole:
            return pattern["name"]
        elif role == self.PathRole:
            return pattern["path"]
        elif role == self.PreviewRole:
            # For patterns in subdirectories, check both flattened and hierarchical cache structures
            pattern_name = pattern["name"]
            
            # Try PNG format for kiosk compatibility
            # First try hierarchical structure (preserving subdirectories)
            preview_path_hierarchical = self.cache_dir / f"{pattern_name}.png"
            if preview_path_hierarchical.exists():
                return str(preview_path_hierarchical.absolute())
            
            # Then try flattened structure (replace / with _)
            preview_name_flat = pattern_name.replace("/", "_").replace("\\", "_")
            preview_path_flat = self.cache_dir / f"{preview_name_flat}.png"
            if preview_path_flat.exists():
                return str(preview_path_flat.absolute())
            
            # Fallback to WebP if PNG not found (for existing caches)
            preview_path_hierarchical_webp = self.cache_dir / f"{pattern_name}.webp"
            if preview_path_hierarchical_webp.exists():
                return str(preview_path_hierarchical_webp.absolute())
            
            preview_path_flat_webp = self.cache_dir / f"{preview_name_flat}.webp"
            if preview_path_flat_webp.exists():
                return str(preview_path_flat_webp.absolute())
            
            return ""
        
        return None
    
    @Slot()
    def refresh(self):
        print(f"Loading patterns from: {self.patterns_dir.absolute()}")
        self.beginResetModel()
        patterns = []
        for file_path in self.patterns_dir.rglob("*.thr"):
            relative = file_path.relative_to(self.patterns_dir)
            patterns.append({
                "name": str(relative),
                "path": str(file_path)
            })
        self._patterns = sorted(patterns, key=lambda x: x["name"])
        self._filtered_patterns = self._patterns.copy()
        print(f"Loaded {len(self._patterns)} patterns")
        self.endResetModel()
    
    @Slot(str)
    def filter(self, search_text):
        self.beginResetModel()
        if not search_text:
            self._filtered_patterns = self._patterns.copy()
        else:
            search_lower = search_text.lower()
            self._filtered_patterns = [
                p for p in self._patterns 
                if search_lower in p["name"].lower()
            ]
        self.endResetModel()