import logging
import requests
from datetime import datetime, timedelta
from asgiref.sync import sync_to_async
from pms_integration.models import PMSConfiguration
from hotels.models import Hotel, Reservation
from .base_plugin import BasePMSPlugin


class EcviPMSPlugin(BasePMSPlugin):
    """
    Плагин для интеграции с PMS Ecvi (интерфейс для получения данных об отеле).
    """

    def __init__(self, pms_config):
        super().__init__(pms_config)
        
        # Инициализация логгера
        self.logger = logging.getLogger(self.__class__.__name__)  # Логгер с именем класса
        handler = logging.StreamHandler()  # Потоковый обработчик для вывода в консоль
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.logger.setLevel(logging.DEBUG)  # Уровень логирования

        # Инициализация параметров API
        self.api_url = pms_config.url
        self.token = pms_config.token
        self.username = pms_config.username
        self.password = pms_config.password
        self.pagination_count = 50  # Максимальное количество записей на страницу (если используется пагинация)

    def get_default_parser_settings(self):
        """
        Возвращает настройки парсера по умолчанию.
        """
        return {
            "field_mapping": {
                "check_in": "checkin",
                "check_out": "checkout",
                "room_number": "room_name",  
                "room_type_name": "room_type",
                "status": "occupancy",
            },
            "date_format": "%Y-%m-%dT%H:%M:%S"
        }

    async def _fetch_data(self):
        """
        Получает данные из PMS API, фильтрует и сохраняет в базу данных.
        """
        now = datetime.now()
        current_date = now.strftime('%Y-%m-%d')
        yesterday_date = (now - timedelta(days=1)).strftime('%Y-%m-%d')

        headers = {
            "Content-Type": "application/json",
        }
        data = {
            "token": self.token,
        }

        try:
            # Запрос данных из PMS API
            response = await sync_to_async(requests.post)(self.api_url, headers=headers, json=data, auth=(self.username, self.password))
            response.raise_for_status()  # Если ошибка, выбросит исключение
            data = response.json()  # Преобразуем ответ в JSON
            self.logger.debug(f"Получены данные с API: {data}")
        except requests.exceptions.RequestException as e:
            self.logger.error(f"Ошибка запроса: {e}")
            return []

        # Фильтрация данных
        filtered_data = []
        for item in data:
            if item.get('occupancy') in ['проживание', 'под выезд', 'под заезд']:
                filtered_item = {
                    'checkin': datetime.strptime(item.get('checkin'), '%Y-%m-%d %H:%M:%S'),
                    'checkout': datetime.strptime(item.get('checkout'), '%Y-%m-%d %H:%M:%S'),
                    'room_number': item.get('room_name'),
                    'room_type': item.get('room_type'),
                    'status': item.get('occupancy')
                }
                filtered_data.append(filtered_item)

        # Логируем результат фильтрации
        self.logger.debug(f"Отфильтрованные данные: {filtered_data}")

        # Сохранение данных в базу данных
        for item in filtered_data:
            await self._save_to_db(item)

        self.logger.debug(f"Данные успешно сохранены.")
        return filtered_data

    async def _save_to_db(self, item):
        """
        Сохраняет данные в БД (например, информацию о номере).
        """
        try:
            # Проверяем, что item — это словарь
            if not isinstance(item, dict):
                self.logger.error(f"Ожидался словарь, но получен: {type(item)}. Данные: {item}")
                return

            # Получаем отель по настройкам PMS
            hotel = await sync_to_async(Hotel.objects.get)(pms=self.pms_config)
            self.logger.debug(f"Отель найден: {hotel.name}")

            # Сохраняем данные бронирования
            room_number = item.get("room_number")
            check_in = item.get("checkin")
            check_out = item.get("checkout")
            room_type = item.get("room_type")

            # Логируем полученные данные
            self.logger.debug(f"Полученные данные для сохранения: room_number={room_number}, check_in={check_in}, check_out={check_out}, room_type={room_type}")

            # Проверяем, существует ли запись с таким номером и датой заезда
            existing_reservation = await sync_to_async(
                Reservation.objects.filter(room_number=room_number, check_in=check_in).first
            )()

            if existing_reservation:
                self.logger.debug(f"Резервация с таким номером и датой заезда уже существует. Обновляем...")
                await sync_to_async(Reservation.objects.update_or_create)(
                    room_number=room_number,
                    check_in=check_in,
                    defaults={
                        "check_out": check_out,
                        "hotel": hotel,
                        "room_type": room_type,
                    },
                )
                self.logger.debug(f"Обновлена существующая резервация.")
            else:
                self.logger.debug(f"Резервация не найдена, создаем новую...")
                reservation = await sync_to_async(Reservation.objects.create)(
                    room_number=room_number,
                    check_in=check_in,
                    check_out=check_out,
                    hotel=hotel,
                    room_type=room_type,
                )
                self.logger.debug(f"Создана новая резервация. ID: {reservation.reservation_id}")

        except Exception as e:
            self.logger.error(f"Ошибка сохранения данных: {e}")

