# Copyright 2025 - Today Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo import api
from odoo import fields
from odoo import models


class ProductProduct(models.Model):
    _inherit = "product.product"

    group_order_ids = fields.Many2many(
        "group.order",
        "group_order_product_rel",
        "product_id",
        "order_id",
        string="Group Orders",
        readonly=True,
        help="Group orders where this product is available",
    )

    is_out_of_stock = fields.Boolean(
        compute="_compute_stock_ribbons",
        store=False,
        help="True if virtual_available <= 0",
    )

    is_low_stock = fields.Boolean(
        compute="_compute_stock_ribbons",
        store=False,
        help="True if 0 < virtual_available <= threshold",
    )

    dynamic_ribbon_id = fields.Many2one(
        "product.ribbon",
        string="Dynamic Stock Ribbon",
        compute="_compute_stock_ribbons",
        store=False,
        help="Auto-assigned ribbon based on stock levels",
    )

    @api.depends("virtual_available", "type", "allow_out_of_stock_order")
    def _compute_stock_ribbons(self):
        """Compute stock-based ribbons dynamically.

        A product is considered out of stock only when:
        - It is a storable product (type='consu')
        - virtual_available <= 0
        - allow_out_of_stock_order is False

        If allow_out_of_stock_order is True, the product can always be sold
        regardless of stock level.
        """
        # Obtener ribbons (usar sudo para evitar permisos)
        out_of_stock_ribbon = self.env.ref(
            "website_sale_aplicoop.out_of_stock_ribbon", raise_if_not_found=False
        )
        low_stock_ribbon = self.env.ref(
            "website_sale_aplicoop.low_stock_ribbon", raise_if_not_found=False
        )

        # Obtener threshold de configuración
        threshold = float(
            self.env["ir.config_parameter"]
            .sudo()
            .get_param("website_sale_aplicoop.low_stock_threshold", default="5.0")
        )

        for product in self:
            # Solo para productos almacenables (type='consu' en Odoo 18)
            if product.type != "consu":
                product.is_out_of_stock = False
                product.is_low_stock = False
                product.dynamic_ribbon_id = False
                continue

            qty = product.virtual_available

            # Check if product allows selling when out of stock
            # If True, never block add-to-cart based on stock
            allow_oos = getattr(product, "allow_out_of_stock_order", True)

            if qty <= 0 and not allow_oos:
                # Out of stock and NOT allowed to sell without stock
                product.is_out_of_stock = True
                product.is_low_stock = False
                product.dynamic_ribbon_id = out_of_stock_ribbon
            elif qty <= 0 and allow_oos:
                # Out of stock but allowed to sell anyway
                product.is_out_of_stock = False
                product.is_low_stock = False
                product.dynamic_ribbon_id = False
            elif qty <= threshold:
                product.is_out_of_stock = False
                product.is_low_stock = True
                product.dynamic_ribbon_id = low_stock_ribbon
            else:
                product.is_out_of_stock = False
                product.is_low_stock = False
                product.dynamic_ribbon_id = False

    @api.model
    def _get_products_for_group_order(self, order_id):
        """Backward-compatible delegation to `group.order` discovery.

        The canonical discovery logic lives on `group.order` to keep
        responsibilities together. Keep this wrapper so existing callers
        on `product.product` keep working.
        """
        order = self.env["group.order"].browse(order_id)
        if not order.exists():
            return self.browse()
        return order._get_products_for_group_order(order.id)


class ProductTemplate(models.Model):
    _inherit = "product.template"

    group_order_ids = fields.Many2many(
        "group.order",
        compute="_compute_group_order_ids",
        string="Consumer Group Orders",
        readonly=True,
        help="Consumer group orders where variants of this product are available",
    )

    @api.depends("product_variant_ids.group_order_ids")
    def _compute_group_order_ids(self):
        for template in self:
            variants = template.product_variant_ids
            template.group_order_ids = variants.mapped("group_order_ids")
