from odoo import fields, models, api, _
from odoo.exceptions import UserError
from odoo.osv import expression


class AccountAccount(models.Model):
    _inherit = "account.account"
    _parent_name = "parent_id"
    _parent_store = True
    company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True,
        default=lambda self: self.env.company)
    account_type = fields.Selection(
        selection_add=[('view', 'View')],
        ondelete={'view': 'cascade'}
    )
    automticAccountsCodes = fields.Boolean(
        related='company_id.automticAccountsCodes',
    )
    internal_group = fields.Selection(
        selection_add=[('view', 'View')],
        ondelete={'view': lambda recs: recs.write({'internal_group': 'off'})}
    )

    parent_id = fields.Many2one(
        comodel_name='account.account',
        string='Parent Account',
        domain="[('account_type', '=', 'view')]"
    )

    parent_path = fields.Char(index=True)

    child_ids = fields.One2many(
        'account.account', 'parent_id', 'Child Accounts'
    )

    auto_code = fields.Char(
        compute='_get_code', default='0',
        store=True, size=64, index=True
    )

    level = fields.Integer(
        compute="_get_level", store=True, string='Level'
    )


    @api.depends('code', 'account_type')
    def _compute_account_type(self):

        view_accounts = self.filtered(lambda acc: acc.account_type == 'view')

        other_accounts = self - view_accounts
        if other_accounts:
            super(AccountAccount, other_accounts)._compute_account_type()

    @api.depends('account_type')
    def _compute_internal_group(self):
        """Override to handle view type"""
        for record in self:
            if record.account_type == 'view':
                record.internal_group = 'view'
            else:
                super(AccountAccount, record)._compute_internal_group()

    @api.model
    def _name_search(self, name, domain=None, operator='ilike', limit=100, order=None):
        if domain is None:
            domain = []

        # استبدال internal_type بـ account_type في Odoo 18
        domain = self._replace_internal_type_domain(domain)

        if not self.env.context.get('show_view') and not self.env.context.get('import_file'):
            domain += [('account_type', '!=', 'view')]

        return super()._name_search(name, domain, operator, limit, order)

    def _replace_internal_type_domain(self, domain):
        """استبدال internal_type بـ account_type"""
        new_domain = []
        for condition in domain:
            if isinstance(condition, (list, tuple)) and len(condition) >= 3:
                if condition[0] in ('internal_type', 'type') and condition[2] == 'view':
                    new_domain.append(('account_type', condition[1], 'view'))
                elif condition[0] in ('internal_type', 'type') and condition[1] == '!=':
                    new_domain.append(('account_type', '!=', 'view'))
                else:
                    new_domain.append(condition)
            else:
                new_domain.append(condition)
        return new_domain

    @api.depends('parent_id')
    def _get_level(self):
        for rec in self:
            level = 0
            if rec.parent_id:
                level = rec.parent_id.level + 1
                if rec.company_id.useFiexedTree and rec.company_id.chart_account_length:
                    if level > rec.company_id.chart_account_length:
                        raise UserError(
                            _('This account level is greater than the chart of account length.'))
            rec.level = level

    @api.depends('parent_id', 'code', 'parent_id.code')
    def _get_code(self):
        for rec in self:
            if not rec.company_id.automticAccountsCodes and rec.code:
                rec.auto_code = rec.code
                continue

            code = str(0)
            if rec.parent_id:
                default_padding = self.env.company.chart_account_padding
                if rec.account_type == 'view':
                    default_padding = False

                parent_code = rec.parent_id.code or ''
                parent_code = int(parent_code) != 0 and str(parent_code) or ''

                siblings = self.search([
                    ('parent_id', '=', rec.parent_id.id),
                    ('id', '!=', rec.id)
                ])

                max_siblings_code = False
                if siblings:
                    sibling_codes = [int(s.code) for s in siblings if s.code and s.code.isdigit()]
                    if sibling_codes:
                        max_siblings_code = max(sibling_codes)

                if not max_siblings_code:
                    code = parent_code + str(1).zfill(default_padding or 0)
                else:
                    code = str(max_siblings_code + 1)

                rec.auto_code = code
            else:
                rec.auto_code = rec.code or '0'

    @api.model
    def search_panel_select_range(self, field_name, **kwargs):

        if field_name != 'parent_id':
            return super().search_panel_select_range(field_name, **kwargs)


        enable_counters = kwargs.get('enable_counters', False)
        search_domain = kwargs.get('search_domain', [])


        all_view_accounts = self.search([('account_type', '=', 'view')], order='code')

        count_by_parent = {}
        if enable_counters:
            all_accounts = self.search(search_domain)

            for account in all_accounts:
                if account.parent_id:
                    parent_id = account.parent_id.id
                    count_by_parent[parent_id] = count_by_parent.get(parent_id, 0) + 1

                    ancestor = account.parent_id.parent_id
                    while ancestor:
                        count_by_parent[ancestor.id] = count_by_parent.get(ancestor.id, 0) + 1
                        ancestor = ancestor.parent_id


        values = []
        for parent in all_view_accounts:
            value = {
                'id': parent.id,
                'display_name': f"{parent.code} {parent.name}" if parent.code else parent.name,
                'parent_id': parent.parent_id.id if parent.parent_id else False,
            }

            if enable_counters:
                value['__count'] = count_by_parent.get(parent.id, 0)

            values.append(value)


        result = {
            'parent_field': 'parent_id',
            'values': values,
        }

        return result
