from odoo import models, fields, api, _
import logging

_logger = logging.getLogger(__name__)

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    def _get_available_carriers(self, **kwargs):
        """Force Include the Uber carrier in the available list to bypass Odoo's address/website filters"""
        carriers = super()._get_available_carriers(**kwargs)
        if self.carrier_id and 'Uber' in (self.carrier_id.name or ''):
            if self.carrier_id not in carriers:
                carriers |= self.carrier_id
        return carriers

    def _add_uber_delivery_fee(self, amount):
        """Add the delivery fee using Odoo's standard delivery system to satisfy checkout validation"""
        _logger.info("Uber: Syncing delivery fee %s to order %s", amount, self.name)
        
        # 1. Ensure fulfillment type is set
        if hasattr(self, 'fulfilment_type'):
            self.write({
                'fulfilment_type': 'delivery',
                'partner_shipping_id': self.partner_id.id
            })
        else:
            self.write({'partner_shipping_id': self.partner_id.id})

        # 2. Find or Create the Uber Delivery carrier
        Carrier = self.env['delivery.carrier'].sudo()
        config = self.env['uber.config'].sudo().search([('active', '=', True)], limit=1)
        
        # Search for any carrier linked to the Uber product or with Uber in the name
        carrier = Carrier.search(['|', ('name', 'ilike', 'Uber'), ('product_id', '=', config.delivery_product_id.id if config.delivery_product_id else 0)], limit=1)
        
        if not carrier and config:
            # Fallback product if one isn't set in config
            product = config.delivery_product_id
            if not product:
                product = self.env['product.product'].sudo().search([('name', 'ilike', 'Delivery')], limit=1)
                if not product:
                    product = self.env['product.product'].sudo().search([], limit=1) # Last resort
            
            _logger.info("Uber: Creating new Uber Delivery carrier using product %s", product.name)
            carrier = Carrier.create({
                'name': 'Uber Direct Delivery',
                'delivery_type': 'fixed',
                'product_id': product.id,
                'website_published': True,
                'fixed_price': 0.0,
                'active': True,
            })
        
        if carrier:
            # Force carrier to be published and global to avoid "No shipping method" error
            carrier.sudo().write({
                'website_published': True,
                'active': True,
                'country_ids': [(6, 0, [])], 
                'state_ids': [(6, 0, [])],
                'zip_prefix_ids': [(6, 0, [])] if hasattr(Carrier, 'zip_prefix_ids') else False
            })
            
            # 3. Use Odoo's standard method to set delivery
            _logger.info("Uber: Setting carrier %s with fee %s", carrier.name, amount)
            
            # Lock the price on the carrier record itself temporarily (SUDO) to satisfy Odoo's check_carrier
            carrier.sudo().write({'fixed_price': amount})
            
            # Remove any existing delivery lines first to prevent accumulation
            # We do this manually because our protection in online_orders blocks the automatic removal
            self.order_line.filtered(lambda l: l.is_delivery).sudo().unlink()
            
            # Apply to order
            self.sudo().set_delivery_line(carrier, amount)
            self.sudo().write({'carrier_id': carrier.id})
            
            # Force the line name and price one more time to be sure
            delivery_line = self.order_line.filtered(lambda l: l.is_delivery)
            if delivery_line:
                delivery_line.sudo().write({
                    'price_unit': amount,
                    'name': f"Uber Direct Delivery ({self.partner_id.city or 'Local'})"
                })
        else:
            _logger.warning("Uber: No delivery carrier found to apply fee")
        
        # Save everything to DB immediately
        self.env.cr.commit()
        return True
