from odoo import fields, http, _
from odoo.http import request
import werkzeug
from odoo.tools import format_datetime, format_date, is_html_empty
from datetime import datetime,timedelta
from dateutil.relativedelta import relativedelta
from odoo.exceptions import UserError,AccessError, MissingError,Warning
from odoo.addons.website_event.controllers.main import WebsiteEventController
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
from odoo.addons.sale.controllers.portal import CustomerPortal
from odoo.addons.portal.controllers.portal import pager as portal_pager, get_records_pager
import json
import binascii
from odoo.addons.payment.controllers.portal import PaymentProcessing
from odoo.addons.portal.controllers.mail import _message_post_helper
from odoo.osv import expression


class booking(WebsiteEventController,AuthSignupHome):

    @http.route(['/booking/registration/options'], type='http', auth='user', website=True, sitemap=False,csrf=False)
    def bookingregistration_options(self,event_id,*args,**kw):
        data={}
        
        #contact lié à l'utilisateur
        userid=request.env.context.get('uid')
        user=request.env['res.users'].search([('id','=',int(userid))])
        partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))])
        request.session['partner_id']=int(partner.id)
        #si le pays n'est pas renseigné, on le renseigne avec France
        #c'est indispensable pour pouvoir régléer le devis
        if not partner.country_id:
            country=request.env['res.country'].search([('name','=','France')])
            partner.country_id=country.id


        data['partner']=partner
       
        #évenement
        request.session['event_id']=int(event_id)
        event=request.env['event.event'].sudo().search([('id','=',int(event_id))])
        data['event']=event
        data['bottom_text']=request.env['booking.parameter'].sudo().search([('name','=','bottom_text')]).value
       
        request.session['individual_booking_event']=event.individual_booking_event
        data['individual_booking_event']=event.individual_booking_event


        
        data['status']=partner.member_status
        
        if data['status']=='not member':data['your_status']='non adhérent'
        if data['status']=='member':data['your_status']='adhérent'
        if data['status']=='super member':data['your_status']='adhérent de soutien'
        
        #prix
        data['price']=0
        if partner.member_status=='not member':data['price']=event.booking_price
        if partner.member_status=='member':data['price']=event.booking_member_price
        if partner.member_status=='super member':data['price']=event.booking_super_member_price
        
        #membership product
        #membership_product=request.env['event.membership_product'].sudo().search([])
        membership_product=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1)
        if not  membership_product: raise Warning('no membership product find')
        data['membership_product']=membership_product
        #options
        data['options']=[]
        
        data['id_opt_reduction1200']=False
        data['id_opt_individual_room']=False
        data['i_opt_reduction1200']=False
        data['i_opt_individual_room']=False
        i=1
        for opt in event.booking_option_ids:
            
            if opt.booking_option_id.individual_room:
                data['id_opt_individual_room']=opt.booking_option_id.id
                data['i_opt_individual_room']=i
            if "1200" in opt.booking_option_id.name:
                data['id_opt_reduction1200']=opt.booking_option_id.id
                data['i_opt_reduction1200']=i
            if opt.booking_option_id.membership_product:
                
                if partner.member_status!='member' and partner.member_status!='super member':data['options'].append(opt)
                i=i-1
            else:
                
                
                data['options'].append(opt)
            i=i+1


        #questions
        data['questions']=event.question_ids

        request.session['invoice_id']=False
        return http.request.render('kalachakra.booking_registration_options_form2',data)

    @http.route(['/booking/registration/questionnaire'], type='http', auth='user', website=True, sitemap=False,csrf=False)
    def bookingregistration_questionnaire(self,**post):
        vals={}
        data={}
        
        
            
        #gestion du retour page précédente depuis page de paiement : on supprime les éléments générés ( don , adhésion)
        if not post.get('nb_o'):
            if request.session['invoice_id']:
                invoice=request.env['account.move'].sudo().search([("id","=",int(request.session['invoice_id']))])
                invoice.state='draft'
                invoice.unlink()
            return request.redirect('/booking/registration/options?event_id='+str(request.session['event_id']))

        #si déjà inscrit, redirection vers page d'information
        reg=request.env['event.registration'].sudo().search([('state','!=','cancel'),('event_id','=',int(post.get('event_id'))),('email','=',post.get('email'))])
        
        if reg and not request.session['individual_booking_event']:
            return http.request.render('kalachakra.booking_registration_already_registered')
            
        vals['event_id']=post.get('event_id')
        vals['name']=post.get('name')
        vals['phone']=post.get('phone')
        vals['city']=post.get('city')
        vals['email']=post.get('email')
        	
        vals['firstname']=post.get('firstname')
        vals['age']=post.get('age')
        vals['gender']=post.get('gender')
        vals['mobile']=post.get('mobile')

        #individual booking data
        if request.session['individual_booking_event']:
            s=post.get('start_day').split('/')
            start_day=s[2]+'-'+s[1]+'-'+s[0]
           
            e=post.get('end_day').split('/')
            end_day=e[2]+'-'+e[1]+'-'+e[0]
           

            vals['start_day_individual_booking']=start_day
            vals['end_day_individual_booking']=end_day
            vals['days_duration']=post.get('days_duration')
            vals['price_individual_booking']=post.get('price_individual_booking')

        request.session['registrant'] = vals
        request.session['down_payment'] =False
        if post.get('down_payment')=="false":request.session['down_payment'] =  False
        if post.get('down_payment')=="true":request.session['down_payment'] =  True
        
        #options
        
        if post.get('nb_o')!="0":
                
            vals3={}
            i=1
            k=1
            while i <= int(post.get('nb_o')):
                if post.get('o['+str(i)+']'):
                    vals3[k]=post.get('o['+str(i)+']')
                    k=k+1
                i=i+1
            request.session['options']=vals3
            request.session['nb_o']=k-1
        else:
            request.session['options']=None
            request.session['nb_o']=0
        #questions
                
        event=request.env['event.event'].sudo().search([('id','=',int(post.get('event_id')))])
        data['event']=event
        data['questions']=False
        if event.question_ids:
            data['questions']=event.question_ids
        
        return http.request.render('kalachakra.booking_registration_questionnaire_form',data)

    @http.route(['/booking/payment_choice'], type='http',auth='user', website=True, sitemap=False,csrf=False)
    def bookinginvoice(self,**post):
        
                
        vals={}
        vals['event_id']=request.session['event_id']
        vals['partner_id']=request.session['partner_id']
        vals['name']=request.session['registrant']['name']
        vals['phone']=request.session['registrant']['phone']
        vals['city']=request.session['registrant']['city']
        vals['email']=request.session['registrant']['email']
        vals['firstname']=request.session['registrant']['firstname']
        vals['age']=request.session['registrant']['age']
        vals['gender']=request.session['registrant']['gender']
        vals['mobile']=request.session['registrant']['mobile']

        vals['medical_concern']=post.get('medical_concern')
        vals['medical_information']=post.get('medical_information')
        vals['medical_contact_name']=post.get('medical_contact_name')
        vals['medical_contact_phone']=post.get('medical_contact_phone')
        vals['image_permission']=post.get('image_permission')

        vals['down_payment']=request.session['down_payment']
        vals['state']='draft'

        if request.session['individual_booking_event']:
            vals['start_day_individual_booking']=request.session['registrant']['start_day_individual_booking']
            vals['end_day_individual_booking']=request.session['registrant']['end_day_individual_booking']
            vals['days_duration']=request.session['registrant']['days_duration']
            vals['price_individual_booking']=request.session['registrant']['price_individual_booking']


        
        res=request.env['event.registration'].sudo().create(vals)
        request.session['res_id']=res.id
        vals2={}
        
        #questionnaire'
        i=1
        vals2['event_registration_id']=res.id
        #suppression du questionnaire de la personne inscrite
        request.env['event.registration_questionnaire'].sudo().search([('event_registration_id','=',int(res.id))]).unlink()

        if post.get('nb_q')!="0":
            while i < int(post.get('nb_q')):
                vals2['sequence']=i
                vals2['question']=post.get('q['+str(i)+']')
                vals2['answer']=post.get('a['+str(i)+']')
                
                
                #ajout du questionnaire avec les réponses
                res2=request.env['event.registration_questionnaire'].sudo().create(vals2)
                
                res.write({'questionnaire_ids':[(4,res2.id)]})
                i=i+1

        #options
        membership=False
       #suppression des options de la personne inscrite
        request.env['event.registration_option'].sudo().search([('event_registration_id','=',int(res.id))]).unlink()
        if request.session['nb_o']!=0 :
            vals3={}
            i=1
            
            
            while i <= int(request.session['nb_o']):
                    
                    vals3['booking_option_id']=int(request.session['options'][i])
                    vals3['event_registration_id']=res.id
                    #ajout des options

                    #Si option d'adhesion on prepare la creation de l'adhesion
                    membership_product=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1)
                    if membership_product.id==int(vals3['booking_option_id']):membership=True
                    
                    
                    res3=request.env['event.registration_option'].sudo().create(vals3)    
                    
                    res.write({'option_ids':[(4,res3.id)]})
                    i=i+1
        if res.event_id.individual_booking_event:
            # envoi d'un mail aux gestionnaires
            mail_template = request.env['mail.template'].sudo().search([('name','=','individual_booking_request')])
           
            if mail_template:
                mail_template.sudo().send_mail(res.id,False)
            #affichage de la page de confirmation
            url="/booking/individual_confirmation/"

        else:
            invoice=request.env['event.registration'].sudo().action_event_registration_generate_invoice(request.session['res_id'],False,False)
            request.session['invoice_id']=invoice.id
            
            #ajout de l'adhésion
            if membership:
                membership_product=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1)
                if not membership_product: raise UserError(_('No membership product, please add one'))
                vals={}
                vals['invoice_id']=int(invoice.id)
                vals['balance_invoice_id']=int(res.balance_invoice_id)
                vals['partner_id']=int(res.partner_id)
                vals['product_id']=int(membership_product.id)
                vals['start_date']=datetime.now()
                vals['end_date']=datetime.now()+relativedelta(years=1)
                vals['amount']=membership_product.list_price
                membership=request.env['kalachakra.membership'].sudo().create(vals)
        
            #redirection sur la page de paiement de la facture :
            url="/my/invoices/"+str(invoice.id)
        return request.redirect(url)
        
        
    @http.route(['/booking/individual_confirmation'], type='http',auth='user', website=True, sitemap=False,csrf=False)
    def individual_confirmation(self,**post):
        return http.request.render('kalachakra.individual_confirmation')


    @http.route(['/booking/payment/transaction/',
        '/booking/payment/transaction/<int:so_id>',
        '/booking/payment/transaction/<int:so_id>/<string:access_token>'], type='json', auth="public", website=True)
    def booking_payment_transaction(self, acquirer_id,order_id, save_token=False, so_id=None, access_token=None, token=None, **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button. After having
        created the transaction, the event continues and the user is redirected
        to the acquirer website.

        :param int acquirer_id: id of a payment.acquirer record. If not set the
                                user is redirected to the checkout page
        """
        # Ensure a payment acquirer is selected
        
        
        if not acquirer_id:
            return False

        try:
            acquirer_id = int(acquirer_id)
        except:
            return False

        order_id=order_id
        order=request.env['sale.order'].search([('id','=',int(order_id))], limit=1)
        

        # Ensure there is something to proceed
        if not order or (order and not order.order_line):
            return False
    
        assert order.partner_id.id != request.website.partner_id.id

        # Create transaction
        vals = {'acquirer_id': acquirer_id,
                'return_url': '/booking/payment/validate'}

        if save_token:
            vals['type'] = 'form_save'
        if token:
            vals['payment_token_id'] = int(token)

        transaction = order.sudo()._create_payment_transaction(vals)

        # store the new transaction into the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id
        request.session['order_id']=order.id
        return transaction.render_sale_button(order)

        

    http.route('/booking/payment/token', type='http', auth='public', website=True, sitemap=False)
    def booking_payment_token(self, pm_id=None, **kwargs):
        """ Method that handles payment using saved tokens

        :param int pm_id: id of the payment.token that we want to use to pay.
        """
        
        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect('/shop/?error=invalid_token_id')

        # We retrieve the token the user want to use to pay
        if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]):
            return request.redirect('/shop/?error=token_not_found')

        # Create transaction
        vals = {'payment_token_id': pm_id, 'return_url': '/booking/payment/validate'}

        
        tx = order._create_payment_transaction(vals)
        
        request.session['transaction_id']=tx.id
        PaymentProcessing.add_payment_transaction(tx)
        return request.redirect('booking/payment/process')

    @http.route(['/booking/payment/process'], type="http", auth="public", website=True, sitemap=False)
    def booking_payment_status_page(self, **kwargs):
        # When the customer is redirect to this website page,
        # we retrieve the payment transaction list from his session
        tx_ids_list = self.get_payment_transaction_ids()
        payment_transaction_ids = request.env['payment.transaction'].sudo().browse(tx_ids_list).exists()

        render_ctx = {
            'payment_tx_ids': payment_transaction_ids.ids,
        }
        return request.render("payment.payment_process_page", render_ctx)
    
    @http.route('/booking/payment/validate', type='http', auth="public", website=True, sitemap=False)
    def booking_payment_validate(self, transaction_id=None, sale_order_id=None, **post):
        
       
        #suppression du devis et création de la facture au statut payé
        order_id=int(request.session['order_id'])
        #request.env['sale.order'].search([('id','=',order_id)]).unlink()
        
        invoice=request.env['event.registration'].sudo().action_event_registration_generate_invoice(request.session['res_id'],'electronic')
        invoice.action_post()
        
        request.session['order_id']=None

        transaction_id=int(request.session['__website_sale_last_tx_id'] )
        tx = request.env['payment.transaction'].sudo().browse(transaction_id)

        PaymentProcessing.remove_payment_transaction(tx)
        return request.redirect('/booking/payment/confirmation') 

    
    @http.route(['/booking/payment/confirmation'], type='http', auth="public", website=True, sitemap=False)
    def booking_payment_confirmation(self, **post):
        
        return request.render("kalachakra.booking_thankyou")
    
    @http.route(['/booking/registration/individual_booking'], type='http', auth="public", website=True, sitemap=False)
    def booking_registration_individual_booking(self):

        individual_booking=request.env['event.event'].sudo().search([('name','=','Retraite individuelle')])
        if individual_booking:
            data={}
            data['event']=individual_booking

        return request.render("kalachakra.individual_booking_p1",data)
        #individual_booking=request.env['event.event'].sudo().search([('name','=','Retraite individuelle')])
        #if individual_booking:
        #    return request.redirect('/booking/registration/options?event_id='+str(int(individual_booking.id))) 
      
