import logging
from datetime import date, timedelta, timezone
from django.conf import settings
from django.template.loader import render_to_string
from django_q.tasks import async_task, schedule
from django_q.models import Schedule
from django.db.models import Q
from uncloud_pay.models import Bill, Payment
from uncloud_pay.selectors import has_enough_balance, get_balance_for_user
from .models import VMInstance

log = logging.getLogger(__name__)

def send_warning_email(bill, html_message):
    schedule('django.core.mail.send_mail',
             'Renewal Warning',
             None,
             settings.RENEWAL_FROM_EMAIL,
             [bill.owner.email],
             html_message,
             schedule_type=Schedule.ONCE,
             next_run=timezone.now() + timedelta(hours=1))

def charge_open_bills():
    un_paid_bills = Bill.objects.filter(status="new")
    for bill in un_paid_bills:
        date_diff = (date.today() - bill.due_date.date()).days
        # If there is not enough money in the account 7 days before renewal, the system sends a warning
        # If there is not enough money in the account 3 days before renewal, the system sends a 2nd warning
        # If on renewal date there is not enough money in the account, delete the instance
        if date_diff == 7:
            if not has_enough_balance(bill.owner):
                context = {'name': bill.owner.name, 'message': "You don't have enough balance for renewal... upload to your account _here"}
                html_message = render_to_string('matrixhosting/emails/renewal_warning.html', context)
                send_warning_email(bill, html_message)
        elif date_diff == 3:
            if not has_enough_balance(bill.owner):
                context = {'name': bill.owner.name, 'message': "You don't have enough balance for renewal... Your instance will be deleted in 3 days"}
                html_message = render_to_string('matrixhosting/emails/renewal_warning.html', context)
                send_warning_email(bill, html_message)
        elif date_diff <= 0:
            if not has_enough_balance(bill.owner):
                VMInstance.delete_for_bill(bill)
            else:
                try:
                    balance = get_balance_for_user(bill.owner)
                    if balance < 0:
                       payment = Payment.objects.create(owner=bill.owner, amount=balance, source='stripe')
                       if payment:
                           bill.close(status="paid")
                    bill.close(status="cancelled")
                except Exception as e:
                    log.error(f"It seems that there is issue in payment for {bill.owner.name}", e)
                    # do nothing
            

def process_recurring_orders():
    """
    Check for pending recurring and charge it and generate bills or send the customer warning
    """
    Bill.create_bills_for_all_users()

def delete_instance(instance_id):
    VMInstance.objects.delete(instance_id)