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

_logger = logging.getLogger(__name__)

class PosOrderLine(models.Model):
    _inherit = 'pos.order.line'

    preparation_status = fields.Selection([
        ('waiting', 'Waiting'),
        ('preparing', 'Preparing'),
        ('ready', 'Ready'),
        ('served', 'Served'),
        ('cancelled', 'Cancelled')
    ], string='Preparation Status', default='waiting', tracking=True, group_expand='_read_group_preparation_status')

    @api.model
    def _read_group_preparation_status(self, stages, domain, order):
        return ['waiting', 'preparing', 'ready', 'served']

    color = fields.Integer(string='Color', default=0)
    preparation_time_start = fields.Datetime(string='Start Time')
    preparation_time_end = fields.Datetime(string='Ready Time')
    cooking_time = fields.Integer(string='Cooking Time (min)', compute='_compute_cooking_time', store=True)
    
    table_id = fields.Many2one('restaurant.table', related='order_id.table_id', string='Table', store=True)
    floor_id = fields.Many2one('restaurant.floor', related='order_id.table_id.floor_id', string='Floor', store=True)
    order_source = fields.Selection([
        ('walk_in',    'Walk-In (Standard POS)'),
        ('phone',      'Telephone Order'),
        ('online',     'Online / eCommerce'),
        ('whatsapp',   'WhatsApp'),
        ('social_media', 'Social Media'),
        ('platform',   'Third-Party Platform'),
        ('kiosk',      'Self-Order Kiosk'),
        ('qr',         'QR Table Order'),
    ], related='order_id.order_source', string='Order Source', store=True)
    fulfilment_type = fields.Selection([
        ('dine_in',  'Dine-In'),
        ('pickup',   'Pickup'),
        ('delivery', 'Delivery'),
    ], related='order_id.fulfilment_type', string='Fulfilment Type', store=True)

    @api.depends('preparation_time_start', 'preparation_time_end')
    def _compute_cooking_time(self):
        for line in self:
            if line.preparation_time_start and line.preparation_time_end:
                diff = line.preparation_time_end - line.preparation_time_start
                line.cooking_time = int(diff.total_seconds() / 60)
            else:
                line.cooking_time = 0

    def _notify_pos(self):
        """Send notification to POS when order line status changes"""
        _logger.info("=== _notify_pos called for %s lines ===" % len(self))
        for line in self:
            _logger.info(f"Processing line {line.id}, order: {line.order_id.name}, config: {line.order_id.config_id}")
            if line.order_id.config_id:
                channel_name = "pos_config_Channel_%s" % line.order_id.config_id.id
                payload = {
                    'line_id': line.id,
                    'order_id': line.order_id.id,
                    'status': line.preparation_status,
                    'status_label': dict(self._fields['preparation_status']._description_selection(self.env)).get(line.preparation_status),
                    'order_uid': line.order_id.pos_reference,
                    'product_id': line.product_id.id,
                    'qty': line.qty,
                }
                _logger.info(f"KDS NOTIFICATION: Sending update for Line {line.id} Status {line.preparation_status} to {channel_name}")
                self.env['bus.bus']._sendone(channel_name, 'kds_update', payload)
            else:
                _logger.warning(f"Line {line.id} has no config_id - cannot send notification")

    def _notify_kds(self):
        """Send notification to KDS backend when new order lines are created"""
        _logger.info("=== _notify_kds called for %s lines ===" % len(self))
        for line in self:
            # Only notify for kitchen items
            if line.product_id.is_kitchen_item and line.product_id.name != 'Water':
                # Send to global KDS channel
                kds_channel = "kds_channel"
                payload = {
                    'line_id': line.id,
                    'order_id': line.order_id.id,
                    'product_name': line.product_id.name,
                    'qty': line.qty,
                    'table_name': line.table_id.name if line.table_id else '',
                    'floor_name': line.floor_id.name if line.floor_id else '',
                    'customer_note': line.customer_note or '',
                    'preparation_status': line.preparation_status,
                    'create_date': line.create_date.isoformat() if line.create_date else '',
                }
                _logger.info(f"KDS BACKEND NOTIFICATION: New order line {line.id} for {line.product_id.name}")
                self.env['bus.bus']._sendone(kds_channel, 'kds_new_order', payload)

    @api.model_create_multi
    def create(self, vals_list):
        """Override create to send notifications to KDS when new orders are added"""
        lines = super(PosOrderLine, self).create(vals_list)
        # Skip KDS notification if flagged (online orders wait for cashier confirmation)
        if not self.env.context.get('skip_kds_notify'):
            # Send notification to KDS backend only for new items (waiting status)
            waiting_lines = lines.filtered(lambda l: l.preparation_status == 'waiting')
            if waiting_lines:
                waiting_lines._notify_kds()
        return lines

    def write(self, vals):
        """Prevent resetting 'served' or 'ready' status back to 'waiting' during POS sync"""
        if 'preparation_status' in vals and vals['preparation_status'] == 'waiting':
            for line in self:
                if line.preparation_status in ['served', 'ready', 'preparing']:
                    # Keep the current status if it's already being processed or served
                    actual_vals = vals.copy()
                    actual_vals['preparation_status'] = line.preparation_status
                    super(PosOrderLine, line).write(actual_vals)
            
            # Handle lines that are actually allowed to be updated to waiting
            remaining_lines = self.filtered(lambda l: l.preparation_status not in ['served', 'ready', 'preparing'])
            if remaining_lines:
                res = super(PosOrderLine, remaining_lines).write(vals)
                # If quantity changed or status is waiting, notify KDS to refresh
                remaining_lines._notify_kds()
                return res
            return True

        res = super(PosOrderLine, self).write(vals)
        # Notify KDS for quantity changes on active items
        if 'qty' in vals:
            active_lines = self.filtered(lambda l: l.preparation_status in ['waiting', 'preparing'])
            if active_lines:
                active_lines._notify_kds()
        return res

    def action_start_preparing(self):
        self.write({
            'preparation_status': 'preparing',
            'preparation_time_start': fields.Datetime.now()
        })
        self._notify_pos()

    def action_mark_ready(self):
        self.write({
            'preparation_status': 'ready',
            'preparation_time_end': fields.Datetime.now()
        })
        self._notify_pos()

    def action_mark_served(self):
        self.write({
            'preparation_status': 'served'
        })
        self._notify_pos()

class PosOrder(models.Model):
    _inherit = 'pos.order'

    order_source = fields.Selection([
        ('walk_in',    'Walk-In (Standard POS)'),
        ('phone',      'Telephone Order'),
        ('online',     'Online / eCommerce'),
        ('whatsapp',   'WhatsApp'),
        ('social_media', 'Social Media'),
        ('platform',   'Third-Party Platform'),
        ('kiosk',      'Self-Order Kiosk'),
        ('qr',         'QR Table Order'),
    ], string='Order Source', default='walk_in')

    fulfilment_type = fields.Selection([
        ('dine_in',  'Dine-In'),
        ('pickup',   'Pickup'),
        ('delivery', 'Delivery'),
    ], string='Fulfilment Type', default='dine_in')

    @api.model
    def _prepare_order_line_vals(self, line, session_id=None):
        res = super()._prepare_order_line_vals(line, session_id)
        if 'preparation_status' in line:
            res['preparation_status'] = line['preparation_status']
        return res
