"""
Модели заявок на источники (SourceRequest, SourceRequestStatusHistory).
"""
from django.contrib.gis.db import models as gis
from django.db import models


class SourceRequest(models.Model):
    """
    Модель заявки на источник.
    
    Хранит информацию о заявках на обработку источников с различными статусами.
    """
    
    STATUS_CHOICES = [
        ('planned', 'Запланировано'),
        ('canceled_gso', 'Отменено ГСО'),
        ('canceled_kub', 'Отменено МКА'),
        ('conducted', 'Проведён'),
        ('successful', 'Успешно'),
        ('no_correlation', 'Нет корреляции'),
        ('no_signal', 'Нет сигнала в спектре'),
        ('unsuccessful', 'Неуспешно'),
        ('downloading', 'Скачивание'),
        ('processing', 'Обработка'),
        ('result_received', 'Результат получен'),
    ]
    
    PRIORITY_CHOICES = [
        ('low', 'Низкий'),
        ('medium', 'Средний'),
        ('high', 'Высокий'),
    ]
    
    # Связь с источником (опционально для заявок без привязки)
    source = models.ForeignKey(
        'mainapp.Source',
        on_delete=models.CASCADE,
        related_name='source_requests',
        verbose_name='Источник',
        null=True,
        blank=True,
        help_text='Связанный источник',
    )
    
    # Связь со спутником
    satellite = models.ForeignKey(
        'mainapp.Satellite',
        on_delete=models.SET_NULL,
        related_name='satellite_requests',
        verbose_name='Спутник',
        null=True,
        blank=True,
        help_text='Связанный спутник',
    )

    # Основные поля
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='planned',
        verbose_name='Статус',
        db_index=True,
        help_text='Текущий статус заявки',
    )
    priority = models.CharField(
        max_length=10,
        choices=PRIORITY_CHOICES,
        default='medium',
        verbose_name='Приоритет',
        db_index=True,
        help_text='Приоритет заявки',
    )
    
    # Даты
    planned_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Дата и время планирования',
        help_text='Запланированная дата и время',
    )
    request_date = models.DateField(
        null=True,
        blank=True,
        verbose_name='Дата заявки',
        help_text='Дата подачи заявки',
    )
    card_date = models.DateField(
        null=True,
        blank=True,
        verbose_name='Дата формирования карточки',
        help_text='Дата формирования карточки',
    )
    status_updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления статуса',
        help_text='Дата и время последнего обновления статуса',
    )
    
    # Частоты и перенос
    downlink = models.FloatField(
        null=True,
        blank=True,
        verbose_name='Частота Downlink, МГц',
        help_text='Частота downlink в МГц',
    )
    uplink = models.FloatField(
        null=True,
        blank=True,
        verbose_name='Частота Uplink, МГц',
        help_text='Частота uplink в МГц',
    )
    transfer = models.FloatField(
        null=True,
        blank=True,
        verbose_name='Перенос, МГц',
        help_text='Перенос по частоте в МГц',
    )

    # Результаты
    gso_success = models.BooleanField(
        null=True,
        blank=True,
        verbose_name='ГСО успешно?',
        help_text='Успешность ГСО',
    )
    kubsat_success = models.BooleanField(
        null=True,
        blank=True,
        verbose_name='Кубсат успешно?',
        help_text='Успешность Кубсат',
    )
    
    # Район
    region = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        verbose_name='Район',
        help_text='Район/местоположение',
    )
    
    # Комментарий
    comment = models.TextField(
        null=True,
        blank=True,
        verbose_name='Комментарий',
        help_text='Дополнительные комментарии к заявке',
    )
    
    # Координаты ГСО (усреднённые по выбранным точкам)
    coords = gis.PointField(
        srid=4326,
        null=True,
        blank=True,
        verbose_name='Координаты ГСО',
        help_text='Координаты ГСО (WGS84)',
    )
    
    # Координаты источника
    coords_source = gis.PointField(
        srid=4326,
        null=True,
        blank=True,
        verbose_name='Координаты источника',
        help_text='Координаты источника (WGS84)',
    )
    
    # Координаты объекта
    coords_object = gis.PointField(
        srid=4326,
        null=True,
        blank=True,
        verbose_name='Координаты объекта',
        help_text='Координаты объекта (WGS84)',
    )

    # Количество точек, использованных для расчёта координат
    points_count = models.PositiveIntegerField(
        default=0,
        verbose_name='Количество точек',
        help_text='Количество точек ГЛ, использованных для расчёта координат',
    )
    
    # Метаданные
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания',
        help_text='Дата и время создания записи',
    )
    created_by = models.ForeignKey(
        'mainapp.CustomUser',
        on_delete=models.SET_NULL,
        related_name='source_requests_created',
        null=True,
        blank=True,
        verbose_name='Создан пользователем',
        help_text='Пользователь, создавший запись',
    )
    updated_by = models.ForeignKey(
        'mainapp.CustomUser',
        on_delete=models.SET_NULL,
        related_name='source_requests_updated',
        null=True,
        blank=True,
        verbose_name='Изменен пользователем',
        help_text='Пользователь, последним изменивший запись',
    )
    
    def __str__(self):
        return f"Заявка #{self.pk} - {self.source_id} ({self.get_status_display()})"
    
    def save(self, *args, **kwargs):
        # Определяем, изменился ли статус
        old_status = None
        if self.pk:
            try:
                old_instance = SourceRequest.objects.get(pk=self.pk)
                old_status = old_instance.status
            except SourceRequest.DoesNotExist:
                pass
        
        super().save(*args, **kwargs)
        
        # Если статус изменился, создаем запись в истории
        if old_status is not None and old_status != self.status:
            SourceRequestStatusHistory.objects.create(
                source_request=self,
                old_status=old_status,
                new_status=self.status,
                changed_by=self.updated_by,
            )
    
    class Meta:
        verbose_name = 'Заявка на источник'
        verbose_name_plural = 'Заявки на источники'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['-created_at']),
            models.Index(fields=['status']),
            models.Index(fields=['priority']),
            models.Index(fields=['source', '-created_at']),
        ]


class SourceRequestStatusHistory(models.Model):
    """
    Модель истории изменений статусов заявок.
    
    Хранит полную хронологию изменений статусов заявок.
    """
    
    source_request = models.ForeignKey(
        SourceRequest,
        on_delete=models.CASCADE,
        related_name='status_history',
        verbose_name='Заявка',
        help_text='Связанная заявка',
    )
    old_status = models.CharField(
        max_length=20,
        choices=SourceRequest.STATUS_CHOICES,
        verbose_name='Старый статус',
        help_text='Статус до изменения',
    )
    new_status = models.CharField(
        max_length=20,
        choices=SourceRequest.STATUS_CHOICES,
        verbose_name='Новый статус',
        help_text='Статус после изменения',
    )
    changed_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата изменения',
        db_index=True,
        help_text='Дата и время изменения статуса',
    )
    changed_by = models.ForeignKey(
        'mainapp.CustomUser',
        on_delete=models.SET_NULL,
        related_name='status_changes',
        null=True,
        blank=True,
        verbose_name='Изменен пользователем',
        help_text='Пользователь, изменивший статус',
    )
    
    def __str__(self):
        return f"{self.source_request_id}: {self.get_old_status_display()} → {self.get_new_status_display()}"
    
    class Meta:
        verbose_name = 'История статуса заявки'
        verbose_name_plural = 'История статусов заявок'
        ordering = ['-changed_at']
        indexes = [
            models.Index(fields=['-changed_at']),
            models.Index(fields=['source_request', '-changed_at']),
        ]
