from tokenize import blank_re
import uuid

from django.db import models

from authenticate.models import User
from exam.models import Exam
from institute.models import Institute
from plan.models import UserPlan, InstitutePlan, Environment
from quiz.models import Quiz


class Transaction(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT, db_index=True)
    authority = models.CharField(max_length=180, db_index=True)
    amount = models.IntegerField()
    status = models.CharField(max_length=20, null=True, blank=True)
    ref_id = models.CharField(max_length=180, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    modified_at = models.DateTimeField(auto_now_add=True, db_index=True)
    meta = models.JSONField(null=True, blank=True)

    def __str__(self):
        return str(self.user)


InitialBalance = 'initial_balance'
ExamPurchase = 'exam_purchase'
QuizPurchase = 'quiz_purchase'
BalancePurchase = 'balance_purchase'
SubscriptionPurchase = 'subscription_purchase'


class UserBalanceHistory(models.Model):
    id = models.UUIDField(primary_key=True, unique=True,
                          db_index=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(
        User, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    amount = models.IntegerField()
    reason = models.CharField(max_length=25)
    exam = models.ForeignKey(
        Exam, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    quiz = models.ForeignKey(
        Quiz, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    plan = models.ForeignKey(
        UserPlan, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    reason_meta_data = models.JSONField()
    remaining_balance = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    modified_at = models.DateTimeField(auto_now=True, db_index=True)

    @staticmethod
    def create_initial_balance_history(user):
        initial_user_balance = Environment.get_active_environment().initial_user_balance
        return UserBalanceHistory.objects.create(amount=initial_user_balance, reason=InitialBalance,
                                                 user=user, remaining_balance=initial_user_balance,
                                                 reason_meta_data={})

    @staticmethod
    def get_last_user_balance(user):
        last_user_balance_history = UserBalanceHistory.objects.filter(
            user=user).order_by('created_at').last()

        if last_user_balance_history is None:
            last_user_balance_history = UserBalanceHistory.create_initial_balance_history(
                user)

        return last_user_balance_history


class InstituteBalanceHistory(models.Model):
    id = models.UUIDField(primary_key=True, unique=True,
                          db_index=True, default=uuid.uuid4, editable=False)
    institute = models.ForeignKey(
        Institute, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    amount = models.IntegerField()
    reason = models.CharField(max_length=25)
    exam = models.ForeignKey(
        Exam, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    quiz = models.ForeignKey(
        Quiz, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    plan = models.ForeignKey(
        InstitutePlan, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    reason_meta_data = models.JSONField()
    remaining_balance = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    modified_at = models.DateTimeField(auto_now=True, db_index=True)

    @staticmethod
    def get_last_institute_balance(institute):
        last_institute_balance_history = InstituteBalanceHistory.objects.filter(
            institute=institute).order_by('created_at').last()

        if last_institute_balance_history is None:
            last_institute_balance_history = InstituteBalanceHistory.objects.create(institute=institute, amount=0, reason=InitialBalance, remaining_balance=0,
                                                                                    reason_meta_data={})

        return last_institute_balance_history


class WikiazmaBalanceHistory(models.Model):
    id = models.UUIDField(primary_key=True, unique=True,
                          db_index=True, default=uuid.uuid4, editable=False)
    amount = models.IntegerField()
    reason = models.CharField(max_length=25)
    institute = models.ForeignKey(
        Institute, on_delete=models.SET_NULL, null=True, blank=True, db_index=True)
    exam = models.ForeignKey(
        Exam, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    quiz = models.ForeignKey(
        Quiz, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    user = models.ForeignKey(
        User, on_delete=models.SET_NULL, db_index=True, null=True, blank=True)
    reason_meta_data = models.JSONField()
    remaining_balance = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    modified_at = models.DateTimeField(auto_now=True, db_index=True)

    @staticmethod
    def get_last_wikiazma_balance():
        last_wikiazma_balance_history = WikiazmaBalanceHistory.objects.order_by(
            'created_at').last()

        if last_wikiazma_balance_history is None:
            last_wikiazma_balance_history = WikiazmaBalanceHistory.objects.create(amount=0, reason=InitialBalance, remaining_balance=0,
                                                                                  reason_meta_data={})

        return last_wikiazma_balance_history
