#!/usr/bin/env python3
"""
JSON文件存储实现
"""

import json
import os
import glob
from pathlib import Path
from typing import Any, List, Dict
from datetime import datetime

from .base import StorageInterface, StorageConfig, StorageException, StorageOperationError
from python_core.utils.logger import logger

class JSONStorage(StorageInterface):
    """JSON文件存储实现"""
    
    def __init__(self, config: StorageConfig):
        super().__init__(config)
        
        # 设置基础路径
        if config.base_path:
            self.base_path = Path(config.base_path)
        else:
            from python_core.config import settings
            self.base_path = settings.temp_dir / "storage"
        
        # 确保目录存在
        self.base_path.mkdir(parents=True, exist_ok=True)
        
        logger.info(f"JSON storage initialized at: {self.base_path}")
    
    def _get_collection_path(self, collection: str) -> Path:
        """获取集合目录路径"""
        return self.base_path / collection
    
    def _get_file_path(self, collection: str, key: str) -> Path:
        """获取文件路径"""
        collection_path = self._get_collection_path(collection)
        collection_path.mkdir(parents=True, exist_ok=True)
        return collection_path / f"{key}.json"
    
    def _ensure_serializable(self, data: Any) -> Any:
        """确保数据可序列化"""
        if hasattr(data, '__dict__'):
            # 处理dataclass或自定义对象
            if hasattr(data, '__dataclass_fields__'):
                from dataclasses import asdict
                return asdict(data)
            else:
                return data.__dict__
        elif isinstance(data, (list, tuple)):
            return [self._ensure_serializable(item) for item in data]
        elif isinstance(data, dict):
            return {k: self._ensure_serializable(v) for k, v in data.items()}
        else:
            return data
    
    def save(self, collection: str, key: str, data: Any) -> bool:
        """保存数据到JSON文件"""
        try:
            file_path = self._get_file_path(collection, key)
            
            # 准备保存的数据
            save_data = {
                "key": key,
                "data": self._ensure_serializable(data),
                "created_at": datetime.now().isoformat(),
                "updated_at": datetime.now().isoformat()
            }
            
            # 如果文件已存在，保留创建时间
            if file_path.exists():
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        existing_data = json.load(f)
                        save_data["created_at"] = existing_data.get("created_at", save_data["created_at"])
                except Exception:
                    pass  # 如果读取失败，使用新的创建时间
            
            # 保存文件
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(save_data, f, 
                         indent=self.config.json_indent,
                         ensure_ascii=self.config.json_ensure_ascii)
            
            logger.debug(f"Saved data to {file_path}")
            return True
            
        except Exception as e:
            logger.error(f"Failed to save data to {collection}/{key}: {e}")
            raise StorageOperationError(f"Failed to save data: {e}")
    
    def load(self, collection: str, key: str) -> Any:
        """从JSON文件加载数据"""
        try:
            file_path = self._get_file_path(collection, key)
            
            if not file_path.exists():
                return None
            
            with open(file_path, 'r', encoding='utf-8') as f:
                file_data = json.load(f)
                return file_data.get("data")
                
        except Exception as e:
            logger.error(f"Failed to load data from {collection}/{key}: {e}")
            raise StorageOperationError(f"Failed to load data: {e}")
    
    def delete(self, collection: str, key: str) -> bool:
        """删除JSON文件"""
        try:
            file_path = self._get_file_path(collection, key)
            
            if file_path.exists():
                file_path.unlink()
                logger.debug(f"Deleted file {file_path}")
                return True
            
            return False
            
        except Exception as e:
            logger.error(f"Failed to delete data from {collection}/{key}: {e}")
            raise StorageOperationError(f"Failed to delete data: {e}")
    
    def exists(self, collection: str, key: str) -> bool:
        """检查JSON文件是否存在"""
        file_path = self._get_file_path(collection, key)
        return file_path.exists()
    
    def list_keys(self, collection: str, pattern: str = "*") -> List[str]:
        """列出集合中的所有键"""
        try:
            collection_path = self._get_collection_path(collection)
            
            if not collection_path.exists():
                return []
            
            # 使用glob模式匹配
            if pattern == "*":
                pattern = "*.json"
            elif not pattern.endswith(".json"):
                pattern = f"{pattern}.json"
            
            files = glob.glob(str(collection_path / pattern))
            keys = [Path(f).stem for f in files]
            
            return sorted(keys)
            
        except Exception as e:
            logger.error(f"Failed to list keys in {collection}: {e}")
            raise StorageOperationError(f"Failed to list keys: {e}")
    
    def save_batch(self, collection: str, data: Dict[str, Any]) -> bool:
        """批量保存数据"""
        try:
            success_count = 0
            for key, value in data.items():
                if self.save(collection, key, value):
                    success_count += 1
            
            logger.info(f"Batch saved {success_count}/{len(data)} items to {collection}")
            return success_count == len(data)
            
        except Exception as e:
            logger.error(f"Failed to batch save data to {collection}: {e}")
            raise StorageOperationError(f"Failed to batch save data: {e}")
    
    def load_batch(self, collection: str, keys: List[str]) -> Dict[str, Any]:
        """批量加载数据"""
        try:
            result = {}
            for key in keys:
                data = self.load(collection, key)
                if data is not None:
                    result[key] = data
            
            logger.debug(f"Batch loaded {len(result)}/{len(keys)} items from {collection}")
            return result
            
        except Exception as e:
            logger.error(f"Failed to batch load data from {collection}: {e}")
            raise StorageOperationError(f"Failed to batch load data: {e}")
    
    def clear_collection(self, collection: str) -> bool:
        """清空集合（删除所有文件）"""
        try:
            collection_path = self._get_collection_path(collection)
            
            if not collection_path.exists():
                return True
            
            # 删除所有JSON文件
            json_files = list(collection_path.glob("*.json"))
            for file_path in json_files:
                file_path.unlink()
            
            logger.info(f"Cleared {len(json_files)} files from collection {collection}")
            return True
            
        except Exception as e:
            logger.error(f"Failed to clear collection {collection}: {e}")
            raise StorageOperationError(f"Failed to clear collection: {e}")
    
    def get_collections(self) -> List[str]:
        """获取所有集合名称"""
        try:
            if not self.base_path.exists():
                return []
            
            collections = []
            for item in self.base_path.iterdir():
                if item.is_dir():
                    collections.append(item.name)
            
            return sorted(collections)
            
        except Exception as e:
            logger.error(f"Failed to get collections: {e}")
            raise StorageOperationError(f"Failed to get collections: {e}")
    
    def get_stats(self, collection: str) -> Dict[str, Any]:
        """获取集合统计信息"""
        try:
            collection_path = self._get_collection_path(collection)
            
            if not collection_path.exists():
                return {
                    "collection": collection,
                    "exists": False,
                    "file_count": 0,
                    "total_size": 0
                }
            
            json_files = list(collection_path.glob("*.json"))
            total_size = sum(f.stat().st_size for f in json_files)
            
            # 获取最新和最旧的文件时间
            if json_files:
                file_times = [f.stat().st_mtime for f in json_files]
                oldest_file = min(file_times)
                newest_file = max(file_times)
            else:
                oldest_file = newest_file = None
            
            return {
                "collection": collection,
                "exists": True,
                "file_count": len(json_files),
                "total_size": total_size,
                "oldest_file": datetime.fromtimestamp(oldest_file).isoformat() if oldest_file else None,
                "newest_file": datetime.fromtimestamp(newest_file).isoformat() if newest_file else None,
                "path": str(collection_path)
            }
            
        except Exception as e:
            logger.error(f"Failed to get stats for collection {collection}: {e}")
            raise StorageOperationError(f"Failed to get stats: {e}")
    
    def close(self):
        """关闭存储连接（JSON存储无需特殊关闭操作）"""
        logger.debug("JSON storage closed")
