"""本地缓存管理模块"""
import json
import logging
import os
import sqlite3
import threading
import time
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional

from .config import LogConfig

logger = logging.getLogger(__name__)


class CacheManager:
    """本地缓存管理器
    
    使用 SQLite 实现本地日志缓存，在网络故障时提供兜底
    """
    
    def __init__(self, config: LogConfig):
        """初始化缓存管理器
        
        Args:
            config: 日志配置
        """
        self.config = config
        self.db_path = config.cache_db_path
        self.lock = threading.Lock()
        
        # 初始化数据库
        self._init_database()
        
        # 清理过期数据
        self._cleanup_old_data()
        
        logger.info(f"缓存管理器已初始化，数据库路径: {self.db_path}")
    
    def _init_database(self):
        """初始化数据库表"""
        with sqlite3.connect(self.db_path) as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS log_cache (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT NOT NULL,
                    level TEXT NOT NULL,
                    message TEXT NOT NULL,
                    metadata TEXT,
                    retry_count INTEGER DEFAULT 0,
                    created_at TEXT DEFAULT CURRENT_TIMESTAMP
                )
            """)
            
            # 创建索引
            conn.execute("""
                CREATE INDEX IF NOT EXISTS idx_created_at 
                ON log_cache(created_at)
            """)
            
            conn.commit()
    
    def save_to_cache(self, log_entry: Dict[str, Any]) -> bool:
        """保存日志到本地缓存
        
        Args:
            log_entry: 日志条目
            
        Returns:
            是否保存成功
        """
        try:
            with self.lock:
                # 检查缓存大小
                if self._get_cache_size_mb() >= self.config.cache_max_size_mb:
                    logger.warning("缓存已达到最大大小，跳过保存")
                    return False
                
                with sqlite3.connect(self.db_path) as conn:
                    metadata_json = json.dumps(log_entry.get("metadata", {}))
                    
                    conn.execute("""
                        INSERT INTO log_cache 
                        (timestamp, level, message, metadata, retry_count)
                        VALUES (?, ?, ?, ?, ?)
                    """, (
                        log_entry.get("timestamp"),
                        log_entry.get("level"),
                        log_entry.get("message"),
                        metadata_json,
                        0
                    ))
                    
                    conn.commit()
            
            return True
        
        except Exception as e:
            logger.error(f"保存到缓存失败: {e}", exc_info=True)
            return False
    
    def get_cached_logs(self, limit: int = 100) -> List[Dict[str, Any]]:
        """获取缓存的日志
        
        Args:
            limit: 最大返回数量
            
        Returns:
            日志列表
        """
        try:
            with self.lock:
                with sqlite3.connect(self.db_path) as conn:
                    conn.row_factory = sqlite3.Row
                    cursor = conn.execute("""
                        SELECT id, timestamp, level, message, metadata, retry_count
                        FROM log_cache
                        WHERE retry_count < ?
                        ORDER BY id ASC
                        LIMIT ?
                    """, (self.config.max_retries, limit))
                    
                    logs = []
                    for row in cursor:
                        log_entry = {
                            "id": row["id"],
                            "timestamp": row["timestamp"],
                            "level": row["level"],
                            "message": row["message"],
                            "metadata": json.loads(row["metadata"]) if row["metadata"] else {},
                            "retry_count": row["retry_count"]
                        }
                        logs.append(log_entry)
                    
                    return logs
        
        except Exception as e:
            logger.error(f"获取缓存日志失败: {e}", exc_info=True)
            return []
    
    def delete_cached_logs(self, log_ids: List[int]) -> bool:
        """删除已成功发送的缓存日志
        
        Args:
            log_ids: 日志 ID 列表
            
        Returns:
            是否删除成功
        """
        if not log_ids:
            return True
        
        try:
            with self.lock:
                with sqlite3.connect(self.db_path) as conn:
                    placeholders = ",".join("?" * len(log_ids))
                    conn.execute(f"""
                        DELETE FROM log_cache
                        WHERE id IN ({placeholders})
                    """, log_ids)
                    
                    conn.commit()
            
            return True
        
        except Exception as e:
            logger.error(f"删除缓存日志失败: {e}", exc_info=True)
            return False
    
    def increment_retry_count(self, log_ids: List[int]) -> bool:
        """增加重试次数
        
        Args:
            log_ids: 日志 ID 列表
            
        Returns:
            是否更新成功
        """
        if not log_ids:
            return True
        
        try:
            with self.lock:
                with sqlite3.connect(self.db_path) as conn:
                    placeholders = ",".join("?" * len(log_ids))
                    conn.execute(f"""
                        UPDATE log_cache
                        SET retry_count = retry_count + 1
                        WHERE id IN ({placeholders})
                    """, log_ids)
                    
                    conn.commit()
            
            return True
        
        except Exception as e:
            logger.error(f"更新重试次数失败: {e}", exc_info=True)
            return False
    
    def _cleanup_old_data(self):
        """清理过期数据"""
        try:
            cutoff_date = datetime.now() - timedelta(days=self.config.cache_retention_days)
            cutoff_str = cutoff_date.strftime("%Y-%m-%d %H:%M:%S")
            
            with self.lock:
                with sqlite3.connect(self.db_path) as conn:
                    cursor = conn.execute("""
                        DELETE FROM log_cache
                        WHERE created_at < ?
                    """, (cutoff_str,))
                    
                    deleted = cursor.rowcount
                    conn.commit()
            
            if deleted > 0:
                logger.info(f"清理了 {deleted} 条过期日志")
        
        except Exception as e:
            logger.error(f"清理过期数据失败: {e}", exc_info=True)
    
    def _get_cache_size_mb(self) -> float:
        """获取缓存文件大小（MB）
        
        Returns:
            文件大小（MB）
        """
        try:
            if os.path.exists(self.db_path):
                size_bytes = os.path.getsize(self.db_path)
                return size_bytes / (1024 * 1024)
            return 0.0
        except Exception:
            return 0.0
    
    def get_stats(self) -> Dict[str, Any]:
        """获取缓存统计信息
        
        Returns:
            统计信息字典
        """
        try:
            with self.lock:
                with sqlite3.connect(self.db_path) as conn:
                    cursor = conn.execute("SELECT COUNT(*) FROM log_cache")
                    total_count = cursor.fetchone()[0]
                    
                    cursor = conn.execute("""
                        SELECT COUNT(*) FROM log_cache
                        WHERE retry_count >= ?
                    """, (self.config.max_retries,))
                    failed_count = cursor.fetchone()[0]
            
            return {
                "total_cached": total_count,
                "failed_logs": failed_count,
                "cache_size_mb": round(self._get_cache_size_mb(), 2),
                "db_path": self.db_path
            }
        
        except Exception as e:
            logger.error(f"获取统计信息失败: {e}", exc_info=True)
            return {}
