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

import json

from odoo.exceptions import ValidationError
from odoo.http import request, route

from odoo.addons.base.models.ir_qweb_fields import nl2br_enclose
from odoo.addons.website.controllers import main
from odoo.addons.website.controllers.form import WebsiteForm
from odoo.addons.website_sale.models.website import (
    FISCAL_POSITION_SESSION_CACHE_KEY,
    PRICELIST_SELECTED_SESSION_CACHE_KEY,
    PRICELIST_SESSION_CACHE_KEY,
)


class WebsiteSaleForm(WebsiteForm):

    @route('/website/form/shop.sale.order', type='http', auth="public", methods=['POST'], website=True)
    def website_form_saleorder(self, **kwargs):
        model_record = request.env.ref('sale.model_sale_order').sudo()
        try:
            data = self.extract_data(model_record, kwargs)
        except ValidationError as e:
            return json.dumps({'error_fields': e.args[0]})

        if not (order_sudo := request.cart):
            return json.dumps({'error': "No order found; please add a product to your cart."})

        if data['record']:
            order_sudo.write(data['record'])

        if data['custom']:
            order_sudo._message_log(
                body=nl2br_enclose(data['custom'], 'p'),
                message_type='comment',
            )

        if data['attachments']:
            self.insert_attachment(model_record, order_sudo.id, data['attachments'])

        return json.dumps({'id': order_sudo.id})

    def extract_data(self, model_sudo, values):
        parent_name = values.pop('parent_name', None)
        data = super().extract_data(model_sudo, values)
        if model_sudo.model == 'res.partner' and parent_name:
            # `parent_name` is a non-stored field, passing it in the record
            # allows to create the parent company during record creation.
            data['record']['parent_name'] = parent_name
        return data


class Website(main.Website):

    def _login_redirect(self, uid, redirect=None):
        # If we are logging in, clear the current pricelist to be able to find
        # the pricelist that corresponds to the user afterwards.
        request.session.pop(PRICELIST_SESSION_CACHE_KEY, None)
        request.session.pop(FISCAL_POSITION_SESSION_CACHE_KEY, None)
        request.session.pop(PRICELIST_SELECTED_SESSION_CACHE_KEY, None)
        return super()._login_redirect(uid, redirect=redirect)

    @route()
    def autocomplete(self, search_type=None, term=None, order=None, limit=5, max_nb_chars=999, options=None):
        options = options or {}
        if 'display_currency' not in options:
            options['display_currency'] = request.website.currency_id
        return super().autocomplete(search_type, term, order, limit, max_nb_chars, options)

    @route()
    def get_current_currency(self, **kwargs):
        return {
            'id': request.website.currency_id.id,
            'symbol': request.website.currency_id.symbol,
            'position': request.website.currency_id.position,
        }

    @route()
    def change_lang(self, lang, **kwargs):
        if cart := request.cart:
            request.env.add_to_compute(
                cart.order_line._fields['name'],
                cart.order_line.with_context(lang=lang),
            )
        return super().change_lang(lang, **kwargs)
