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

from odoo import api, fields, models, tools, _


class MailComposerMixin(models.AbstractModel):
    """ Mixin used to edit and render some fields used when sending emails or
    notifications based on a mail template.

    Main current purpose is to hide details related to subject and body computation
    and rendering based on a mail.template. It also give the base tools to control
    who is allowed to edit body, notably when dealing with templating language
    like inline_template or qweb.

    It is meant to evolve in a near future with upcoming support of qweb and fine
    grain control of rendering access.
    """
    _name = 'mail.composer.mixin'
    _inherit = 'mail.render.mixin'
    _description = 'Mail Composer Mixin'

    # Content
    subject = fields.Char('Subject', compute='_compute_subject', readonly=False, store=True, compute_sudo=False)
    body = fields.Html('Contents', compute='_compute_body', render_engine='qweb', store=True, readonly=False, sanitize=False, compute_sudo=False)
    template_id = fields.Many2one('mail.template', 'Mail Template', domain="[('model', '=', render_model)]")
    # Access
    is_mail_template_editor = fields.Boolean('Is Editor', compute='_compute_is_mail_template_editor')
    can_edit_body = fields.Boolean('Can Edit Body', compute='_compute_can_edit_body')

    @api.depends('template_id')
    def _compute_subject(self):
        for composer_mixin in self:
            if composer_mixin.template_id:
                composer_mixin.subject = composer_mixin.template_id.subject
            elif not composer_mixin.subject:
                composer_mixin.subject = False

    @api.depends('template_id')
    def _compute_body(self):
        for composer_mixin in self:
            if composer_mixin.template_id:
                composer_mixin.body = composer_mixin.template_id.body_html
            elif not composer_mixin.body:
                composer_mixin.body = False

    @api.depends_context('uid')
    def _compute_is_mail_template_editor(self):
        is_mail_template_editor = self.env.is_admin() or self.env.user.has_group('mail.group_mail_template_editor')
        for record in self:
            record.is_mail_template_editor = is_mail_template_editor

    @api.depends('template_id', 'is_mail_template_editor')
    def _compute_can_edit_body(self):
        for record in self:
            record.can_edit_body = (
                record.is_mail_template_editor
                or not record.template_id
            )

    def _render_field(self, field, *args, **kwargs):
        """Render the given field on the given records.
        This method bypass the rights when needed to
        be able to render the template values in mass mode.
        """
        if field not in self._fields:
            raise ValueError(_("The field %s does not exist on the model %s", field, self._name))

        composer_value = self[field]

        if (
            not self.template_id
            or self.is_mail_template_editor
        ):
            # Do not need to bypass the verification
            return super(MailComposerMixin, self)._render_field(field, *args, **kwargs)

        template_field = 'body_html' if field == 'body' else field
        assert template_field in self.template_id._fields
        template_value = self.template_id[template_field]

        if field == 'body':
            sanitized_template_value = tools.html_sanitize(template_value)
            if not self.can_edit_body or composer_value in (sanitized_template_value, template_value):
                # Take the previous body which we can trust without HTML editor reformatting
                self.body = self.template_id.body_html
                return super(MailComposerMixin, self.sudo())._render_field(field, *args, **kwargs)

        elif composer_value == template_value:
            # The value is the same as the mail template so we trust it
            return super(MailComposerMixin, self.sudo())._render_field(field, *args, **kwargs)

        return super(MailComposerMixin, self)._render_field(field, *args, **kwargs)
