from .models import *
from django.template.loader import render_to_string
from django.utils.translation import get_language, activate
from datetime import datetime, timedelta
import json


def get_user_subscribes_that_is_going_to_finish():
    user_subscribes = SubscribeForUser.objects.filter(
        enable=True,
        subscribe__price__gt=0,
        paid_period_to_DT__lt=datetime.now() + timedelta(days=3),
        paid_period_to_DT__gt=datetime.now()
    )

    return user_subscribes


def extension_free_subscribes():
    subscribe = get_null_price_subscribe()
    if not subscribe:
        return None

    user_subscribes = SubscribeForUser.objects.filter(
        enable=True,
        subscribe=subscribe
    )
    for user_subscribe in user_subscribes:
        user_subscribe.extension()
        msg = f'{str(user_subscribe)} free subscribe extended'
        print(msg)

    return True


def finish_user_subscribes():

    finished_user_subscribes = SubscribeForUser.objects.filter(
        enable=True, paid_period_to_DT__lt=datetime.now()
    )
    finished_user_subscribes.update(enable=False)
    for finished_user_subscribe in finished_user_subscribes:
        msg = f'{str(finished_user_subscribe)} subscribe finished and switch to free'
        print(msg)
        subscribe_user_to_null_price_subscribe(finished_user_subscribe.user)

    return True


def create_subscribe_by_data(create_kwargs):
    subscribe = create_kwargs['subscribe']
    create_kwargs.update({
        'paid_period_from_DT': datetime.now(),
        'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
        'enable': False
    })
    subscribe_for_user = SubscribeForUser.objects.create(**create_kwargs)
    return subscribe_for_user


def check_option_in_cur_user_subscribe(user, option_name):
    if not user or not user.is_active or not user.is_authenticated:
        return False

    user_subscribe = get_cur_user_subscribe(user)
    try:
        option = SubscribeOption.objects.get(
            rel_subscribes_for_option=user_subscribe.subscribe,
            name_ru__iexact=option_name
        )
        return True
    except SubscribeOption.DoesNotExist:
        return False



def get_null_price_subscribe():
    subscribes_null_price = Subscribe.objects.filter(
        enable=True,
        price=0
    )
    if subscribes_null_price:
        return subscribes_null_price[0]

    return None

def subscribe_user_to_null_price_subscribe(user):
    subscribe = get_null_price_subscribe()
    if not subscribe:
        return None

    kwargs = {
        'user': user,
        'subscribe': subscribe,
    }

    subscribe_for_user = create_subscribe_by_data(kwargs)
    subscribe_for_user = subscribe_for_user.activate()

    return subscribe_for_user


def get_cur_user_subscribe(user):

    if not user or not user.is_active or not user.is_authenticated:
        return None

    try:
        user_subscribe = SubscribeForUser.objects.get(enable=True, user=user)
    except SubscribeForUser.DoesNotExist:
        user_subscribe = subscribe_user_to_null_price_subscribe(user)
    except SubscribeForUser.MultipleObjectsReturned:
        user_subscribes = SubscribeForUser.objects.filter(enable=True, user=user).order_by('-paid_period_to_DT')
        user_subscribe = user_subscribes[0]
        user_subscribes.exclude(id=user_subscribe.id).delete()

    return user_subscribe


def get_subscribes_w_options(user=None, check_subscribe_orders=False):
    all_options = SubscribeOption.objects.filter(enable=True)
    subscribes = Subscribe.objects.filter(enable=True)
    for subscribe in subscribes:
        subscribe_options_ids = subscribe.options.values_list('id', flat=True)
        subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
        if user and check_subscribe_orders:
            order = subscribe.get_last_order(user)
            if order and order.status not in ['charged']:
                error = f'{order.status}'
                if 'status' in order.json_data and 'failure_message' in order.json_data['status']:
                    error = f'{error} ({order.json_data["status"]["failure_message"]})'
                subscribe.order_error = error

    return subscribes, all_options


def check_n_enable_subscribe_by_order(order):

    if order and order.enable:
        if order.status == 'charged':
            order = order.activate_subscribe_for_user()

    return order


def get_profile_subscribe_page_content_Dict(request, check_orders_required=False):

    try:

        from GeneralApp.funcs import get_and_set_lang
        lang = get_and_set_lang(request)

        data = {}
        if request.body:
            data = json.loads(request.body)
        # check_orders_required = False
        if data and 'check_orders_required' in data: #Требуется проверка статусов заказов
            check_orders_required = data['check_orders_required']
        # all_options = SubscribeOption.objects.filter(enable=True)


        subscribes = []
        subscribe_for_user = None
        all_options = []

        orders = None
        if request.user and request.user.is_authenticated:
            from BillingApp.funcs import get_orders_for_user, get_order_status
            orders = get_orders_for_user(request.user)
            if orders:
                if check_orders_required:
                    for order in orders:
                        order = get_order_status(order)
                        order = check_n_enable_subscribe_by_order(order)
                        subscribe_for_user = order.subscribe_for_user

                    subscribes, all_options = get_subscribes_w_options(
                        request.user, check_subscribe_orders=True)

                    check_orders_required = False
                else:
                    check_orders_required = True

        if not subscribes:
            subscribes, all_options = get_subscribes_w_options()

        # if not subscribes_for_user:
        subscribes_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)

        if not subscribes_for_user:
            tpl_name = 'blocks/profile/b_subscribe_variants.html'
        else:
            tpl_name = 'blocks/profile/b_subscribe_current.html'
            subscribe_for_user = subscribes_for_user[0]
            subscribe_options_ids = subscribe_for_user.subscribe.options.values_list('id', flat=True)
            subscribe_for_user.subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)

        # subscribes = Subscribe.objects.filter(enable=True)
        # for subscribe in subscribes:
        #     subscribe_options_ids = subscribe.options.values_list('id', flat=True)
        #     subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)

        Dict = {
            'subscribe_for_user': subscribe_for_user,
            'subscribes': subscribes,
        }

        html = render_to_string(tpl_name, Dict, request=request)
        return {
            'html': html,
            'check_orders_required': check_orders_required,
        }

    except Exception as e:
        msg = f'show_cur_subscribe_ajax Error = {str(e)}'
        return msg