# -*- coding: utf-8 -*-
from django.db import models
from django.core.exceptions import ValidationError


class Delivery(models.Model):
    """
    Модель доставки заказа.
    Один заказ имеет одну доставку.
    """

    # Константы для типов доставки
    DELIVERY_TYPE_COURIER = 'courier'
    DELIVERY_TYPE_PICKUP = 'pickup'

    DELIVERY_TYPE_CHOICES = [
        (DELIVERY_TYPE_COURIER, 'Доставка курьером'),
        (DELIVERY_TYPE_PICKUP, 'Самовывоз'),
    ]

    # === Связи ===

    order = models.OneToOneField(
        'orders.Order',
        on_delete=models.CASCADE,
        related_name='delivery',
        verbose_name='Заказ',
        help_text='Заказ, к которому относится доставка'
    )

    # Адрес доставки (только для курьерской доставки)
    address = models.ForeignKey(
        'orders.Address',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='deliveries',
        verbose_name='Адрес доставки',
        help_text='Адрес для курьерской доставки. На один адрес может быть много доставок'
    )

    # Склад для самовывоза (только для самовывоза)
    pickup_warehouse = models.ForeignKey(
        'inventory.Warehouse',
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name='deliveries',
        verbose_name='Склад самовывоза',
        help_text='Склад для самовывоза заказа'
    )

    # === Основные поля ===

    delivery_type = models.CharField(
        max_length=20,
        choices=DELIVERY_TYPE_CHOICES,
        default=DELIVERY_TYPE_COURIER,
        verbose_name='Способ доставки',
        db_index=True
    )

    # Дата и время доставки
    delivery_date = models.DateField(
        null=True,
        blank=True,
        verbose_name='Дата доставки',
        help_text='Дата, когда должна быть выполнена доставка (обязательна для не-черновиков)'
    )

    time_from = models.TimeField(
        null=True,
        blank=True,
        verbose_name='Время доставки от',
        help_text='Начальное время временного интервала доставки (необязательно)'
    )

    time_to = models.TimeField(
        null=True,
        blank=True,
        verbose_name='Время доставки до',
        help_text='Конечное время временного интервала доставки (необязательно)'
    )

    cost = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0,
        verbose_name='Стоимость доставки',
        help_text='Стоимость доставки в рублях. 0 для бесплатной доставки/самовывоза'
    )

    # === Метаданные ===

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )

    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )

    class Meta:
        verbose_name = 'Доставка'
        verbose_name_plural = 'Доставки'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['delivery_type']),
            models.Index(fields=['created_at']),
            models.Index(fields=['delivery_date']),
            models.Index(fields=['time_from']),
            models.Index(fields=['time_to']),
        ]

    def __str__(self):
        """Строковое представление доставки"""
        type_display = self.get_delivery_type_display()
        return f"{type_display} для заказа #{self.order.order_number}"

    def clean(self):
        """Валидация модели"""
        super().clean()

        # Для черновиков пропускаем строгую валидацию
        if self.order and self.order.status and hasattr(self.order.status, 'code') and self.order.status.code == 'draft':
            # Для черновиков только проверяем время, если оно указано
            if self.time_from and self.time_to and self.time_from > self.time_to:
                raise ValidationError({
                    'time_to': 'Время окончания доставки не может быть раньше времени начала'
                })
            return

        # Для не-черновиков ранее действовала строгая валидация даты и адреса.
        # В рамках новой логики разрешаем сохранять заказы в любом статусе без адреса
        # и без обязательной даты доставки. Сохраняем только базовые проверки
        # непротиворечивости данных.

        # Проверка: время "до" не может быть раньше времени "от" (равные времена разрешены для POS)
        if self.time_from and self.time_to and self.time_from > self.time_to:
            raise ValidationError({
                'time_to': 'Время окончания доставки не может быть раньше времени начала'
            })

    def save(self, *args, validate=True, **kwargs):
        """Переопределение save для вызова валидации"""
        if validate:
            self.full_clean()
        super().save(*args, **kwargs)
