# Copyright 2014 Ignacio Ibeas <ignacio@acysos.com>
# Copyright 2020 Santi Noreña <santi@criptomart.net>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging

from odoo import api, models, fields, _

_logger = logging.getLogger(__name__)


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

    balance_code_ids = fields.One2many(
        comodel_name="product.balance.code",
        inverse_name="product_id",
        string="Balance Codes",
    )
    balance_type = fields.Selection(
        [("price", "Price"), ("weight", "Weight")], "Type Balance"
    )
    balance_name = fields.Char(string="Code", readonly=False, related="default_code")
    balance_nomenclature = fields.Many2one(
        comodel_name="barcode.nomenclature", string="Nomenclature"
    )
    balance_rule = fields.Many2one(comodel_name="barcode.rule", string="Rule")
    not_weighed = fields.Boolean("Not weighed", required=False)

    tare = fields.Integer(
        string="Tare",
        help="Tare in grams of the product. Maximum 5 digits",
        default=0,
        readonly=False,
    )

    @api.onchange("balance_name", "balance_rule")
    def get_ean_code(self):
        barcode = False
        for product in self:
            if self.balance_rule and self.balance_name:
                ean = product.balance_rule.pattern[:1]
                ean += product.balance_name
                ean += "00000"
                code = list(ean)
                oddsum = evensum = total = control_digit = 0
                for i in range(len(code)):
                    if i % 2 == 0:
                        # even calculation
                        evensum += int(code[i])
                    else:
                        # odd calculation
                        oddsum += int(code[i])
                total = oddsum * 3 + evensum
                control_digit = int((10 - total % 10) % 10)
                barcode = ean + str(control_digit)
                product.barcode = barcode

    def update_codes(self):
        # _logger.debug("updating codes")
        for product in self:
            if len(product.balance_code_ids) > 0:
                for code in product.balance_code_ids:
                    if len(code.shop_id.balance_ids) > 0:
                        code.remove_balance()
                        code.update_balance()


class product_balance_code(models.Model):
    _name = "product.balance.code"
    _description = "Product Balance Code"

    def add_balance(self):
        for code in self:
            for balance in code.shop_id.balance_ids:
                if balance.network:
                    balance_con = getattr(self, "add_balance_" + balance.model_id.code)
                    balance_con(code, balance)

        return True

    def update_balance(self):
        for code in self:
            # _logger.debug("code : " + code )
            for balance in code.shop_id.balance_ids:
                _logger.debug("balance con ")
                if balance.network:
                    # _logger.debug("balance con " + balance)
                    balance_con = getattr(
                        self, "update_balance_" + balance.model_id.code
                    )
                    # _logger.debug('update_balance_' + balance.model_id.code))
                    balance_con(code, balance)
        return True

    def remove_balance(self):
        for code in self:
            for balance in code.shop_id.balance_ids:
                if balance.network:
                    balance_con = getattr(
                        self, "remove_balance_" + balance.model_id.code
                    )
                    balance_con(code, balance)
        return True

    product_id = fields.Many2one(
        comodel_name="product.template", string="Product", required=True
    )
    key = fields.Char(string="Key")
    table = fields.Char(string="Table")
    shop_id = fields.Many2one(comodel_name="balance.sale.shop", string="Shop")


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

    @api.onchange("balance_name", "balance_rule")
    def get_ean_code(self):
        barcode = False
        for product in self:
            if self.balance_rule and self.balance_name:
                ean = product.balance_rule.pattern[:1]
                ean += product.balance_name
                ean += "00000"
                code = list(ean)

                oddsum = evensum = total = control_digit = 0
                for i in range(len(code)):
                    if i % 2 == 0:
                        # even calculation
                        evensum += int(code[i])
                    else:
                        # odd calculation
                        oddsum += int(code[i])
                total = oddsum * 3 + evensum

                control_digit = int((10 - total % 10) % 10)
                barcode = ean + str(control_digit)
                product.barcode = barcode

    def unlink(self):
        self.balance_code_ids.remove_balance()
        res = super(ProductProduct, self).unlink()
        return res

    def update_codes(self):
        for product in self:
            if len(product.balance_code_ids) > 0:
                for code in product.balance_code_ids:
                    if len(code.shop_id.balance_ids) > 0:
                        code.remove_balance()
