from odoo import api, fields, models
from odoo.exceptions import UserError


class AccountMoveTemplateWizardLine(models.TransientModel):
    _name = 'account.move.template.wizard.line'
    _description = 'Черновая строка визарда шаблона'

    wizard_id = fields.Many2one(
        comodel_name='account.move.template.wizard',
        required=True,
        ondelete='cascade',
    )
    account_id = fields.Many2one(
        comodel_name='account.account',
        string='Счёт',
        required=True,
    )
    move_type = fields.Selection(
        selection=[('debit', 'Дебет'), ('credit', 'Кредит')],
        string='Сторона',
        required=True,
    )
    amount = fields.Float(
        string='Сумма',
        digits=(16, 2),
    )


class AccountMoveTemplateWizard(models.TransientModel):
    _name = 'account.move.template.wizard'
    _description = 'Визард создания проводки по шаблону'

    res_model = fields.Char(string='Модель документа', required=True)
    res_id = fields.Integer(string='ID документа', required=True)
    template_id = fields.Many2one(
        comodel_name='account.move.template',
        string='Шаблон',
    )
    amount = fields.Float(
        string='Базовая сумма',
        digits=(16, 2),
    )
    draft_line_ids = fields.One2many(
        comodel_name='account.move.template.wizard.line',
        inverse_name='wizard_id',
        string='Черновые строки',
    )

    @api.onchange('template_id', 'amount')
    def _onchange_compute_draft_lines(self):
        """Recompute draft lines when template or amount changes."""
        self.draft_line_ids = [(5, 0, 0)]  # clear existing
        if not self.template_id or not self.amount:
            return
        lines = []
        for tpl_line in self.template_id.line_ids:
            line_amount = self.amount * tpl_line.percent / 100.0
            lines.append((0, 0, {
                'account_id': tpl_line.account_id.id,
                'move_type': tpl_line.move_type,
                'amount': line_amount,
            }))
        self.draft_line_ids = lines

    def action_post(self):
        """Create account.move from draft lines and link to source document."""
        self.ensure_one()
        if not self.template_id or not self.amount:
            raise UserError('Необходимо выбрать шаблон и указать базовую сумму.')

        try:
            # Build move lines
            move_line_vals = []
            for draft_line in self.draft_line_ids:
                if draft_line.move_type == 'debit':
                    debit = draft_line.amount
                    credit = 0.0
                else:
                    debit = 0.0
                    credit = draft_line.amount
                move_line_vals.append((0, 0, {
                    'account_id': draft_line.account_id.id,
                    'debit': debit,
                    'credit': credit,
                    'name': self.template_id.name,
                }))

            # Create the move
            move = self.env['account.move'].create({
                'move_type': 'entry',
                'state': 'draft',
                'line_ids': move_line_vals,
            })

            # Link move to source document via move_ids
            source_record = self.env[self.res_model].browse(self.res_id)
            source_record.move_ids = [(4, move.id)]

        except Exception as e:
            raise UserError(f'Ошибка при создании проводки: {str(e)}') from e

        return {'type': 'ir.actions.act_window_close'}
