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

from werkzeug import utils
import base64
import logging
_logger = logging.getLogger(__name__)

# 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)

#     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,
#         )
  
        


class DonationDonation(models.Model):
    _inherit = 'donation.donation'

    invoice_id=fields.Many2one('account.move','invoice')
    transaction_id=fields.Many2one('payment.transaction','payment transaction')
    state_done=fields.Boolean(compute='_compute_donation_state',store=True)
    
    # @api.depends('transaction_id.state')
    # def transaction_state(self):
    #     _logger.error("onchange_transaction_state")
    #     if self.state=='done':
    #         if self.donation_ids:
    #             for donation_id in donation_ids:
    #                 _logger.error("donation_id="+str(donation_id))
    #                 donation=request.env['donation.donation'].sudo().search([('id','=',int(donation_id))])
    #                 if donation:donation.state='done'
            
    #         if self.membership_ids:
    #             for membership_id in membership_ids:
    #                 membership=request.env['kalachakra.membership'].sudo().search([('id','=',int(membership_id))])
    #                 if membership:membership.state='done'

    @api.depends('invoice_id.payment_state','transaction_id.state')
    def _compute_donation_state(self):
        for d in self:
            if d.invoice_id:
                if d.invoice_id.payment_state=='paid':
                        
                        d.state='done'
                        d.state_done=True
                else:
                        d.state='draft'
                        d.state_done=False
            if d.transaction_id:
                if d.transaction_id.state=='done':
                     if d.state!='done':
                        d.state='done'
                        d.state_done=True
                        d.email_confirmation()
                 

    def email_confirmation(self):
       
       mail_template = self.env['mail.template'].search([('name','=','confirmation_donation')])

       mail_template.email_to = self.partner_id.email

       #mail_template.with_context({'end_date':self.end_date}).send_mail(self.id,False)
       mail_template.send_mail(self.id,False)
        
       return True

    def bulk_remove_draft_donation(self):
        payment_transaction=self.env['payment.transaction'].search([('state','=','draft')])
        if payment_transaction:
            for p in payment_transaction:
                if p.donation_ids:
                    for d in p.donation_ids:
                        #on ne supprime que les dons brouillons
                        if d.state=='draft':
                             today=date.today()
                             b_date = date(d.create_date.year,d.create_date.month, d.create_date.day)
                             #b_date = date(2022,8, 12)
                             e_date = date(today.year,today.month, today.day)
                             diff=e_date-b_date
                           
                             _logger.error("errK2-diff days="+str(diff.days)) 
                             if diff.days>15:self.env['donation.donation'].search([('id','=',int(d.id))]).unlink()

        #on supprime également les dons brouillon de plus de 15 jours non lié à une retraite, donc sans facture
        donation=self.env['donation.donation'].search([('state','=','draft')])
        if donation:
            for d in donation:
                if not d.invoice_id:
                    today=date.today()
                    b_date = date(d.create_date.year,d.create_date.month, d.create_date.day)
                    e_date = date(today.year,today.month, today.day)
                    diff=e_date-b_date
                    _logger.error("errK2-diff days m="+str(diff.days))
                    if diff.days>15:self.env['donation.donation'].search([('id','=',int(d.id))]).unlink()



    def _get_payment_type(self, tokenize=False):
        self.ensure_one()
        return 'form_save' if tokenize else 'form'

    def _create_payment_transaction(self, vals):
        '''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the
        current donation fields (e.g. the partner or the currency).
        :param vals: The values to create a new payment.transaction.
        :return: The newly created payment.transaction record.
        '''
        # Ensure the currencies are the same.
        currency = self[0].currency_id
        # if any(so.pricelist_id.currency_id != currency for so in self):
        #     raise ValidationError(_('A transaction can\'t be linked to sales orders having different currencies.'))

        # Ensure the partner are the same.
        partner = self[0].partner_id
        if any(so.partner_id != partner for so in self):
            raise ValidationError(_('A transaction can\'t be linked to sales orders having different partners.'))

        # Try to retrieve the acquirer. However, fallback to the token's acquirer.
        acquirer_id = vals.get('acquirer_id')
        acquirer = False
        payment_token_id = vals.get('payment_token_id')

        if payment_token_id:
            payment_token = self.env['payment.token'].sudo().browse(payment_token_id)

            # Check payment_token/acquirer matching or take the acquirer from token
            if acquirer_id:
                acquirer = self.env['payment.acquirer'].browse(acquirer_id)
                if payment_token and payment_token.acquirer_id != acquirer:
                    raise ValidationError(_('Invalid token found! Token acquirer %s != %s') % (
                    payment_token.acquirer_id.name, acquirer.name))
                if payment_token and payment_token.partner_id != partner:
                    raise ValidationError(_('Invalid token found! Token partner %s != %s') % (
                    payment_token.partner.name, partner.name))
            else:
                acquirer = payment_token.acquirer_id

        # Check an acquirer is there.
        if not acquirer_id and not acquirer:
            raise ValidationError(_('A payment acquirer is required to create a transaction.'))

        if not acquirer:
            acquirer = self.env['payment.acquirer'].browse(acquirer_id)

        # Check a journal is set on acquirer.
        if not acquirer.journal_id:
            raise ValidationError(_('A journal must be specified for the acquirer %s.', acquirer.name))

        if not acquirer_id and acquirer:
            vals['acquirer_id'] = acquirer.id

        vals.update({
            'amount': sum(self.mapped('amount_total')),
            'currency_id': currency.id,
            'partner_id': partner.id,
            'donation_ids': [(6, 0, self.ids)],
            'type': self[0]._get_payment_type(vals.get('type')=='form_save'),
        })
        
        
        transaction = self.env['payment.transaction'].create(vals)
        
        
        # Process directly if payment_token
        if transaction.payment_token_id:
            transaction.s2s_do_transaction()

        return transaction

    # def _generate_invoice_donation(self, vals):
