import requests
import json
from datetime import datetime, timedelta
from .base_plugin import BasePMSPlugin
from asgiref.sync import sync_to_async
from pms_integration.models import PMSConfiguration


class BnovoPMSPlugin(BasePMSPlugin):
    """Плагин для работы с PMS Bnovo."""

    def __init__(self, config):
        super().__init__(config)
        self.api_url = config.url.rstrip("/")  # Убираем лишний `/` в конце URL
        self.username = config.username
        self.password = config.password
        self.token = None  # SID

        if not self.api_url:
            raise ValueError("Не указан URL для работы плагина.")
        if not self.username or not self.password:
            raise ValueError("Не указаны логин или пароль для авторизации.")

    def get_default_parser_settings(self):
        """Возвращает настройки по умолчанию для обработки данных."""
        return {
            "date_format": "%Y-%m-%dT%H:%M:%S",
            "timezone": "UTC"
        }

    async def _save_token_to_db(self, sid):
        """Сохраняет токен (SID) в базу данных."""
        try:
            await sync_to_async(PMSConfiguration.objects.update_or_create)(
                plugin_name="bnovo",
                defaults={"token": sid}
            )
            print(f"[DEBUG] Токен сохранен в БД: {sid}")
        except Exception as e:
            print(f"[ERROR] Ошибка сохранения токена в БД: {e}")

    def _get_auth_headers(self):
        """Создает заголовки авторизации."""
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json",
        }
        if self.token:
            headers["Cookie"] = f"SID={self.token}"
        return headers

    async def _fetch_session(self):
        """Получает идентификатор сессии (SID) через запрос."""
        url = f"{self.api_url}/"
        payload = {
            "username": self.username,
            "password": self.password,
        }

        print(f"[DEBUG] URL авторизации: {url}")
        print(f"[DEBUG] Тело запроса: {json.dumps(payload, indent=2)}")
        headers = self._get_auth_headers()

        session = requests.Session()
        response = session.post(url, json=payload, headers=headers, allow_redirects=False)

        print(f"[DEBUG] Статус ответа: {response.status_code}")
        print(f"[DEBUG] Ответ заголовков: {response.headers}")
        print(f"[DEBUG] Cookies: {session.cookies}")

        if response.status_code == 302 and "SID" in session.cookies:
            sid = session.cookies.get("SID")
            self.token = sid
            print(f"[DEBUG] Получен SID: {sid}")

            # Правильное сохранение в БД через sync_to_async
            try:
                await self._save_token_to_db(sid)
                print(f"[DEBUG] Токен сохранен в БД")
            except Exception as e:
                print(f"[ERROR] Ошибка сохранения токена в БД: {e}")
        else:
            raise ValueError(f"Не удалось получить SID из ответа: {response.text}")

    async def _fetch_data(self):
        """Получает данные о бронированиях с помощью эндпоинта `/dashboard`."""
        await self._fetch_session()  # Авторизуемся перед каждым запросом

        now = datetime.now()
        create_from = (now - timedelta(days=90)).strftime("%d.%m.%Y")  # Диапазон: последние 90 дней
        create_to = now.strftime("%d.%m.%Y")

        params = {
            "create_from": create_from,
            "create_to": create_to,
            "status_ids": "1",
            "advanced_search": 2,  # Обязательный параметр
            "c": 100,  # Количество элементов на странице (максимум 100)
            "page": 1,  # Начальная страница
            "order_by": "create_date.asc",  # Сортировка по возрастанию даты создания
        }

        headers = self._get_auth_headers()

        all_bookings = []  # Для сохранения всех бронирований
        while True:
            print(f"[DEBUG] Запрос к /dashboard с параметрами: {json.dumps(params, indent=2)}")
            response = requests.get(f"{self.api_url}/dashboard", headers=headers, params=params)

            print(f"[DEBUG] Статус ответа: {response.status_code}")
            if response.status_code != 200:
                raise ValueError(f"Ошибка при получении данных: {response.status_code}, {response.text}")

            data = response.json()
            print(json.dumps(data, indent=2))
            bookings = data.get("bookings", [])
            all_bookings.extend(bookings)

            print(f"[DEBUG] Получено бронирований: {len(bookings)}")
            print(f"[DEBUG] Всего бронирований: {len(all_bookings)}")

            # Проверка на наличие следующей страницы
            pages_info = data.get("pages", {})
            current_page = pages_info.get("current_page", 1)
            total_pages = pages_info.get("total_pages", 1)

            if current_page >= total_pages:
                break  # Все страницы загружены

            params["page"] += 1  # Переход на следующую страницу

            if not all_bookings:
                print("[DEBUG] Нет бронирований за указанный период.")
        else:
            print(f"[DEBUG] Полученные бронирования: {json.dumps(all_bookings, indent=2)}")
        return all_bookings