from odoo import _, api, fields, models


class ProductValue(models.Model):
    """ This model represents the history of manual update of a value.
    The potential update could be:
        - Modification of the product standard price
        - Modification of the lot standard price
        - Modification of the move value
    In case of modification of:
        - standard price, value contains the new standard price (by unit).
        - a move value: value contains the global value of the move.
    """
    _name = 'product.value'
    _description = 'Product Value'

    product_id = fields.Many2one('product.product', string='Product')
    lot_id = fields.Many2one('stock.lot', string='Lot')
    move_id = fields.Many2one('stock.move', string='Move')

    value = fields.Monetary(string='Value', currency_field='currency_id', required=True)
    company_id = fields.Many2one(
        'res.company', string='Company', compute='_compute_company_id',
        store=True, required=True, precompute=True, readonly=False)
    currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
    date = fields.Datetime(string='Date', default=fields.Datetime.now, required=True)
    user_id = fields.Many2one('res.users', string='User', default=lambda self: self.env.user, required=True)

    description = fields.Char(string='Description')

    # User Display Fields
    current_value = fields.Monetary(
        string='Current Value', currency_field='currency_id',
        related='move_id.value')
    current_value_details = fields.Char(string='Current Value Details', compute="_compute_current_value_details")
    current_value_description = fields.Text(string='Current Value Description', compute="_compute_value_description")
    computed_value_description = fields.Text(string='Computed Value Description', compute="_compute_value_description")

    @api.depends('move_id', 'lot_id', 'product_id')
    def _compute_company_id(self):
        for product_value in self:
            if product_value.move_id:
                product_value.company_id = product_value.move_id.company_id
            elif product_value.lot_id:
                product_value.company_id = product_value.lot_id.company_id
            elif product_value.product_id:
                product_value.company_id = product_value.product_id.company_id
            else:
                product_value.company_id = self.env.company

    def _compute_current_value_details(self):
        for product_value in self:
            if not (product_value.move_id and product_value.move_id.quantity):
                product_value.current_value_details = False
                continue
            move = product_value.move_id
            quantity = move.quantity
            uom = move.product_uom.name
            price_unit = move.value / move.quantity
            product_value.current_value_details = _("For %(quantity)s %(uom)s (%(price_unit)s per %(uom)s)",
                quantity=quantity, uom=uom, price_unit=price_unit)

    def _compute_value_description(self):
        for product_value in self:
            if not product_value.move_id:
                product_value.current_value_description = False
                product_value.computed_value_description = False
                continue
            product_value.current_value_description = product_value.move_id.value_justification
            product_value.computed_value_description = product_value.move_id.value_computed_justification

    @api.model_create_multi
    def create(self, vals_list):
        lot_ids = set()
        product_ids = set()
        move_ids = set()

        for vals in vals_list:
            if vals.get('move_id'):
                move_ids.add(vals['move_id'])
            elif vals.get('lot_id'):
                lot_ids.add(vals['lot_id'])
            else:
                product_ids.add(vals['product_id'])
        if lot_ids:
            move_ids.update(self.env['stock.move.line'].search([('lot_id', 'in', lot_ids)]).move_id.ids)
        products = self.env['product.product'].browse(product_ids)
        if products:
            moves_by_product = products._get_remaining_moves()
            for qty_by_move in moves_by_product.values():
                move_ids.update(self.env['stock.move'].concat(*qty_by_move.keys()).ids)

        res = super().create(vals_list)
        if move_ids:
            self.env['stock.move'].browse(move_ids)._set_value()
        return res
