from odoo import models, fields, api
from dateutil.relativedelta import relativedelta
from datetime import date,datetime,timedelta
import logging
_logger = logging.getLogger(__name__)

class kalachakra_membership(models.Model):
    _name = 'kalachakra.membership'
    _description = 'manage membership'

    
    partner_id = fields.Many2one(
        'res.partner',
        string='partner',
        required=True,
        index=True,
        track_visibility='onchange',
        ondelete='restrict'
    )
    email=fields.Char(related='partner_id.email')
    firstname=fields.Char(string='firstname', related='partner_id.firstname',translate=True)

    def _default_product_id(self):
        membership_product=self.env['product.product'].sudo().search([('membership_product','=',True)],limit=1)
        if not membership_product: raise UserError(_('No membership product, please add one'))
        return membership_product.id

    product_id=fields.Many2one('product.product',required=True,string='membership product',default=_default_product_id,domain="[('membership_product','=',True)]")
    start_date=fields.Date('start date',required=True,default=lambda self: fields.Date.today())
    invoice_id=fields.Many2one('account.move','invoice')
    balance_invoice_id=fields.Many2one('account.move','balance invoice')
    transaction_id=fields.Many2one('payment.transaction','payment transaction')
    payment_state=fields.Selection(string='payment_state',selection=[('paid', 'paid'), ('not paid', 'not paid')])
    
    payment_mode_id = fields.Many2one(
        "account.payment.mode",
        string="Payment Mode",
        #domain="[('company_id', '=', company_id)]",
        copy=False,
        tracking=True
    
    )

    
   
    def _default_end_date(self):
        end_date=datetime.now()+relativedelta(years=1)
        return end_date

    end_date=fields.Date('end date',default=_default_end_date)
    alert_mail_date=fields.Date('alert mail date')
    
    
            
    state=fields.Selection(string='state',selection=[('draft', 'draft'), ('done', 'done')],default='draft',compute='_compute_membership_state',inverse='_inverse_membership_state', store=True)
    currency_id = fields.Many2one(
        "res.currency",
        string="Currency",
        required=True,
        tracking=True,
        ondelete="restrict",
        default=lambda self: self.env.company.currency_id,
    )
   

    amount = fields.Monetary(
        string="Amount",
        currency_field="currency_id",
        tracking=True,
        
    )
    date_compta=fields.Datetime('date import',default=False)
    
    

    @api.depends('invoice_id.payment_state','balance_invoice_id.payment_state','transaction_id.state')
    def _compute_membership_state(self):
        for m in self:
            if m.invoice_id and not m.balance_invoice_id:
                if m.invoice_id.payment_state=='paid':
                        
                        m.payment_state='paid'
                        m.state='done'
                else:
                        m.payment_state='not paid'
                        m.state='draft'
            
            if m.balance_invoice_id:
                if m.balance_invoice_id.payment_state=='paid':
                        
                        m.payment_state='paid'
                        m.state='done'
                else:
                        m.payment_state='not paid'
                        m.state='draft'

            
            if m.transaction_id:
                if m.transaction_id.state=='done':
                     if m.state!='done':
                        m.payment_state='paid'
                        m.state='done'
                        m.email_confirmation()
            m.update_membership()
            
    
    def _inverse_membership_state(self):
        for m in self:
            
            m.update_membership()

    @api.onchange('product_id')
    def onchange_product_id(self):
        if self.product_id:
            self.amount = self.product_id.list_price

    @api.onchange('product_id')
    def onchange_product_id(self):
        if self.product_id:
            self.amount = self.product_id.list_price

    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 membership 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')),
            'currency_id': currency.id,
            'partner_id': partner.id,
            'membership_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 update_membership(self):
        member=self.env['kalachakra.membership'].search([('partner_id','=', int(self.partner_id)),('end_date','>=',datetime.now()),('state','=','done')])
        
        if member : self.partner_id.member_status='member'
        else :self.partner_id.member_status='not member'
        if self.partner_id.super_member: self.partner_id.member_status='super member'
        
        return True
    
    def bulk_update_membership(self):
        members=self.env['kalachakra.membership'].search([('end_date','<',datetime.now())])

        for m in members:
            m.update_membership()


    def bulk_mail_end_membership(self,debug:bool):
        
        date_30=date.today()+relativedelta(months=1)
        members=self.env['kalachakra.membership'].search([('alert_mail_date','=',False),('end_date','<=',date_30),('end_date','>=',date.today())])

        for m in members:
            if not debug:
                m.alert_mail_date=date.today()
                mail_template = self.env['mail.template'].search([('name','=','end_membership')])
                mail_template.email_to = self.partner_id.email
                mail_template.send_mail(m.id,False)
            _logger.error(m.partner_id.name+' '+str(m.end_date))
            

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

       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 write(self,vals):

        res=super(kalachakra_membership, self).write(vals)
        self.update_membership()
        return True
    @api.model
    def create(self,vals):

        res=super(kalachakra_membership, self).create(vals)
        res.update_membership()
        return res
        
    def update_amount(self):
        members=self.env['kalachakra.membership'].search([])
        for m in members:
            m.amount=45
            m.state='done'

    def unlink(self):
        for rec in self:
            if rec.partner_id.super_member==False:
                rec.partner_id.member_status='not member'
            super(kalachakra_membership, rec).unlink()

    def bulk_updatepayment_state(self):
        memberships=self.env['kalachakra.membership'].search([])
        for m in memberships:
            
            if m.invoice_id.payment_state=='paid':
                
                m.payment_state='paid'
                m.state='done'
            else:
                m.payment_state='not paid'
                m.state='draft'
    
    def bulk_remove_draft_membership(self):
        payment_transaction=self.env['payment.transaction'].search([('state','=','draft')])
        if payment_transaction:
            for p in payment_transaction:
                if p.membership_ids:
                    for m in p.membership_ids:
                        #on ne supprime que les adhesion brouillons
                        if m.state=='draft':
                             today=date.today()
                             b_date = date(m.create_date.year,m.create_date.month, m.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['kalachakra.membership'].search([('id','=',int(d.id))]).unlink()
        
        #on supprime également les adhésions brouillon de plus de 15 jours non lié à une retraite, donc sans facture
        members=self.env['kalachakra.membership'].search([('state','=','draft')])
        if members:
            for m in members:
                if not m.invoice_id:
                    today=date.today()
                    b_date = date(m.create_date.year,m.create_date.month, m.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['kalachakra.membership'].search([('id','=',int(m.id))]).unlink()


