"""File management for YAML note files."""

import os
import logging
from pathlib import Path
from typing import List, Optional, Dict
import re

from .models import Note

logger = logging.getLogger(__name__)


class FileManager:
    """Manages reading and writing YAML note files."""
    
    def __init__(self, base_dir: str = "notes"):
        """Initialize file manager.
        
        Args:
            base_dir: Base directory for storing YAML files
        """
        self.base_dir = Path(base_dir)
        self.base_dir.mkdir(exist_ok=True, parents=True)
    
    def sanitize_filename(self, text: str, note_id: int) -> str:
        """Generate a safe filename from note content.
        
        Args:
            text: Text to use as basis for filename (typically from a field)
            note_id: Note ID for uniqueness
            
        Returns:
            Safe filename with .yaml extension
        """
        # Remove non-alphanumeric characters except spaces and hyphens
        safe_text = re.sub(r'[^a-zA-Z0-9\s\-]', '', text)
        # Replace spaces with hyphens
        safe_text = re.sub(r'\s+', '-', safe_text).lower()
        # Remove leading/trailing hyphens
        safe_text = safe_text.strip('-')
        # Truncate to reasonable length (leaving room for ID)
        safe_text = safe_text[:40]
        
        if not safe_text:
            safe_text = "note"
        
        # Include note ID to ensure uniqueness
        return f"{safe_text}_{note_id}.yaml"
    
    def save_note(self, note: Note) -> str:
        """Save a note to a YAML file.
        
        Args:
            note: The Note object to save
            
        Returns:
            Path to the saved file (relative to base_dir)
        """
        filename = self.sanitize_filename(note.get_summary(), note.id)
        filepath = self.base_dir / filename
        
        yaml_content = note.to_yaml()
        
        with open(filepath, 'w') as f:
            f.write(yaml_content)
        
        logger.debug(f"Saved note {note.id} to {filename}")
        return filename
    
    def load_note(self, filename: str) -> Optional[Note]:
        """Load a note from a YAML file.
        
        Args:
            filename: Name of the YAML file (in base_dir)
            
        Returns:
            The loaded Note object, or None if file doesn't exist or is invalid
        """
        filepath = self.base_dir / filename
        
        if not filepath.exists():
            logger.warning(f"File not found: {filepath}")
            return None
        
        try:
            with open(filepath, 'r') as f:
                yaml_content = f.read()
            
            note = Note.from_yaml(yaml_content)
            logger.debug(f"Loaded note {note.id} from {filename}")
            return note
        except Exception as e:
            logger.error(f"Failed to load note from {filename}: {e}")
            return None
    
    def get_all_yaml_files(self) -> List[str]:
        """Get list of all YAML files in the base directory.
        
        Returns:
            List of YAML filenames (not including path)
        """
        if not self.base_dir.exists():
            return []
        
        yaml_files = [f.name for f in self.base_dir.glob('*.yaml') if f.is_file()]
        logger.debug(f"Found {len(yaml_files)} YAML files")
        return yaml_files
    
    def get_all_notes(self) -> List[Note]:
        """Load all notes from YAML files.
        
        Returns:
            List of loaded Note objects
        """
        yaml_files = self.get_all_yaml_files()
        notes = []
        
        for filename in yaml_files:
            note = self.load_note(filename)
            if note:
                notes.append(note)
        
        logger.info(f"Loaded {len(notes)} notes from {len(yaml_files)} files")
        return notes
    
    def note_file_exists(self, note_id: int) -> bool:
        """Check if a YAML file exists for a note ID.
        
        Args:
            note_id: The note ID to check
            
        Returns:
            True if a file matching this note ID exists
        """
        yaml_files = self.get_all_yaml_files()
        # Check if any file contains this note ID
        return any(f"_{note_id}.yaml" in f for f in yaml_files)
    
    def update_note_id_in_file(self, filename: str, new_id: int) -> bool:
        """Update the ID field in a YAML file after note creation.
        
        Args:
            filename: The YAML filename
            new_id: The new note ID to set
            
        Returns:
            True if successful, False otherwise
        """
        filepath = self.base_dir / filename
        
        if not filepath.exists():
            logger.warning(f"File not found: {filepath}")
            return False
        
        try:
            note = self.load_note(filename)
            if not note:
                return False
            
            note.id = new_id
            yaml_content = note.to_yaml()
            
            with open(filepath, 'w') as f:
                f.write(yaml_content)
            
            logger.debug(f"Updated note ID in {filename} to {new_id}")
            return True
        except Exception as e:
            logger.error(f"Failed to update note ID in {filename}: {e}")
            return False
