"""Parquet cache handler."""

from pathlib import Path
from typing import Optional
import pandas as pd

from kline_package.cache.base import BaseCache


class ParquetCache(BaseCache):
    """
    Cache handler for Parquet format.
    
    Parquet is a columnar storage format that provides:
    - Efficient compression
    - Fast read/write operations
    - Smaller file sizes compared to CSV
    """
    
    def __init__(self, cache_dir: str = "./cache"):
        """
        Initialize the Parquet cache handler.
        
        Args:
            cache_dir: Directory where cache files will be stored
        """
        super().__init__(cache_dir)
        self.extension = ".parquet"
    
    def save(
        self,
        data: pd.DataFrame,
        filename: str,
        compression: str = "snappy"
    ) -> None:
        """
        Save DataFrame to Parquet file.
        
        Args:
            data: The DataFrame to save
            filename: The name of the file (without extension)
            compression: Compression algorithm ('snappy', 'gzip', 'brotli', 'none')
            
        Raises:
            ValueError: If data is empty or invalid
            IOError: If file cannot be written
        """
        if data is None or data.empty:
            raise ValueError("Cannot save empty DataFrame")
        
        file_path = self._get_file_path(filename)
        
        try:
            data.to_parquet(
                file_path,
                compression=compression,
                index=True,
                engine='pyarrow'
            )
        except Exception as e:
            raise IOError(f"Failed to save Parquet file: {e}")
    
    def load(self, filename: str) -> pd.DataFrame:
        """
        Load DataFrame from Parquet file.
        
        Args:
            filename: The name of the file to load (without extension)
            
        Returns:
            pd.DataFrame: The loaded DataFrame
            
        Raises:
            FileNotFoundError: If file doesn't exist
            IOError: If file cannot be read
        """
        file_path = self._get_file_path(filename)
        
        if not file_path.exists():
            raise FileNotFoundError(f"Parquet file not found: {file_path}")
        
        try:
            return pd.read_parquet(file_path, engine='pyarrow')
        except Exception as e:
            raise IOError(f"Failed to load Parquet file: {e}")
    
    def exists(self, filename: str) -> bool:
        """
        Check if a Parquet cache file exists.
        
        Args:
            filename: The name of the file to check (without extension)
            
        Returns:
            bool: True if file exists, False otherwise
        """
        file_path = self._get_file_path(filename)
        return file_path.exists()
    
    def delete(self, filename: str) -> None:
        """
        Delete a Parquet cache file.
        
        Args:
            filename: The name of the file to delete (without extension)
        """
        file_path = self._get_file_path(filename)
        if file_path.exists():
            file_path.unlink()
    
    def list_files(self) -> list:
        """
        List all Parquet cache files.
        
        Returns:
            list: List of cache file names (without extensions)
        """
        parquet_files = list(self.cache_dir.glob(f"*{self.extension}"))
        return [f.stem for f in parquet_files]
    
    def _get_file_path(self, filename: str) -> Path:
        """Get full file path with extension."""
        if not filename.endswith(self.extension):
            filename = f"{filename}{self.extension}"
        return self.cache_dir / filename
