# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)

import logging
from odoo import models, fields, api

_logger = logging.getLogger(__name__)


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

    x_fi_price_offset = fields.Float(
        string='Price Offset',
        default=0.0,
        help='Margin-calculated price adjustment, kept separate from '
             'manual attribute price extras.')
    x_fi_variant_margin_pct = fields.Float(
        string='Margin (%)',
        compute='_compute_variant_margin',
        inverse='_inverse_variant_margin',
        store=True, readonly=False,
        help='Profit margin based on (cost + shipping + extra cost). '
             'Extra Price from attributes is added on top, outside margin.')
    x_fi_margin_override = fields.Boolean(
        string='Margin Override',
        default=False,
        help='When set, the template "Apply Margin" button '
             'and automatic propagation skip this variant.')
    x_fi_variant_profit = fields.Float(
        string='Profit',
        compute='_compute_variant_profit',
        help='Total sale price minus total cost.')
    x_fi_shipping_cost = fields.Float(
        string='Shipping Cost',
        default=0.0,
        help='Per-unit shipping cost.')
    x_fi_cost_extra = fields.Float(
        string='Attribute Extra Cost',
        compute='_compute_cost_extra', store=True,
        help='Sum of Extra Cost from all attribute values for this variant.')

    @api.depends('product_template_attribute_value_ids.x_fi_extra_cost')
    def _compute_cost_extra(self):
        for product in self:
            product.x_fi_cost_extra = sum(
                product.product_template_attribute_value_ids.mapped(
                    'x_fi_extra_cost'))

    # ── Include price offset in pricelist / SO pricing ──

    def _get_attributes_extra_price(self):
        extra = super()._get_attributes_extra_price()
        return extra + (self.x_fi_price_offset or 0.0)

    # ── Override lst_price to include our price offset ──

    @api.depends('list_price', 'price_extra', 'x_fi_price_offset')
    @api.depends_context('uom')
    def _compute_product_lst_price(self):
        to_uom = None
        if 'uom' in self._context:
            to_uom = self.env['uom.uom'].browse(self._context['uom'])
        for product in self:
            if to_uom:
                list_price = product.uom_id._compute_price(
                    product.list_price, to_uom)
            else:
                list_price = product.list_price
            product.lst_price = (
                list_price
                + product.price_extra
                + (product.x_fi_price_offset or 0.0))

    def _set_product_lst_price(self):
        for product in self:
            if self._context.get('uom'):
                value = (
                    float(product.lst_price) * product.uom_id.factor
                    / self.env['uom.uom'].browse(
                        self._context['uom']).factor)
            else:
                value = product.lst_price
            value -= product.price_extra
            value -= (product.x_fi_price_offset or 0.0)
            product.write({'list_price': value})

    # ── Margin / Profit ──
    # effective_cost  = standard_price + shipping + extra_cost
    # base_sale_price = list_price + x_fi_price_offset  (margin applies here)
    # final_price     = base_sale_price + price_extra    (surcharge on top)
    # margin          = (base_sale_price - effective_cost) / base_sale_price

    @api.depends('list_price', 'price_extra', 'x_fi_price_offset',
                 'standard_price', 'x_fi_shipping_cost', 'x_fi_cost_extra')
    def _compute_variant_margin(self):
        for var in self:
            base = var.list_price + (var.x_fi_price_offset or 0.0)
            eff = (var.standard_price
                   + (var.x_fi_shipping_cost or 0.0)
                   + (var.x_fi_cost_extra or 0.0))
            if base > 0 and eff > 0:
                var.x_fi_variant_margin_pct = round(
                    ((base - eff) / base) * 100, 2)
            else:
                var.x_fi_variant_margin_pct = 0.0

    def _inverse_variant_margin(self):
        for var in self:
            margin = var.x_fi_variant_margin_pct or 0.0
            eff = (var.standard_price
                   + (var.x_fi_shipping_cost or 0.0)
                   + (var.x_fi_cost_extra or 0.0))
            if eff > 0 and 0 < margin < 100:
                base = round(eff / (1 - margin / 100), 2)
                var.x_fi_price_offset = round(base - var.list_price, 2)

    @api.depends('list_price', 'price_extra', 'x_fi_price_offset',
                 'standard_price', 'x_fi_shipping_cost', 'x_fi_cost_extra')
    def _compute_variant_profit(self):
        for var in self:
            lst = (var.list_price
                   + var.price_extra
                   + (var.x_fi_price_offset or 0.0))
            eff = (var.standard_price
                   + (var.x_fi_shipping_cost or 0.0)
                   + (var.x_fi_cost_extra or 0.0))
            var.x_fi_variant_profit = lst - eff

    # ── Onchange handlers ──

    @api.onchange('x_fi_variant_margin_pct')
    def _onchange_variant_margin(self):
        for var in self:
            margin = var.x_fi_variant_margin_pct or 0.0
            eff = (var.standard_price
                   + (var.x_fi_shipping_cost or 0.0)
                   + (var.x_fi_cost_extra or 0.0))
            if eff > 0 and 0 < margin < 100:
                base = round(eff / (1 - margin / 100), 2)
                var.x_fi_price_offset = round(base - var.list_price, 2)

    @api.onchange('standard_price', 'x_fi_shipping_cost')
    def _onchange_variant_cost(self):
        """When cost or shipping changes, recalculate price to keep margin."""
        for var in self:
            margin = var.x_fi_variant_margin_pct or 0.0
            eff = (var.standard_price
                   + (var.x_fi_shipping_cost or 0.0)
                   + (var.x_fi_cost_extra or 0.0))
            if eff > 0 and 0 < margin < 100:
                base = round(eff / (1 - margin / 100), 2)
                var.x_fi_price_offset = round(base - var.list_price, 2)

    def _apply_margin_to_variant(self, margin_pct):
        """Set this variant's price offset to achieve the given margin."""
        self.ensure_one()
        eff = (self.standard_price
               + (self.x_fi_shipping_cost or 0.0)
               + (self.x_fi_cost_extra or 0.0))
        if eff <= 0 or margin_pct <= 0 or margin_pct >= 100:
            return
        base = round(eff / (1 - margin_pct / 100), 2)
        new_offset = round(base - self.list_price, 2)
        if abs((self.x_fi_price_offset or 0.0) - new_offset) > 0.001:
            self.x_fi_price_offset = new_offset
