# Django imports
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import ExpressionWrapper, F
from django.db.models.functions import Abs

# Local imports
from mainapp.models import Polarization, Satellite, get_default_polarization, CustomUser


class Transponders(models.Model):
    """
    Модель транспондера спутника.

    Хранит информацию о частотах uplink/downlink, зоне покрытия и поляризации.
    """

    # Основные поля
    name = models.CharField(
        max_length=30,
        null=True,
        blank=True,
        verbose_name="Название транспондера",
        db_index=True,
        help_text="Название транспондера",
    )
    downlink = models.FloatField(
        blank=True,
        null=True,
        verbose_name="Downlink",
        # validators=[MinValueValidator(0), MaxValueValidator(50000)],
        # help_text="Частота downlink в МГц (0-50000)"
    )
    frequency_range = models.FloatField(
        blank=True,
        null=True,
        verbose_name="Полоса",
        # validators=[MinValueValidator(0), MaxValueValidator(1000)],
        # help_text="Полоса частот в МГц (0-1000)"
    )
    uplink = models.FloatField(
        blank=True,
        null=True,
        verbose_name="Uplink",
        # validators=[MinValueValidator(0), MaxValueValidator(50000)],
        # help_text="Частота uplink в МГц (0-50000)"
    )
    zone_name = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        verbose_name="Название зоны",
        db_index=True,
        help_text="Название зоны покрытия транспондера",
    )
    snr = models.FloatField(
        blank=True,
        null=True,
        verbose_name="ОСШ, дБ",
        # validators=[MinValueValidator(0), MaxValueValidator(1000)],
        help_text="Отношение сигнал/шум в децибелах",
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Дата создания",
        help_text="Дата и время создания записи",
    )
    created_by = models.ForeignKey(
        CustomUser,
        on_delete=models.SET_NULL,
        related_name="transponder_created",
        null=True,
        blank=True,
        verbose_name="Создан пользователем",
        help_text="Пользователь, создавший запись",
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Дата последнего изменения",
        help_text="Дата и время последнего изменения",
    )
    updated_by = models.ForeignKey(
        CustomUser,
        on_delete=models.SET_NULL,
        related_name="transponder_updated",
        null=True,
        blank=True,
        verbose_name="Изменен пользователем",
        help_text="Пользователь, последним изменивший запись",
    )

    # Связи
    polarization = models.ForeignKey(
        Polarization,
        default=get_default_polarization,
        on_delete=models.SET_DEFAULT,
        related_name="tran_polarizations",
        null=True,
        blank=True,
        verbose_name="Поляризация",
        help_text="Поляризация сигнала",
    )
    sat_id = models.ForeignKey(
        Satellite,
        on_delete=models.SET_NULL,
        null=True,
        related_name="tran_satellite",
        verbose_name="Спутник",
        db_index=True,
        help_text="Спутник, которому принадлежит транспондер",
    )

    # Вычисляемые поля
    transfer = models.GeneratedField(
        expression=ExpressionWrapper(
            Abs(F("downlink") - F("uplink")), output_field=models.FloatField()
        ),
        output_field=models.FloatField(),
        db_persist=True,
        null=True,
        blank=True,
        verbose_name="Перенос",
    )

    # def clean(self):
    #     """Валидация на уровне модели"""
    #     super().clean()

    #     # Проверка что downlink и uplink заданы
    #     if self.downlink and self.uplink:
    #         # Обычно uplink выше downlink для спутниковой связи
    #         if self.uplink < self.downlink:
    #             raise ValidationError({
    #                 'uplink': 'Частота uplink обычно выше частоты downlink'
    #             })

    def __str__(self):
        if self.name:
            return self.name
        return f"Транспондер {self.sat_id.name if self.sat_id else 'Unknown'}"

    class Meta:
        verbose_name = "Транспондер"
        verbose_name_plural = "Транспондеры"
        ordering = ["sat_id", "downlink"]
        indexes = [
            models.Index(fields=["sat_id", "downlink"]),
            models.Index(fields=["sat_id", "zone_name"]),
        ]
