import os
import json
import atexit
import signal
import logging
from typing import Dict
from aiogram.types import FSInputFile, Message

logger = logging.getLogger(__name__)

# File ID cache
_file_id_cache: Dict[str, str] = {}
_CACHE_FILE = "media_cache.json"
_cache_modified = False

# Load existing file_id cache if available
def load_file_id_cache():
    """Load file_id cache from disk if available"""
    global _file_id_cache
    try:
        if os.path.exists(_CACHE_FILE):
            with open(_CACHE_FILE, 'r', encoding='utf-8') as f:
                _file_id_cache = json.load(f)
            logger.info(f"Loaded {len(_file_id_cache)} cached file_ids")
    except Exception as e:
        logger.error(f"Error loading file_id cache: {e}")
        _file_id_cache = {}

# Save file_id cache to disk
def save_file_id_cache():
    """Save file_id cache to disk if modified"""
    global _cache_modified
    if not _cache_modified:
        return
        
    try:
        with open(_CACHE_FILE, 'w', encoding='utf-8') as f:
            json.dump(_file_id_cache, f)
        logger.info(f"Saved {len(_file_id_cache)} file_ids to cache")
        _cache_modified = False
    except Exception as e:
        logger.error(f"Error saving file_id cache: {e}")

# Function to handle shutdown signals
def handle_shutdown(signum, frame):
    """Handle shutdown signals to save cache before exit"""
    logger.info("Received shutdown signal, saving media cache...")
    save_file_id_cache()

# Register signal handlers for graceful shutdown
signal.signal(signal.SIGINT, handle_shutdown)  # Ctrl+C
signal.signal(signal.SIGTERM, handle_shutdown)  # Termination signal

# Register save_file_id_cache to run on exit
atexit.register(save_file_id_cache)

# Load cache on module import
load_file_id_cache()

def get_cached_media(path: str):
    """Get media file - if exist file return either cached file_id or FSInputFile, else return None"""
    if path in _file_id_cache:
        return _file_id_cache[path]
    # Check if file exists
    if os.path.exists(path):
        return FSInputFile(path)
    return None

# Function to update file_id cache after sending
def update_file_id_cache(path: str, message: Message):
    """Store file_id after sending a photo, but only if it's different"""
    global _cache_modified
    
    if hasattr(message, 'photo') and message.photo:
        file_id = message.photo[-1].file_id
        
        # Only update if the file_id is different
        if path not in _file_id_cache or _file_id_cache[path] != file_id:
            _file_id_cache[path] = file_id
            _cache_modified = True
            logger.debug(f"Updated file_id for {path}")

# Function to manually save cache (can be called when bot stops)
def save_media_cache():
    """Manually save media cache - can be called when bot is shutting down"""
    logger.info("Manually saving media cache...")
    save_file_id_cache() 