# -*- coding: utf-8 -*-
"""
Тесты защиты системного клиента от изменений и удаления.

Системный клиент используется для анонимных продаж в POS системе
и должен быть защищён от случайного изменения или удаления.

Используем TenantTestCase для корректной работы с tenant-системой.
"""
from django.core.exceptions import ValidationError
from django_tenants.test.cases import TenantTestCase

from customers.models import Customer


class SystemCustomerProtectionTestCase(TenantTestCase):
    """
    Тесты защиты системного клиента от изменений и удаления.
    
    Системный клиент используется для анонимных продаж в POS системе
    и должен быть защищён от случайного изменения или удаления.
    """

    def setUp(self):
        """Создаём системного клиента для тестов."""
        self.system_customer, created = Customer.get_or_create_system_customer()
        self.regular_customer = Customer.objects.create(
            name="Обычный клиент",
            email="regular@test.com"
        )

    def test_get_or_create_system_customer_creates_with_correct_attributes(self):
        """
        Метод get_or_create_system_customer() создаёт клиента с правильными атрибутами.
        
        Проверяем:
        - Фиксированный email: system@pos.customer
        - Флаг is_system_customer = True
        - Правильное имя и заметки
        """
        # Удаляем существующего системного клиента для чистоты теста
        Customer.objects.filter(is_system_customer=True).delete()
        
        # Создаём через метод класса
        customer, created = Customer.get_or_create_system_customer()
        
        # Проверяем, что клиент действительно создан
        self.assertTrue(created, "Системный клиент должен быть создан")
        
        # Проверяем атрибуты
        self.assertEqual(customer.email, "system@pos.customer")
        self.assertTrue(customer.is_system_customer)
        self.assertEqual(customer.name, "АНОНИМНЫЙ ПОКУПАТЕЛЬ (POS)")
        self.assertIn("SYSTEM_CUSTOMER", customer.notes)
        
        # Проверяем идемпотентность - повторный вызов возвращает того же клиента
        customer2, created2 = Customer.get_or_create_system_customer()
        self.assertFalse(created2, "Системный клиент не должен создаваться повторно")
        self.assertEqual(customer.pk, customer2.pk, "Должен вернуться тот же клиент")

    def test_system_customer_cannot_be_deleted(self):
        """
        Системный клиент защищён от удаления через метод delete().
        
        При попытке удаления должен подниматься ValidationError.
        Это критично для работы POS системы.
        """
        with self.assertRaises(ValidationError) as context:
            self.system_customer.delete()
        
        self.assertIn("Нельзя удалить системного клиента", str(context.exception))
        
        # Проверяем, что клиент действительно не удалён
        self.assertTrue(
            Customer.objects.filter(pk=self.system_customer.pk).exists(),
            "Системный клиент не должен быть удалён"
        )

    def test_system_customer_email_cannot_be_changed(self):
        """
        Email системного клиента защищён от изменения.
        
        Фиксированный email "system@pos.customer" используется для поиска
        системного клиента в POS системе. Изменение приведёт к сбоям.
        """
        original_email = self.system_customer.email
        
        # Пытаемся изменить email
        self.system_customer.email = "hacker@evil.com"
        
        with self.assertRaises(ValidationError) as context:
            self.system_customer.save()
        
        self.assertIn("Нельзя изменить email системного клиента", str(context.exception))
        
        # Проверяем, что email остался прежним в БД
        self.system_customer.refresh_from_db()
        self.assertEqual(self.system_customer.email, original_email)

    def test_system_customer_flag_cannot_be_removed(self):
        """
        Флаг is_system_customer защищён от изменения.
        
        Нельзя "превратить" системного клиента в обычного,
        это нарушит логику POS системы.
        """
        # Пытаемся снять флаг системного клиента
        self.system_customer.is_system_customer = False
        
        with self.assertRaises(ValidationError) as context:
            self.system_customer.save()
        
        self.assertIn("Нельзя изменить флаг системного клиента", str(context.exception))
        
        # Проверяем, что флаг остался True в БД
        self.system_customer.refresh_from_db()
        self.assertTrue(self.system_customer.is_system_customer)

    def test_regular_customer_can_be_deleted_normally(self):
        """
        Обычный клиент (не системный) может быть удалён без ограничений.
        
        Защита применяется ТОЛЬКО к системному клиенту.
        Это гарантирует, что мы не сломали обычный функционал удаления.
        """
        customer_pk = self.regular_customer.pk
        
        # Удаление должно пройти успешно
        self.regular_customer.delete()
        
        # Проверяем, что клиент действительно удалён
        self.assertFalse(
            Customer.objects.filter(pk=customer_pk).exists(),
            "Обычный клиент должен быть удалён"
        )
