"""
Chart management utilities for qry-doc.

This module provides functionality to manage temporary chart files
generated by PandasAI/Matplotlib during report generation.
"""
import os
import shutil
import tempfile
from pathlib import Path
from typing import Optional
from datetime import datetime


class ChartManager:
    """
    Manages temporary storage for chart files.
    
    Features:
    - Creates a secure temporary directory for chart storage
    - Retrieves the most recently created chart
    - Cleans up all temporary files on exit
    - Supports context manager protocol for automatic cleanup
    """
    
    # Supported chart file extensions
    CHART_EXTENSIONS = {".png", ".jpg", ".jpeg", ".svg", ".pdf"}
    
    def __init__(self) -> None:
        """
        Initialize the ChartManager with a new temporary directory.
        """
        self._temp_dir: Optional[tempfile.TemporaryDirectory] = None
        self._path: Optional[Path] = None
        self._create_temp_dir()
    
    def _create_temp_dir(self) -> None:
        """Create the temporary directory for chart storage."""
        self._temp_dir = tempfile.TemporaryDirectory(prefix="qry_doc_charts_")
        self._path = Path(self._temp_dir.name)
    
    @property
    def path(self) -> Path:
        """
        Get the path to the temporary chart directory.
        
        Returns:
            Path to the temporary directory.
            
        Raises:
            RuntimeError: If the manager has been cleaned up.
        """
        if self._path is None:
            raise RuntimeError("ChartManager has been cleaned up")
        return self._path
    
    def get_latest_chart(self) -> Optional[Path]:
        """
        Get the path to the most recently created chart file.
        
        Returns:
            Path to the latest chart file, or None if no charts exist.
        """
        if self._path is None:
            return None
        
        charts = self._list_charts()
        if not charts:
            return None
        
        # Sort by modification time, most recent first
        charts.sort(key=lambda p: p.stat().st_mtime, reverse=True)
        return charts[0]
    
    def get_all_charts(self) -> list[Path]:
        """
        Get all chart files in the temporary directory.
        
        Returns:
            List of paths to all chart files, sorted by modification time.
        """
        if self._path is None:
            return []
        
        charts = self._list_charts()
        charts.sort(key=lambda p: p.stat().st_mtime, reverse=True)
        return charts
    
    def _list_charts(self) -> list[Path]:
        """List all chart files in the temporary directory."""
        if self._path is None or not self._path.exists():
            return []
        
        charts = []
        for file in self._path.iterdir():
            if file.is_file() and file.suffix.lower() in self.CHART_EXTENSIONS:
                charts.append(file)
        return charts
    
    def cleanup(self) -> None:
        """
        Remove all temporary files and the temporary directory.
        
        Safe to call multiple times.
        """
        if self._temp_dir is not None:
            try:
                self._temp_dir.cleanup()
            except Exception:
                # Ignore cleanup errors (directory might already be gone)
                pass
            self._temp_dir = None
            self._path = None
    
    def clear_charts(self) -> int:
        """
        Remove all chart files but keep the temporary directory.
        
        Returns:
            Number of files removed.
        """
        if self._path is None:
            return 0
        
        count = 0
        for chart in self._list_charts():
            try:
                chart.unlink()
                count += 1
            except OSError:
                pass
        return count
    
    def file_count(self) -> int:
        """
        Get the number of files in the temporary directory.
        
        Returns:
            Number of files (including non-chart files).
        """
        if self._path is None or not self._path.exists():
            return 0
        
        return sum(1 for f in self._path.iterdir() if f.is_file())
    
    def __enter__(self) -> "ChartManager":
        """Enter context manager."""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """Exit context manager, cleaning up temporary files."""
        self.cleanup()
    
    def __del__(self) -> None:
        """Destructor - ensure cleanup on garbage collection."""
        self.cleanup()
