# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
from odoo.addons.mail.wizard.mail_compose_message import _reopen
from odoo.exceptions import UserError
from odoo.tools.misc import get_lang


class AccountInvoiceSend(models.TransientModel):
    _name = 'account.invoice.send'
    _inherits = {'mail.compose.message':'composer_id'}
    _description = 'Account Invoice Send'

    is_email = fields.Boolean('Email', default=lambda self: self.env.company.invoice_is_email)
    invoice_without_email = fields.Text(compute='_compute_invoice_without_email', string='invoice(s) that will not be sent')
    is_print = fields.Boolean('Print', default=lambda self: self.env.company.invoice_is_print)
    printed = fields.Boolean('Is Printed', default=False)
    invoice_ids = fields.Many2many('account.move', 'account_move_account_invoice_send_rel', string='Invoices')
    composer_id = fields.Many2one('mail.compose.message', string='Composer', required=True, ondelete='cascade')
    template_id = fields.Many2one(
        'mail.template', 'Use template',
        domain="[('model', '=', 'account.move')]"
        )

    # Technical field containing a textual representation of the selected move types,
    # if multiple. It is used to inform the user in the window in such case.
    move_types = fields.Char(
        string='Move types',
        compute='_compute_move_types',
        readonly=True)

    @api.model
    def default_get(self, fields):
        res = super(AccountInvoiceSend, self).default_get(fields)
        res_ids = self._context.get('active_ids')

        invoices = self.env['account.move'].browse(res_ids).filtered(lambda move: move.is_invoice(include_receipts=True))
        if not invoices:
            raise UserError(_("You can only send invoices."))

        composer = self.env['mail.compose.message'].create({
            'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail',
        })
        res.update({
            'invoice_ids': res_ids,
            'composer_id': composer.id,
        })
        return res

    @api.onchange('invoice_ids')
    def _compute_composition_mode(self):
        for wizard in self:
            wizard.composer_id.composition_mode = 'comment' if len(wizard.invoice_ids) == 1 else 'mass_mail'

    @api.onchange('invoice_ids')
    def _compute_move_types(self):
        for wizard in self:
            move_types = False

            if len(wizard.invoice_ids) > 1:
                moves = self.env['account.move'].browse(self.env.context.get('active_ids'))

                # Get the move types of all selected moves and see if there is more than one of them.
                # If so, we'll display a warning on the next window about it.
                move_types_set = set(m.type_name for m in moves)

                if len(move_types_set) > 1:
                    move_types = ', '.join(move_types_set)

            wizard.move_types = move_types


    @api.onchange('template_id')
    def onchange_template_id(self):
        for wizard in self:
            if wizard.composer_id:
                wizard.composer_id.template_id = wizard.template_id.id
                wizard._compute_composition_mode()
                wizard.composer_id._onchange_template_id_wrapper()

    @api.onchange('is_email')
    def onchange_is_email(self):
        if self.is_email:
            res_ids = self._context.get('active_ids')
            if not self.composer_id:
                self.composer_id = self.env['mail.compose.message'].create({
                    'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail',
                    'template_id': self.template_id.id
                })
            else:
                self.composer_id.composition_mode = 'comment' if len(res_ids) == 1 else 'mass_mail'
                self.composer_id.template_id = self.template_id.id
                self._compute_composition_mode()
            self.composer_id._onchange_template_id_wrapper()

    @api.onchange('is_email')
    def _compute_invoice_without_email(self):
        for wizard in self:
            if wizard.is_email and len(wizard.invoice_ids) > 1:
                invoices = self.env['account.move'].search([
                    ('id', 'in', self.env.context.get('active_ids')),
                    ('partner_id.email', '=', False)
                ])
                if invoices:
                    wizard.invoice_without_email = "%s\n%s" % (
                        _("The following invoice(s) will not be sent by email, because the customers don't have email address."),
                        "\n".join([i.name for i in invoices])
                        )
                else:
                    wizard.invoice_without_email = False
            else:
                wizard.invoice_without_email = False

    def _send_email(self):
        if self.is_email:
            # with_context : we don't want to reimport the file we just exported.
            self.composer_id.with_context(no_new_invoice=True,
                                          mail_notify_author=self.env.user.partner_id in self.composer_id.partner_ids,
                                          mailing_document_based=True,
                                          )._action_send_mail()
            if self.env.context.get('mark_invoice_as_sent'):
                #Salesman send posted invoice, without the right to write
                #but they should have the right to change this flag
                self.mapped('invoice_ids').sudo().write({'is_move_sent': True})
            for invoice in self.invoice_ids:
                prioritary_attachments = False
                if self.composition_mode == 'comment':
                    # With a single invoice we take the attachment directly from the composer
                    prioritary_attachments = self.attachment_ids.filtered(lambda x: x.mimetype.endswith('pdf')).sorted('id')
                elif self.composition_mode == 'mass_mail':
                    # In mass mail mode we need to look for attachment in the invoice record
                    prioritary_attachments = invoice.attachment_ids.filtered(lambda x: x.mimetype.endswith('pdf'))
                if prioritary_attachments:
                    main_attachment = prioritary_attachments[0]
                    invoice.with_context(tracking_disable=True).sudo().write({'message_main_attachment_id': main_attachment.id})


    def _print_document(self):
        """ to override for each type of models that will use this composer."""
        self.ensure_one()
        action = self.invoice_ids.action_invoice_print()
        action.update({'close_on_report_download': True})
        return action

    def send_and_print_action(self):
        self.ensure_one()
        # Send the mails in the correct language by splitting the ids per lang.
        # This should ideally be fixed in mail_compose_message, so when a fix is made there this whole commit should be reverted.
        # basically self.body (which could be manually edited) extracts self.template_id,
        # which is then not translated for each customer.
        if self.composition_mode == 'mass_mail' and self.template_id:
            active_ids = self.env.context.get('active_ids', self.res_id)
            active_records = self.env[self.model].browse(active_ids)
            langs = set(active_records.mapped('partner_id.lang'))
            for lang in langs:
                active_ids_lang = active_records.filtered(lambda r: r.partner_id.lang == lang).ids
                self_lang = self.with_context(active_ids=active_ids_lang, lang=get_lang(self.env, lang).code)
                self_lang.onchange_template_id()
                self_lang._send_email()
        else:
            active_record = self.env[self.model].browse(self.res_id)
            lang = get_lang(self.env, active_record.partner_id.lang).code
            self.with_context(lang=lang)._send_email()
        if self.is_print:
            return self._print_document()
        return {'type': 'ir.actions.act_window_close'}

    def save_as_template(self):
        self.ensure_one()
        self.composer_id.action_save_as_template()
        self.template_id = self.composer_id.template_id.id
        action = _reopen(self, self.id, self.model, context=self._context)
        action.update({'name': _('Send Invoice')})
        return action
