from odoo import models, fields,api,_
from odoo.exceptions import UserError
from datetime import timedelta
from dateutil.relativedelta import relativedelta

class AccountMove(models.Model):
    _inherit = 'account.move'

    @api.depends(
        'line_ids.matched_debit_ids.debit_move_id.move_id.payment_id.is_matched',
        'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual',
        'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual_currency',
        'line_ids.matched_credit_ids.credit_move_id.move_id.payment_id.is_matched',
        'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual',
        'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual_currency',
        'line_ids.debit',
        'line_ids.credit',
        'line_ids.currency_id',
        'line_ids.amount_currency',
        'line_ids.amount_residual',
        'line_ids.amount_residual_currency',
        'line_ids.payment_id.state',
        'line_ids.full_reconcile_id')
    def _compute_amount(self):
        super(AccountMove, self)._compute_amount()

        for move in self:
            if move.move_type != 'out_invoice' or move.payment_state not in ['paid','in_payment']:
                continue

            membership_lines = move.invoice_line_ids.filtered(lambda l: l.product_id.is_membership)
            if not membership_lines:
                continue

            existing_membership = self.env['dev.membership'].search([
                ('invoice_id', '=', move.id),
                ('partner_id', '=', move.partner_id.id),
                ('state', 'in', ['confirm','active'])
            ])

            if existing_membership:
                for membership in existing_membership:
                    membership.action_active_membership()
                continue

            for line in membership_lines:
                product = line.product_id

                last_active_membership = self.env['dev.membership'].search([
                    ('partner_id', '=', move.partner_id.id),
                    ('state', 'in',  ['draft', 'active', 'confirm'])
                ], order='to_date desc', limit=1)

                from_date = (last_active_membership.to_date + timedelta(days=1)) if last_active_membership else (
                    move.invoice_date or fields.Date.today())
                to_date = self._calculate_to_date(from_date, product.interval, int(line.quantity))

                membership_vals = {
                    'partner_id': move.partner_id.id,
                    'product_id': product.id,
                    'membership_fees': line.price_subtotal,
                    'from_date': from_date,
                    'to_date': to_date,
                    'date': from_date,
                    'duration': int(line.quantity),
                    'interval': product.interval,
                    'company_id': move.company_id.id,
                    'user_id': product.product_tmpl_id.user_id.id,
                    'invoice_id': move.id,
                    'state': 'confirm',
                }
                membership = self.env['dev.membership'].create(membership_vals)
                membership.action_active_membership()
                move.partner_id.is_member = True

    def _calculate_to_date(self, from_date, interval, duration):
        if interval == 'year':
            return from_date + relativedelta(years=duration) - timedelta(days=1)
        elif interval == 'month':
            return from_date + relativedelta(months=duration) - timedelta(days=1)
        elif interval == 'days':
            return from_date + timedelta(days=duration)
        return from_date

    def button_draft(self):
        res = super(AccountMove, self).button_draft()
        self._reset_membership_state()
        return res

    def button_cancel(self):
        res = super(AccountMove, self).button_cancel()
        self._reset_membership_state()
        return res

    def _reset_membership_state(self):
        for move in self:
            memberships = self.env['dev.membership'].search([
                ('invoice_id', '=', move.id),
                ('state', '=', 'active')
            ])
            for membership in memberships:
                membership.write({'state': 'confirm'})
