# app/heartbeat_monitor.py
import threading
import time
import requests
import datetime
import logging
# import traceback

# Настройка логирования для HeartbeatMonitor
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Добавляем обработчик, если его еще нет (чтобы логи выводились в консоль)
if not logger.handlers:
    handler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)

class HeartbeatMonitor:
    """
    Мониторит доступность заданных внешних эндпоинтов путем периодических HTTP-запросов.
    Работает в отдельном фоновом потоке, логируя результаты.
    """

    def __init__(self, interval_minutes: int = 5):
        self._interval_seconds = interval_minutes * 60
        self._target_urls = [
            "https://render-service-gsu7.onrender.com/heartbeat",
            # Добавьте сюда другие URL для мониторинга, если они появятся
        ]
        self._running = False
        self._thread = None
        self._last_check_results = {}
        logger.info(f"HeartbeatMonitor инициализирован с интервалом {interval_minutes} минут.")
        logger.info(f"Мониторинг URL: {', '.join(self._target_urls)}")

        # Вывод call stack
        # stack_trace = "".join(traceback.format_stack())
        # logger.info(f"Call stack при инициализации HeartbeatMonitor:\n{stack_trace}")

    def _run_heartbeat_loop(self):
        """
        Основной цикл мониторинга, выполняющийся в отдельном потоке.
        """
        while self._running:
            logger.info("Начинается выполнение Heartbeat-проверок...")
            current_results = {}
            overall_healthy = True

            for url in self._target_urls:
                start_time = time.time()
                try:
                    response = requests.get(url, timeout=10) # Таймаут 10 секунд
                    if 200 <= response.status_code < 300:
                        status = {"healthy": True, "status_code": response.status_code, "message": "OK"}
                        logger.info(f"✅ Heartbeat {url}: OK (HTTP {response.status_code})")
                    else:
                        status = {"healthy": False, "status_code": response.status_code, "message": f"Non-2xx status code"}
                        logger.warning(f"⚠️ Heartbeat {url}: Ошибка (HTTP {response.status_code})")
                        overall_healthy = False
                except requests.exceptions.RequestException as e:
                    status = {"healthy": False, "status_code": None, "message": f"Request failed: {e}"}
                    logger.error(f"❌ Heartbeat {url}: Ошибка запроса: {e}")
                    overall_healthy = False
                except Exception as e:
                    status = {"healthy": False, "status_code": None, "message": f"Unexpected error: {e}"}
                    logger.critical(f"🔥 Heartbeat {url}: Неожиданная ошибка: {e}")
                    overall_healthy = False
                finally:
                    status["timestamp"] = datetime.datetime.now().isoformat()
                    status["response_time_ms"] = int((time.time() - start_time) * 1000)
                    current_results[url] = status
            
            self._last_check_results = current_results
            if overall_healthy:
                logger.info("✔ Все Heartbeat-проверки успешно пройдены.")
            else:
                logger.warning("✖ Обнаружены проблемы в Heartbeat-проверках.")

            time.sleep(self._interval_seconds)

    def start(self):
        """
        Запускает мониторинг в отдельном потоке.
        """
        if not self._running:
            self._running = True
            # daemon=True позволяет приложению завершиться, даже если этот поток еще работает.
            # Python автоматически завершит daemon-потоки при выходе из основной программы.
            self._thread = threading.Thread(target=self._run_heartbeat_loop, daemon=True)
            self._thread.start()
            logger.info("HeartbeatMonitor запущен.")
        else:
            logger.warning("HeartbeatMonitor уже запущен.")

    def stop(self):
        """
        Останавливает поток мониторинга.
        """
        if self._running:
            logger.info("Остановка HeartbeatMonitor...")
            self._running = False
            if self._thread and self._thread.is_alive():
                self._thread.join(timeout=5) # Даем потоку 5 секунд на завершение
                if self._thread.is_alive():
                    logger.warning("HeartbeatMonitor поток не завершился в течение таймаута.")
            logger.info("HeartbeatMonitor остановлен.")
        else:
            logger.warning("HeartbeatMonitor не был запущен.")

    def get_last_check_results(self):
        """
        Возвращает результаты последней проверки (для возможного использования внутри приложения).
        """
        return self._last_check_results
