import os
import subprocess
from datetime import datetime

from aiogram.types import BufferedInputFile

from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER
from logger import logger


async def backup_database():
    from bot import bot

    try:
        if backup_file_path := _create_database_backup():
            await _send_backup_to_admin(bot, backup_file_path)
            _cleanup_old_backups()
    except Exception as e:
        logger.error(f"Ошибка при создании или отправке бэкапа: {e}")


def _create_database_backup():
    USER = DB_USER
    HOST = "localhost"
    BACKUP_DIR = BACK_DIR
    DATE = datetime.now().strftime("%Y-%m-%d-%H%M%S")
    BACKUP_FILE = f"{BACKUP_DIR}/{DB_NAME}-backup-{DATE}.sql"

    os.environ["PGPASSWORD"] = DB_PASSWORD

    try:
        subprocess.run(
            [
                "pg_dump",
                "-U",
                USER,
                "-h",
                HOST,
                "-F",
                "c",
                "-f",
                BACKUP_FILE,
                DB_NAME,
            ],
            check=True,
        )
        logger.info(f"Бэкап базы данных создан: {BACKUP_FILE}")
        return BACKUP_FILE
    except subprocess.CalledProcessError as e:
        logger.error(f"Ошибка при создании бэкапа базы данных: {e}")
        return None
    finally:
        del os.environ["PGPASSWORD"]


async def _send_backup_to_admin(bot, backup_file_path):
    try:
        with open(backup_file_path, "rb") as backup_file:
            backup_input_file = BufferedInputFile(
                backup_file.read(), filename=os.path.basename(backup_file_path)
            )
            admin_ids: int | list[int] = ADMIN_ID
            if isinstance(admin_ids, list):
                for id in admin_ids:
                    await bot.send_document(id, backup_input_file)
                    logger.info(f"Бэкап базы данных отправлен админу: {id}")
            else:
                await bot.send_document(admin_ids, backup_input_file)
                logger.info(f"Бэкап базы данных отправлен админу: {ADMIN_ID}")
    except Exception as e:
        logger.error(f"Ошибка при отправке бэкапа в Telegram: {e}")


def _cleanup_old_backups():
    try:
        subprocess.run(
            [
                "find",
                BACK_DIR,
                "-type",
                "f",
                "-name",
                "*.sql",
                "-mtime",
                "+3",
                "-exec",
                "rm",
                "{}",
                ";",
            ],
            check=True,
        )
        logger.info("Старые бэкапы удалены.")
    except subprocess.CalledProcessError as e:
        logger.error(f"Ошибка при удалении старых бэкапов: {e}")


async def create_backup_and_send_to_admins(xui):
    await xui.login()
    await xui.database.export()
