# Copyright (C) 2020: Criptomart (https://criptomart.net)
# @author Santi Noreña (<santi@criptomart.net>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import logging

from odoo import api
from odoo import models
from odoo.tools import float_compare

_logger = logging.getLogger(__name__)

# Fields whose change can alter the net purchase price of the main vendor.
PRICE_FIELDS = {
    "price",
    "discount",
    "discount1",
    "discount2",
    "discount3",
    "sequence",
    "partner_id",
    "product_id",
    "product_tmpl_id",
    "company_id",
}


class ProductSupplierInfo(models.Model):
    _inherit = "product.supplierinfo"

    @api.model_create_multi
    def create(self, vals_list):
        records = super().create(vals_list)
        records._sync_last_purchase_price_received()
        return records

    def write(self, vals):
        res = super().write(vals)
        if PRICE_FIELDS & set(vals):
            self._sync_last_purchase_price_received()
        return res

    def _sync_last_purchase_price_received(self):
        """Keep last_purchase_price_received in sync with the main vendor's
        supplierinfo price, applying its discounts according to each variant's
        last_purchase_price_compute_type. The actual sale price is only refreshed
        in last_purchase_price_updated/list_price_theoritical; lst_price is left
        untouched until the user confirms with the update button (same behaviour
        as a stock receipt)."""
        if self.env.context.get("skip_last_purchase_price_sync"):
            return
        products = self.env["product.product"]
        for seller in self:
            if seller.product_id:
                products |= seller.product_id
            elif seller.product_tmpl_id:
                products |= seller.product_tmpl_id.product_variant_ids
        for product in products.exists():
            if product.last_purchase_price_compute_type == "manual_update":
                continue
            seller = product._get_main_supplierinfo()
            if not seller:
                continue
            net_price = product._compute_supplierinfo_net_price(seller)
            if (
                float_compare(
                    product.last_purchase_price_received,
                    net_price,
                    precision_digits=2,
                )
                != 0
            ):
                _logger.info(
                    "[PRICE] Product %s [%s]: last_purchase_price_received synced "
                    "from supplierinfo %.2f -> %.2f (compute_type: %s)",
                    product.default_code or product.name,
                    product.id,
                    product.last_purchase_price_received,
                    net_price,
                    product.last_purchase_price_compute_type,
                )
                product.write({"last_purchase_price_received": net_price})
                product._recompute_theoritical_price_safe()
