from collections import defaultdict

from odoo import _, models
from odoo.exceptions import UserError
from odoo.tools.float_utils import float_is_zero


class StockMove(models.Model):
    _inherit = "stock.move"

    def _action_confirm(self, merge=True, merge_into=False):
        if self.origin_returned_move_id:
            subcontract_details_per_picking = defaultdict(list)
            move_to_not_merge = self.env["stock.move"]
            for move in self:
                if (
                    move.location_dest_id.usage == "supplier"
                    and move.location_id
                    == self.picking_id.picking_type_id.default_location_src_id
                ):
                    continue
                if move.move_orig_ids.production_id:
                    continue
                bom = move._get_subcontract_bom()
                if not bom:
                    continue
                if (
                    float_is_zero(
                        move.product_qty, precision_rounding=move.product_uom.rounding
                    )
                    and move.picking_id.immediate_transfer is True
                ):
                    raise UserError(_("To subcontract, use a planned transfer."))
                subcontract_details_per_picking[move.picking_id].append((move, bom))
                move_to_not_merge |= move
            for picking, subcontract_details in subcontract_details_per_picking.items():
                picking._subcontracted_produce_unbuild(subcontract_details)

            # We avoid merging move due to complication with stock.rule.
            res = super(StockMove, move_to_not_merge)._action_confirm(merge=False)
            res |= super(StockMove, self - move_to_not_merge)._action_confirm(
                merge=merge, merge_into=merge_into
            )
            if subcontract_details_per_picking:
                self.env["stock.picking"].concat(
                    *list(subcontract_details_per_picking.keys())
                ).action_assign()
            return res
        result = super(StockMove, self)._action_confirm(
            merge=merge, merge_into=merge_into
        )
        return result
