from odoo import api, fields, models, _


class ExpenseChangeWizard(models.TransientModel):
    _inherit = 'hr.expense.change'

    analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account')
    analytic_account_warning = fields.Char(string='Analytic Account Warning', compute='_compute_analytic_warning')

    @api.model
    def default_get(self, fields):
        rec = super(ExpenseChangeWizard, self).default_get(fields)
        expense = self.env['hr.expense'].browse(rec['expense_id'])
        rec.update({
            'analytic_account_id': expense.analytic_account_id.id,
        })
        return rec

    @api.onchange('expense_id', 'analytic_account_id')
    def _compute_analytic_warning(self):
        self.ensure_one()
        expenses = self._find_expenses_to_write_analytic(self.expense_id.analytic_account_id.id)
        if len(expenses) <= 1:
            self.analytic_account_warning = ''
        else:
            other_expenses = expenses - self.expense_id
            self.analytic_account_warning = '%d other expenses will be changed. (%s)' % \
                                            (len(other_expenses), ', '.join(other_expenses.mapped('name')))



    def affect_change(self):
        old_analytic_id = self.expense_id.analytic_account_id.id
        res = super(ExpenseChangeWizard, self).affect_change()
        self._affect_analytic_change(old_analytic_id)
        return res

    def _find_expenses_to_write_analytic(self, old_analytic_id):
        if self.analytic_account_id.id == old_analytic_id:
            return []
        # Essentially, if you have a move, you must write all related expenses and lines.
        if not self.expense_id.sheet_id.account_move_id:
            return self.expense_id
        return self.expense_id.sheet_id.expense_line_ids\
                   .filtered(lambda l: l.analytic_account_id.id == old_analytic_id)

    def _affect_analytic_change(self, old_analytic_id):
        expenses_to_affect = self._find_expenses_to_write_analytic(old_analytic_id)
        if expenses_to_affect:
            prev_state = self.expense_id.sheet_id.state
            self.expense_id.sheet_id.write({'state': 'draft'})
            expenses_to_affect.write({'analytic_account_id': self.analytic_account_id.id})

            lines_to_affect = self.expense_id.sheet_id.account_move_id \
                .line_ids.filtered(lambda l: l.analytic_account_id.id == old_analytic_id and l.debit)
            lines_to_affect.write({'analytic_account_id': self.analytic_account_id.id})
            lines_to_affect.create_analytic_lines()
            self.expense_id.sheet_id.write({'state': prev_state})
