# Part of Odoo. See LICENSE file for full copyright and licensing details.

import hashlib
import uuid

from datetime import datetime
from werkzeug import urls
from odoo import api, fields, models
from odoo.tools.translate import LazyTranslate

VALIDATION_KARMA_GAIN = 3
_lt = LazyTranslate(__name__)


class ResUsers(models.Model):
    _inherit = 'res.users'

    # overridden inherited fields to bypass access rights, in case you have
    # access to the user but not its corresponding partner
    country_id = fields.Many2one(related='partner_id.country_id', inherited=True, readonly=False, user_writeable=True)
    city = fields.Char(related='partner_id.city', inherited=True, readonly=False, user_writeable=True)
    website = fields.Char(related='partner_id.website', inherited=True, readonly=False, user_writeable=True)
    website_description = fields.Html(related='partner_id.website_description', inherited=True, readonly=False, user_writeable=True)
    website_published = fields.Boolean(related='partner_id.website_published', inherited=True, readonly=False, user_writeable=True)

    @api.model
    def _generate_profile_token(self, user_id, email):
        """Return a token for email validation. This token is valid for the day
        and is a hash based on a (secret) uuid generated by the forum module,
        the user_id, the email and currently the day (to be updated if necessary). """
        profile_uuid = self.env['ir.config_parameter'].sudo().get_str('website_profile.uuid')
        if not profile_uuid:
            profile_uuid = str(uuid.uuid4())
            self.env['ir.config_parameter'].sudo().set_str('website_profile.uuid', profile_uuid)
        return hashlib.sha256((u'%s-%s-%s-%s' % (
            datetime.now().replace(hour=0, minute=0, second=0, microsecond=0),
            profile_uuid,
            user_id,
            email
        )).encode('utf-8')).hexdigest()

    def _send_profile_validation_email(self, **kwargs):
        if not self.email:
            return False
        token = self._generate_profile_token(self.id, self.email)
        activation_template = self.env.ref('website_profile.validation_email')
        if activation_template:
            params = {
                'token': token,
                'user_id': self.id,
                'email': self.email
            }
            params.update(kwargs)
            token_url = self.get_base_url() + '/profile/validate_email?%s' % urls.url_encode(params)
            # At this point, user access on template should not restrict template rendering
            activation_template.sudo().with_context(
                email_notification_force_header=True,
                email_notification_force_footer=True,
                email_notification_subtitles=[
                    _lt("%(company_name)s Profile validation", company_name=self.sudo().company_id.name or '')],
                token_url=token_url,
            ).send_mail_batch(
                self.ids, force_send=True, raise_exception=True,
                email_layout_xmlid='mail.mail_notification_layout',
            )
        return True

    def _process_profile_validation_token(self, token, email):
        self.ensure_one()
        validation_token = self._generate_profile_token(self.id, email)
        if token == validation_token and self.karma == 0:
            return self.write({'karma': VALIDATION_KARMA_GAIN})
        return False
