from django.db import models
from hotels.models import Hotel
from hotels.models import Reservation


class UserActivityLog(models.Model):
    external_id = models.CharField(max_length=255, null=True, blank=True)
    user_id = models.BigIntegerField(verbose_name="ID пользователя")
    ip = models.GenericIPAddressField(verbose_name="IP-адрес")
    created = models.DateTimeField(verbose_name="Дата создания")
    timestamp = models.BigIntegerField(verbose_name="Метка времени")
    date_time = models.DateTimeField(verbose_name="Дата и время")
    referred = models.TextField(blank=True, null=True, verbose_name="Реферальная ссылка")
    agent = models.TextField(verbose_name="Агент пользователя")
    platform = models.CharField(max_length=255, blank=True, null=True, verbose_name="Платформа")
    version = models.CharField(max_length=255, blank=True, null=True, verbose_name="Версия")
    model = models.CharField(max_length=255, blank=True, null=True, verbose_name="Модель устройства")
    device = models.CharField(max_length=255, blank=True, null=True, verbose_name="Тип устройства")
    UAString = models.TextField(verbose_name="User-Agent строка")
    location = models.CharField(max_length=255, blank=True, null=True, verbose_name="Местоположение")
    page_id = models.BigIntegerField(blank=True, null=True, verbose_name="ID страницы")
    url_parameters = models.TextField(blank=True, null=True, verbose_name="Параметры URL")
    page_title = models.TextField(blank=True, null=True, verbose_name="Заголовок страницы")
    type = models.CharField(max_length=50, verbose_name="Тип")
    last_counter = models.IntegerField(verbose_name="Последний счетчик")
    hits = models.IntegerField(verbose_name="Количество обращений")
    honeypot = models.BooleanField(verbose_name="Метка honeypot")
    reply = models.BooleanField(verbose_name="Ответ пользователя")
    page_url = models.URLField(blank=True, null=True, verbose_name="URL страницы")

    def __str__(self):
        return f"UserActivityLog {self.id}: {self.page_title}"

    class Meta:
        verbose_name = "Регистрация посетителей"
        verbose_name_plural = "Регистрации посетителей"


class ExternalDBSettings(models.Model):
    name = models.CharField(max_length=255, unique=True, help_text="Имя подключения для идентификации.")
    host = models.CharField(max_length=255, help_text="Адрес сервера базы данных.")
    port = models.PositiveIntegerField(default=3306, help_text="Порт сервера базы данных.")
    user = models.CharField(max_length=255, help_text="Имя пользователя базы данных.")
    password = models.CharField(max_length=255, help_text="Пароль для подключения.")
    database = models.CharField(max_length=255, default="u1510415_wp832", help_text="Имя базы данных.")
    table_name = models.CharField(max_length=255, blank=True, default="wpts_user_activity_log", null=True, help_text="Имя таблицы для загрузки данных.")
    selected_fields = models.TextField(blank=True, null=True, help_text="Список полей для загрузки (через запятую).")
    is_active = models.BooleanField(default=True, help_text="Флаг активности подключения.")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.name} ({self.host}:{self.port})"

    class Meta:
        verbose_name = "Настройка подключения к БД"
        verbose_name_plural = "Настройки подключений к БД"


class RoomDiscrepancy(models.Model):
    hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, verbose_name="Отель")
    room_number = models.CharField(max_length=50, verbose_name="Номер комнаты")
    booking_id = models.CharField(max_length=255, verbose_name="ID бронирования")
    check_in_date_expected = models.DateField(verbose_name="Ожидаемая дата заселения")
    check_in_date_actual = models.DateField(verbose_name="Фактическая дата заселения")
    discrepancy_type = models.CharField(
        max_length=50,
        choices=[("early", "Раннее заселение"), ("late", "Позднее заселение"), ("missed", "Неявка")],
        verbose_name="Тип несоответствия"
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")

    def __str__(self):
        return f"{self.hotel.name} - Room {self.room_number}: {self.discrepancy_type}"

    class Meta:
        verbose_name = "Несовпадение в заселении"
        verbose_name_plural = "Несовпадения в заселении"

    @staticmethod
    def detect_discrepancies(expected_bookings, actual_check_ins):
        """
        Сравнение ожидаемых и фактических данных о заселении.
        """
        discrepancies = []

        # Преобразуем фактические заселения в словарь для быстрого доступа
        actual_dict = {
            (entry.hotel_id, entry.room_number): entry.check_in_date
            for entry in actual_check_ins
        }

        for booking in expected_bookings:
            key = (booking.hotel_id, booking.room_number)
            actual_date = actual_dict.get(key)

            if actual_date is None:
                discrepancies.append(RoomDiscrepancy(
                    hotel=booking.hotel,
                    room_number=booking.room_number,
                    booking_id=booking.booking_id,
                    check_in_date_expected=booking.check_in_date,
                    discrepancy_type="missed"
                ))
            elif actual_date < booking.check_in_date:
                discrepancies.append(RoomDiscrepancy(
                    hotel=booking.hotel,
                    room_number=booking.room_number,
                    booking_id=booking.booking_id,
                    check_in_date_expected=booking.check_in_date,
                    check_in_date_actual=actual_date,
                    discrepancy_type="early"
                ))
            elif actual_date > booking.check_in_date:
                discrepancies.append(RoomDiscrepancy(
                    hotel=booking.hotel,
                    room_number=booking.room_number,
                    booking_id=booking.booking_id,
                    check_in_date_expected=booking.check_in_date,
                    check_in_date_actual=actual_date,
                    discrepancy_type="late"
                ))

        RoomDiscrepancy.objects.bulk_create(discrepancies)

from urllib.parse import unquote
from html import unescape

class ImportedHotel(models.Model):
    id = models.BigAutoField(primary_key=True, auto_created=True, verbose_name="ID")
    external_id = models.CharField(max_length=255, verbose_name="Внешний ID отеля")
    name = models.CharField(max_length=255, verbose_name="Имя отеля")
    display_name = models.CharField(max_length=255, null=True, blank=True, verbose_name="Отображаемое имя")
    created = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
    updated = models.DateTimeField(auto_now=True, verbose_name="Дата обновления")
    imported = models.BooleanField(default=False, verbose_name="Импортирован в основную базу")

    def __str__(self):
        return f"{self.display_name or self.name} ({self.external_id})"

    class Meta:
        verbose_name = "Импортированный отель"
        verbose_name_plural = "Импортированные отели"

    def set_display_name_from_page_title(self, page_title):
        """
        Декодирует HTML-сущности, URL-кодировку и устанавливает display_name.
        """
        if page_title:
            decoded = unquote(unescape(page_title))
            self.display_name = decoded
        else:
            self.display_name = self.name
        self.save()

class SyncLog(models.Model):
    """
    Журнал синхронизации.
    """
    id = models.BigIntegerField(primary_key=True, unique=True, verbose_name="ID")
    hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, verbose_name="Отель")
    reservation = models.ForeignKey(Reservation, on_delete=models.CASCADE, verbose_name="Бронирование")
    created = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
    recieved_records = models.IntegerField(verbose_name="Полученные записи")
    processed_records = models.IntegerField(verbose_name="Обработанные записи")

    class Meta:
        verbose_name = "Журнал синхронизации"
        verbose_name_plural = "Журналы синхронизации"
        
        
class ViolationLog(models.Model):
    hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, verbose_name="Отель")
    room_number = models.CharField(max_length=50, verbose_name="Номер комнаты", null=True, blank=True)
    violation_type = models.CharField(
        max_length=50,
        choices=[("missed", "Неявка"), ("early", "Раннее заселение"), ("late", "Позднее заселение")],
        verbose_name="Тип нарушения"
    )
    violation_details = models.TextField(verbose_name="Детали нарушения", blank=True, null=True)
    detected_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата обнаружения")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")

    def __str__(self):
        return f"{self.hotel.name} - {self.room_number or 'N/A'}: {self.violation_type}"

    class Meta:
        verbose_name = "Журнал нарушений"
        verbose_name_plural = "Журналы нарушений"
