# -*- coding: utf-8 -*-
from odoo.tests.common import TransactionCase
from odoo.fields import Datetime
from datetime import datetime, timedelta
from odoo.exceptions import UserError

class TestEventRental(TransactionCase):

    @classmethod
    def setUpClass(cls):
        super(TestEventRental, cls).setUpClass()
        
        # Create a rental product template first, then get variant
        cls.rental_product = cls.env['product.product'].create({
            'name': 'Wedding Chair',
            'type': 'product',
            'is_rental': True,
            'rental_price_per_day': 10.0,
        })
        
        # Set quantity on hand using Odoo stock.quant
        warehouse = cls.env['stock.warehouse'].search([], limit=1)
        if warehouse:
            location = warehouse.lot_stock_id
            cls.env['stock.quant'].with_context(inventory_mode=True).create({
                'product_id': cls.rental_product.id,
                'location_id': location.id,
                'inventory_quantity': 50.0,
            }).action_apply_inventory()
        
        # Create a customer partner
        cls.partner = cls.env['res.partner'].create({
            'name': 'Test Client',
            'email': 'client@test.com',
            'phone': '1234567890',
        })

    def test_01_rental_flow(self):
        """ Test the complete rental reservation, pricing, approval, payment, and delivery flow """
        # Define dates: 3 days rental duration
        start_date = datetime.now() + timedelta(days=1)
        end_date = start_date + timedelta(days=3)
        
        # Create request
        request = self.env['event.rental.request'].create({
            'partner_id': self.partner.id,
            'start_date': start_date,
            'end_date': end_date,
            'location': 'Grand Palace Hall',
            'event_type': 'wedding',
            'delivery_charge': 50.0,
            'setup_charge': 30.0,
        })
        
        # Create line: booking 10 chairs
        line = self.env['event.rental.line'].create({
            'request_id': request.id,
            'product_id': self.rental_product.id,
            'quantity': 10.0,
        })
        
        # Verify duration-based pricing: 3 days * $10 per day = $30 per chair unit
        self.assertEqual(line.price_unit, 30.0, "Line unit price should be rental_price_per_day * duration")
        self.assertEqual(line.price_subtotal, 300.0, "Subtotal should be quantity * price_unit")
        
        # Verify grand total: $300 (subtotal) + $50 (delivery) + $30 (setup) = $380
        self.assertEqual(request.amount_total, 380.0, "Grand total is incorrect")
        
        # Check availability
        avail = request.check_availability(start_date, end_date, self.rental_product)
        self.assertEqual(avail, 50.0, "Before approval, all 50 chairs should be available")
        
        # Approve request
        request.action_approve()
        
        # Status should become quotation_sent
        self.assertEqual(request.status, 'quotation_sent')
        self.assertTrue(request.sale_order_id, "Sales Order should be generated")
        self.assertEqual(request.sale_order_id.amount_untaxed, 380.0, "Sales order untaxed total should match rental request total")
        
        # Check availability again: since approved request blocks inventory, available should drop by 10
        avail_after_approval = request.check_availability(start_date, end_date, self.rental_product)
        self.assertEqual(avail_after_approval, 40.0, "Approved booking should block inventory")
        
        # Confirm Sale Order (simulating payment)
        request.sale_order_id.action_confirm()
        
        # Request status should automatically become confirmed
        self.assertEqual(request.status, 'confirmed')
        
        # Deliver products
        request.action_deliver()
        self.assertEqual(request.status, 'delivered')
        self.assertEqual(request.delivery_status, 'delivered')
        
        # Return products
        request.action_pickup()
        self.assertEqual(request.status, 'returned')
        self.assertEqual(request.delivery_status, 'picked_up')

    def test_02_overbooking_prevention(self):
        """ Test that overbooking raises a UserError during approval """
        start_date = datetime.now() + timedelta(days=1)
        end_date = start_date + timedelta(days=3)
        
        # Request 60 chairs (only 50 are on hand)
        request = self.env['event.rental.request'].create({
            'partner_id': self.partner.id,
            'start_date': start_date,
            'end_date': end_date,
            'location': 'Venue Hall',
        })
        self.env['event.rental.line'].create({
            'request_id': request.id,
            'product_id': self.rental_product.id,
            'quantity': 60.0,
        })
        
        # Approving should raise UserError
        with self.assertRaises(UserError):
            request.action_approve()
