from django.test import TestCase, Client
from django.urls import reverse
from delivery_app.models import Pedido, Repartidor, Usuario, Plato, PedidosCliente
from django.core.exceptions import ValidationError

class UsuarioTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        self.usuario_cliente = Usuario.objects.create_user(username="cliente1", email="cliente@example.com", password="testpassword", nombre="Cliente")
        self.usuario_repartidor = Usuario.objects.create_user(username="repartidor1", email="repartidor@example.com", password="testpassword", nombre="Repartidor")
    
    def test_login_cliente(self):
        # Prueba para verificar el inicio de sesión de un cliente
        response = self.client.post(reverse('login'), {'username': 'cliente1', 'password': 'testpassword'})
        self.assertEqual(response.status_code, 302)  # Redirección tras login
    
    def test_login_repartidor(self):
        # Prueba para verificar el inicio de sesión de un repartidor
        response = self.client.post(reverse('login'), {'username': 'repartidor1', 'password': 'testpassword'})
        self.assertEqual(response.status_code, 302)

    def test_usuario_model(self):
        # Prueba para verificar la creación de un usuario con datos válidos
        valid_data = {
            'username': 'cliente3',
            'email': 'cliente3@example.com',
            'password': 'testpassword',
            'nombre': 'Cliente',
            'apellido': 'Apellido'
        }
        usuario = Usuario.objects.create_user(**valid_data)
        self.assertEqual(usuario.username, 'cliente3')
        self.assertEqual(usuario.email, 'cliente3@example.com')
        self.assertTrue(usuario.check_password('testpassword'))

    def test_usuario_model_invalid(self):
        # Prueba para verificar que no se puede crear un usuario con datos inválidos
        invalid_data = {
            'username': '',
            'email': 'invalid-email',
            'password': '',
            'nombre': 'Cliente',
            'apellido': 'Apellido'
        }
        with self.assertRaises(ValidationError):
            Usuario.objects.create_user(**invalid_data).full_clean()

class RepartidorTestCase(TestCase):
    def setUp(self):
        self.usuario = Usuario.objects.create_user(username="repartidor2", email="repartidor2@example.com", password="testpassword", nombre="Repartidor")
        self.repartidor = Repartidor.objects.create(usuario=self.usuario, disponibilidad="disponible")
        self.client = Client()
    
    def test_lista_repartidores(self):
        # Prueba para verificar la lista de repartidores
        response = self.client.get(reverse('repartidor_list'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Lista de Repartidores")
    
    def test_detalle_repartidor(self):
        # Prueba para verificar el detalle de un repartidor
        response = self.client.get(reverse('repartidor_detail', args=[self.repartidor.id]))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "disponible")
    
    def test_eliminar_repartidor(self):
        # Prueba para verificar la eliminación de un repartidor
        response = self.client.post(reverse('repartidor_delete', args=[self.repartidor.id]))
        self.assertEqual(response.status_code, 302)
        self.assertEqual(Repartidor.objects.count(), 0)

class PedidoTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        self.usuario = Usuario.objects.create_user(username="cliente2", email="cliente2@example.com", password="testpassword", nombre="Cliente")
        self.repartidor = Repartidor.objects.create(usuario=self.usuario, disponibilidad="disponible")
        self.pedido = Pedido.objects.create(
            direccion="Av. Siempre Viva 123",
            estado="pendiente_aprobacion",
            repartidor=self.repartidor,
            comentarios="Sin cebolla",
            precio_total=500.00
        )
        PedidosCliente.objects.create(usuario=self.usuario, pedido=self.pedido)
    
    def test_cambiar_estado_pedido(self):
        # Prueba para verificar el cambio de estado de un pedido
        response = self.client.post(reverse('cambiar_estado_pedido_repartidor', args=[self.pedido.id]), {
            'estado': 'entregado'
        })
        self.assertEqual(response.status_code, 302)  # Redirección después de cambio
        self.pedido.refresh_from_db()
        self.assertEqual(self.pedido.estado, 'entregado')

    def test_menu(self):
        # Prueba para verificar la vista del menú
        response = self.client.get(reverse('menu'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Menú")

    def test_promociones(self):
        # Prueba para verificar la vista de promociones
        response = self.client.get(reverse('promociones'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Promociones")

    def test_pedidos(self):
        # Prueba para verificar la vista de pedidos
        self.client.login(username='cliente2', password='testpassword')
        response = self.client.get(reverse('pedidos'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Historial de Pedidos")

    def test_index(self):
        # Prueba para verificar la vista de la página de inicio
        response = self.client.get(reverse('index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Bienvenidos a El Nono Rotisería")

    def test_profile(self):
        # Prueba para verificar la vista del perfil de usuario
        self.client.login(username='cliente2', password='testpassword')
        response = self.client.get(reverse('profile'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Perfil de Usuario")

    def test_confirmar_pedido(self):
        # Prueba para verificar la vista de confirmación de pedido
        self.client.login(username='cliente2', password='testpassword')
        response = self.client.get(reverse('confirmar_pedido'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Confirmar Pedido")

    def test_agregar_al_carrito(self):
        # Prueba para verificar la funcionalidad de agregar al carrito
        self.client.login(username='cliente2', password='testpassword')
        plato = Plato.objects.create(plato="Pizza", precio=100.00, ingredientes="Tomate, Queso", t_preparacion=15)
        response = self.client.post(reverse('agregar_al_carrito'), {
            'plato_id': plato.id,
            'cantidad': 2
        })
        self.assertEqual(response.status_code, 302)
        self.assertTrue(Pedido.objects.filter(comentarios="Sin cebolla").exists())

   
