from odoo import models,release, fields, api,_
from odoo.exceptions import UserError, ValidationError,Warning
from psycopg2 import sql, DatabaseError
from datetime import datetime

from pkg_resources import parse_version
from werkzeug import utils
import base64
from odoo.addons.payment_systempay.helpers import constants, tools
from odoo.tools import float_round
from odoo.tools.float_utils import float_compare
from odoo.addons.payment_systempay.controllers.main import SystempayController
import logging
_logger = logging.getLogger(__name__)


try:
    import urlparse
except ImportError:
    import urllib.parse as urlparse

class PaymentTransaction(models.Model):
    _inherit = 'payment.transaction'

    donation_ids = fields.Many2many('donation.donation', 'donation_transaction_rel', 'transaction_id', 'donation_id',
                                      string='Donations', copy=False, readonly=True)
    
    membership_ids = fields.Many2many('kalachakra.membership', 'membership_transaction_rel', 'transaction_id', 'membership_id',
                                      string='Membership', copy=False, readonly=True)

    online_payment_ids = fields.Many2many('kalachakra.online_payment', 'online_payment_transaction_rel', 'transaction_id', 'online_payment_id',
                                      string='Online payment', copy=False, readonly=True)

    reference2=fields.Char('type',compute='compute_reference')

    invoice_bug=fields.Boolean(string="invoice bug", compute='_compute_invoice_bug',store=True)
    
    def _compute_invoice_bug(self):
        for rec in self:
            rec.invoice_bug=False
            for invoice in rec.invoice_ids:
                if rec.state in ['done','authorized'] and invoice.payment_state!='paid' and invoice.state=='posted':
                    rec.invoice_bug=True

    def compute_reference(self):
        for rec in self:
            rec.reference2='Participation'
            if rec.membership_ids:rec.reference2= 'Adhesion'
            if rec.donation_ids: rec.reference2='Don'
            # if not rec.membership_ids and not rec.donation_ids:
            #     #on cherche si transaction lié à une retraite
            #     invoices=rec.invoice_ids
            #     for invoice in invoices:




    def render_donation_button(self, donation, submit_txt=None, render_values=None):
        values = {
            'partner_id': donation.partner_id.id,
            'type': self.type,
        }
        if render_values:
            values.update(render_values)
        # Not very elegant to do that here but no choice regarding the design.
        self._log_payment_transaction_sent()
        return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render(
            self.reference,
            donation.amount_total,
            donation.currency_id.id,
            values=values,
        )
    def render_membership_button(self, membership, submit_txt=None, render_values=None):
        values = {
            'partner_id': membership.partner_id.id,
            'type': self.type,
        }
        if render_values:
            values.update(render_values)
        # Not very elegant to do that here but no choice regarding the design.
        self._log_payment_transaction_sent()
        return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render(
            self.reference,
            membership.amount,
            membership.currency_id.id,
            values=values,
        )
    def render_online_payment_button(self, online_payment, submit_txt=None, render_values=None):
        values = {
            'partner_id': online_payment.partner_id.id,
            'type': self.type,
        }
        if render_values:
            values.update(render_values)
        # Not very elegant to do that here but no choice regarding the design.
        self._log_payment_transaction_sent()
        return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render(
            self.reference,
            membership.amount,
            membership.currency_id.id,
            values=values,
        )
    @api.model
    def _compute_reference_prefix(self, values):
        if values and values.get('invoice_ids'):
            invoices = self.new({'invoice_ids': values['invoice_ids']}).invoice_ids
            
            if len(invoices)==1:
                    invoice=self.env['account.move'].sudo().search([('name','=',invoices.name)])
                    reg=self.env['event.registration'].sudo().search(['|','|',('invoice_id','=',invoice.id),('balance_invoice_id','=',invoice.id),('down_payment_invoice_id','=',invoice.id)])
                    if reg:
                        if reg.event_id.booking_event:
                            return 'txR-'+invoice.name
                        else:
                            return 'txP-'+invoice.name
                    else:
                        return 'txP-'+invoice.name
            else:
                return ','.join(invoices.mapped('name'))
        
        if values and values.get('donation_ids'):
           
            return 'txD'
        
        if values and values.get('membership_ids'):
    
            return 'txA'

        return None

    
                    
class AcquirerSystempay(models.Model):
    _inherit = 'payment.acquirer'

    def systempay_form_generate_values(self, values):
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')

        # trans_id is the number of 1/10 seconds from midnight.
        now = datetime.now()
        midnight = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
        delta = int((now - midnight).total_seconds() * 10)
        delta=str(delta)
        delta=delta[:-1]
        prefix=values['reference'][2:3]
        if prefix not in ('D','A','P','R'): prefix='L'
        
        trans_id = prefix+delta.rjust(5)

        threeds_mpi = u''
        if self.systempay_threeds_min_amount and float(self.systempay_threeds_min_amount) > values['amount']:
            threeds_mpi = u'2'

        # Check currency.
        currency_num = tools.find_currency(values['currency'].name)
        if currency_num is None:
            _logger.error('The plugin cannot find a numeric code for the current shop currency {}.'.format(values['currency'].name))
            raise ValidationError(_('The shop currency {} is not supported.').format(values['currency'].name))

        # Amount in cents.
        k = int(values['currency'].decimal_places)
        amount = int(float_round(float_round(values['amount'], k) * (10 ** k), 0))

        # List of available languages.
        available_languages = ''
        for value in self.systempay_available_languages:
            available_languages += value.code + ';'

        # List of available payment cards.
        payment_cards = ''
        for value in self.systempay_payment_cards:
            payment_cards += value.code + ';'

        #Validation mode
        validation_mode = self.systempay_validation_mode if self.systempay_validation_mode != '-1' else ''

        # Enable redirection?
        AcquirerSystempay.systempay_redirect = True if str(self.systempay_redirect_enabled) == '1' else False

        tx_values = dict() # Values to sign in unicode.
        tx_values.update({
            'vads_site_id': self.systempay_site_id,
            'vads_amount': str(amount),
            'vads_currency': currency_num,
            'vads_trans_date': str(datetime.utcnow().strftime("%Y%m%d%H%M%S")),
            'vads_trans_id': str(trans_id),
            'vads_ctx_mode': str(self._get_ctx_mode()),
            'vads_page_action': u'PAYMENT',
            'vads_action_mode': u'INTERACTIVE',
            'vads_payment_config': self._get_payment_config(amount),
            'vads_version': constants.SYSTEMPAY_PARAMS.get('GATEWAY_VERSION'),
            'vads_url_return': urlparse.urljoin(base_url, SystempayController._return_url),
            'vads_order_id': str(values.get('reference')),
            'vads_contrib': constants.SYSTEMPAY_PARAMS.get('CMS_IDENTIFIER') + u'_' + constants.SYSTEMPAY_PARAMS.get('PLUGIN_VERSION') + u'/' + release.version,

            'vads_language': self.systempay_language or '',
            'vads_available_languages': available_languages,
            'vads_capture_delay': self.systempay_capture_delay or '',
            'vads_validation_mode': validation_mode,
            'vads_payment_cards': payment_cards,
            'vads_return_mode': str(self.systempay_return_mode),
            'vads_threeds_mpi': threeds_mpi,

            # Customer info.
            'vads_cust_id': str(values.get('billing_partner_id')) or '',
            'vads_cust_first_name': values.get('billing_partner_first_name') and values.get('billing_partner_first_name')[0:62] or '',
            'vads_cust_last_name': values.get('billing_partner_last_name') and values.get('billing_partner_last_name')[0:62] or '',
            'vads_cust_address': values.get('billing_partner_address') and values.get('billing_partner_address')[0:254] or '',
            'vads_cust_zip': values.get('billing_partner_zip') and values.get('billing_partner_zip')[0:62] or '',
            'vads_cust_city': values.get('billing_partner_city') and values.get('billing_partner_city')[0:62] or '',
            'vads_cust_state': values.get('billing_partner_state').code and values.get('billing_partner_state').code[0:62] or '',
            'vads_cust_country': values.get('billing_partner_country').code and values.get('billing_partner_country').code.upper() or '',
            'vads_cust_email': values.get('billing_partner_email') and values.get('billing_partner_email')[0:126] or '',
            'vads_cust_phone': values.get('billing_partner_phone') and values.get('billing_partner_phone')[0:31] or '',

            # Shipping info.
            'vads_ship_to_first_name': values.get('partner_first_name') and values.get('partner_first_name')[0:62] or '',
            'vads_ship_to_last_name': values.get('partner_last_name') and values.get('partner_last_name')[0:62] or '',
            'vads_ship_to_street': values.get('partner_address') and values.get('partner_address')[0:254] or '',
            'vads_ship_to_zip': values.get('partner_zip') and values.get('partner_zip')[0:62] or '',
            'vads_ship_to_city': values.get('partner_city') and values.get('partner_city')[0:62] or '',
            'vads_ship_to_state': values.get('partner_state').code and values.get('partner_state').code[0:62] or '',
            'vads_ship_to_country': values.get('partner_country').code and values.get('partner_country').code.upper() or '',
            'vads_ship_to_phone_num': values.get('partner_phone') and values.get('partner_phone')[0:31] or '',
        })

        if AcquirerSystempay.systempay_redirect:
            tx_values.update({
                'vads_redirect_success_timeout': self.systempay_redirect_success_timeout or '',
                'vads_redirect_success_message': self.systempay_redirect_success_message or '',
                'vads_redirect_error_timeout': self.systempay_redirect_error_timeout or '',
                'vads_redirect_error_message': self.systempay_redirect_error_message or ''
            })

        systempay_tx_values = dict() # Values encoded in UTF-8.

        for key in tx_values.keys():
            if tx_values[key] == ' ':
                tx_values[key] = ''

            systempay_tx_values[key] = tx_values[key].encode('utf-8')

        systempay_tx_values['systempay_signature'] = self._systempay_generate_sign(self, tx_values)
        return systempay_tx_values
    
    
            