import os
import sys
from pathlib import Path
import subprocess
from datetime import datetime, timedelta
import shutil
from dotenv import load_dotenv
import asyncio
from aiogram import Bot
from aiogram.types import FSInputFile

# Add the parent directory to sys.path
sys.path.append(str(Path(__file__).parent.parent))

# Load environment variables
load_dotenv()

# MySQL connection settings
MYSQL_USER = os.getenv("MYSQL_USER", "bot")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "secret")
MYSQL_HOST = os.getenv("MYSQL_HOST", "localhost")
MYSQL_PORT = os.getenv("MYSQL_PORT", "3306")
MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", "vpn_shop")

# Telegram settings
BOT_TOKEN = os.getenv("BOT_TOKEN")
ADMIN_IDS = os.getenv("ADMIN_IDS", "0")

# Backup settings
BACKUP_DIR = Path("backups")
BACKUP_KEEP_DAYS = 7  # Number of days to keep backups

def create_backup_dir():
    """Create backup directory if it doesn't exist"""
    BACKUP_DIR.mkdir(exist_ok=True)

async def send_backup_to_admin(backup_file: Path, bot: Bot):
    """Send backup file to admin"""
    try:
        if not backup_file.exists():
            print(f"Backup file not found: {backup_file}")
            return False
        admin_ids = ADMIN_IDS.split(",")
        for admin_id in admin_ids:
            print(f"Sending backup to admin (ID: {admin_id})...")
            
            # Create FSInputFile from the backup file
            file = FSInputFile(backup_file)
            
            # Send file to admin
            await bot.send_document(
                chat_id=admin_id,
                document=file,
                caption=f"Database backup {backup_file.name}\nSize: {backup_file.stat().st_size / (1024*1024):.2f} MB"
            )
        
        print("Backup sent successfully!")
        return True
        
    except Exception as e:
        print(f"Error sending backup to admin: {e}")
        return False

def cleanup_old_backups():
    """Remove backups older than BACKUP_KEEP_DAYS"""
    now = datetime.now()
    print("Cleaning up old backups...")
    
    for backup_file in BACKUP_DIR.glob("*.sql"):
        try:
            backup_file.unlink()
            print(f"Removed backup file: {backup_file}")
        except Exception as e:
            print(f"Error removing backup file {backup_file}: {e}")

async def create_backup(bot: Bot = None):
    """Create a backup of the MySQL database and send to admin"""
    try:
        # Create backup directory
        create_backup_dir()
        
        # Generate backup filename with timestamp
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_file = BACKUP_DIR / f"{MYSQL_DATABASE}_{timestamp}.sql"
        
        print(f"Creating backup: {backup_file}")
        
        # Construct mysqldump command
        command = [
            "mysqldump",
            f"--host={MYSQL_HOST}",
            f"--port={MYSQL_PORT}",
            f"--user={MYSQL_USER}",
            f"--password={MYSQL_PASSWORD}",
            "--single-transaction",  # Consistent backup without locking tables
            "--routines",  # Include stored procedures and functions
            "--triggers",  # Include triggers
            "--add-drop-table",  # Add DROP TABLE statements
            MYSQL_DATABASE
        ]
        
        # Execute mysqldump and save output to file
        with open(backup_file, 'w') as f:
            subprocess.run(command, stdout=f, check=True)
            
        print("Backup created successfully!")
        
        # If bot instance is provided, send backup to admin
        if bot and ADMIN_IDS:
            if await send_backup_to_admin(backup_file, bot):
                print("Backup sent to admin successfully!")
            else:
                print("Failed to send backup to admin!")
        
        # Cleanup all backups after sending
        cleanup_old_backups()
        
        return True
        
    except subprocess.CalledProcessError as e:
        print(f"Error creating backup: {e}")
        return False
    except Exception as e:
        print(f"Unexpected error during backup: {e}")
        return False

if __name__ == "__main__":
    bot = Bot(token=BOT_TOKEN)
    asyncio.run(create_backup(bot))
    asyncio.run(bot.session.close()) 