import random
import string
from django.contrib import admin
from django.http import HttpRequest
from django.http.response import HttpResponse
from django.db.models import Sum
from api.recharge.recharge import distributeCommission

from distributors.models import Commission, Distributors
from helper import calculateCumulativeAmount
from sschedule import scheduleAnyTask
from .models import (
    Notification,
    RechargeErrors,
    Retailer,
    Recharge,
    RetailerAadhaarData,
    RetailerPANInfo,
    Wallet,
    Transaction,
)
from django.contrib.admin.models import LogEntry


def checkUserRoleExists(userRole, roles):
    rslt = False

    for role in roles:
        if str(role).lower() == str(userRole).lower():
            rslt = True
            break

    return rslt


class RetailerInline(admin.StackedInline):
    model = Retailer
    extra = 0
    exclude = []

    def get_exclude(self, request, obj):
        exs = super().get_exclude(request, obj)

        if request.user.is_superuser:
            return exs
        roles = request.user.groups.all()
        if checkUserRoleExists("Super Distributor", roles):
            return ["user", "password"]
        elif checkUserRoleExists("Distributor", roles):
            return ["distributor", "user", "password"]


# Register your models here.
def active_selected_record(self, request, queryset):
    queryset.update(is_active=True)


def inactive_selected_record(self, request, queryset):
    queryset.update(is_active=False)


class RetailerAdmin(admin.ModelAdmin):

    list_display = [
        "name",
        "mobile",
        "wallet_balance",
        "is_kyc",
        "is_kyc_activated",
        "distributor",
        "is_active",
        "transaction_in_progress",
    ]
    search_fields = ["name", "mobile", "email"]

    list_filter = [
        "distributor",
        "transaction_in_progress",
        "is_kyc",
        "is_kyc_activated",
    ]

    actions = ["calculateCumulativeAmount", "calculate"]

    def calculateCumulativeAmount(self, request, queryset):
        for obj in queryset:
            rtrs = Retailer.objects.filter(id=obj.id)
            for rtr in rtrs:
                txs = Transaction.objects.filter(retailer=rtr, status=1)
                last_cumulative_amount = 0
                for obj in txs:
                    if obj.transaction_type == 1:
                        obj.cumulative_amount = last_cumulative_amount + float(
                            obj.deduction_amount
                        )
                    elif obj.transaction_type == 2:
                        obj.cumulative_amount = last_cumulative_amount - float(
                            obj.deduction_amount
                        )

                    last_cumulative_amount = obj.cumulative_amount

                    obj.save()
                Wallet.objects.filter(retailer=rtr).update(
                    amount=last_cumulative_amount
                )

    def calculate(self, request, queryset):
        # wlt = Wallet.objects.filter(is_active=True, amount__lt=0).aggregate(sum_amount=Sum("amount"))
        # print(f"Wallet Balance: {wlt['sum_amount']}")

        for obj in queryset:
            credit_txs = Transaction.objects.filter(
                retailer=obj, status=1, transaction_type=1
            ).aggregate(sum_amount=Sum("deduction_amount"))

            debit_txs = Transaction.objects.filter(
                retailer=obj, status=1, transaction_type=2
            ).aggregate(sum_amount=Sum("deduction_amount"))

            commsn_txs = Transaction.objects.filter(
                retailer=obj, status=1, transaction_type=2
            ).aggregate(sum_amount=Sum("commission_amount"))

            if not debit_txs["sum_amount"]:
                debit_txs["sum_amount"] = 0

            if not credit_txs["sum_amount"]:
                credit_txs["sum_amount"] = 0

            if commsn_txs:
                if not commsn_txs["sum_amount"]:
                    commsn_txs["sum_amount"] = 0
            else:
                commsn_txs = {"sum_amount": 0}

            Wallet.objects.filter(retailer=obj).update(
                deposit=credit_txs["sum_amount"],
                credit=debit_txs["sum_amount"],
                commission=commsn_txs["sum_amount"],
            )

    class Media:
        js = (
            "js/jquery/jquery.min.js",
            "lib/helper.js",
            "lib/admin_retailer.js",
        )

    def get_list_filter(self, request):
        qs = super().get_list_filter(request)

        if request.user.is_superuser:
            return qs
        roles = request.user.groups.all()
        if checkUserRoleExists("Super Distributor", roles):
            return []
        elif checkUserRoleExists("Distributor", roles):
            return []

    def wallet_balance(self, obj):
        wlt = Wallet.objects.get(retailer=obj)
        if wlt:
            return wlt.amount
        else:
            return 0

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        if request.user.is_superuser:
            return qs
        roles = request.user.groups.all()
        if checkUserRoleExists("Super Distributor", roles):
            ids = (
                Distributors.objects.exclude(super_distributor=None)
                .filter(super_distributor__user=request.user, is_active=True)
                .values_list("id", flat=True)
            )
            return qs.filter(distributor__id__in=ids)
        elif checkUserRoleExists("Distributor", roles):
            return qs.filter(distributor__user=request.user)

        return qs

    def get_exclude(self, request, obj):
        exs = super().get_exclude(request, obj)

        if request.user.is_superuser:
            return exs
        roles = request.user.groups.all()
        if checkUserRoleExists("Super Distributor", roles):
            return ["user", "password"]
        elif checkUserRoleExists("Distributor", roles):
            return ["distributor", "user", "password"]

    def save_model(self, request, obj, form, change):
        if not change:
            if not request.user.is_superuser:
                su = Distributors.objects.get(user=request.user)
                obj.distributor = su
                obj.password = "@24Welcome"

            obj.created_by = request.user

        super().save_model(request, obj, form, change)

    def response_add(self, request, obj):
        Wallet.objects.create(retailer=obj, amount=0)
        return super().response_add(request, obj)


class WalletAdmin(admin.ModelAdmin):

    list_display = [
        "retailer",
        "deposit",
        "credit",
        "commission",
        "amount",
        "is_active",
        "created_on",
    ]
    list_filter = ["retailer"]

    actions = ["calculate"]

    def calculate(self, request, queryset):
        rtrs = Retailer.objects.all()
        for rtr in rtrs:
            credit_txs = Transaction.objects.filter(
                retailer=rtr, status=1, transaction_type=1
            ).aggregate(sum_amount=Sum("deduction_amount"))

            debit_txs = Transaction.objects.filter(
                retailer=rtr, status=1, transaction_type=2
            ).aggregate(sum_amount=Sum("deduction_amount"))

            commsn_txs = Transaction.objects.filter(
                retailer=rtr, status=1, transaction_type=2
            ).aggregate(sum_amount=Sum("commission_amount"))

            if not debit_txs["sum_amount"]:
                debit_txs["sum_amount"] = 0

            if not credit_txs["sum_amount"]:
                credit_txs["sum_amount"] = 0

            if not commsn_txs["sum_amount"]:
                commsn_txs["sum_amount"] = 0

            Wallet.objects.filter(retailer=rtr).update(
                deposit=credit_txs["sum_amount"],
                credit=debit_txs["sum_amount"],
                commission=commsn_txs["sum_amount"],
            )

    def save_model(self, request, obj, form, change):
        if not change:
            obj.created_by = request.user

        super().save_model(request, obj, form, change)


class RechargeAdmin(admin.ModelAdmin):

    date_hierarchy = "date"
    list_filter = ["retailer", "operator", "service", "status"]
    search_fields = ["order_id", "recharge_id", "api_transaction_id"]
    list_per_page = 1000

    list_display = [
        "order_id",
        "operator",
        "mobile",
        "status",
        "date",
        "retailer",
        "is_active",
        "amount",
        "deduction_amount",
        "commission_amount",
    ]
    actions = ["mark_as_paid"]

    def mark_as_paid(self, request, queryset):
        for obj in queryset:
            obj.status = 1
            obj.save()

    def getUniqueID(self):

        N = 7

        return "".join(random.choices(string.ascii_uppercase + string.digits, k=N))

    def init_comm(self, request, queryset):
        for rech in queryset:
            rtr = rech.retailer
            oprtr = rech.operator
            cmsn = Commission.objects.get(distributor=rtr.distributor, operator=oprtr)

            print(cmsn)
            distributeCommission(cmsn, rech.amount)

    def save_model(self, request, obj, form, change):
        if not change:
            obj.created_by = request.user

        objOld = Recharge.objects.get(id=obj.id)
        if objOld.status is None or objOld.status == "":
            if obj.status != "" and obj.status == "1":
                order_id = self.getUniqueID()
                tnx_id = self.getUniqueID()
                obj.order_id = order_id

                Transaction.objects.create(
                    order_id=order_id,
                    tnx_id=tnx_id,
                    source=2,
                    operator=obj.operator,
                    retailer=obj.retailer,
                    transaction_type=2,
                    amount=obj.amount,
                    deduction_amount=obj.deduction_amount,
                    commission_amount=obj.commission_amount,
                    cumulative_amount=0,
                    date=obj.date,
                    status=1,
                    recharge=obj,
                    remark="Manual transfer in this",
                )

        super().save_model(request, obj, form, change)


class TransactionAdmin(admin.ModelAdmin):

    list_display = [
        "order_id",
        "date",
        "source",
        "transaction_type",
        "status",
        "amount",
        "deduction_amount",
        "commission_amount",
        "cumulative_amount",
        "retailer",
        "tnx_id",
        "operator",
    ]
    list_per_page = 1000

    date_hierarchy = "date"
    list_filter = [
        "retailer",
        "transaction_type",
        "source",
        "status",
        "tnx_id",
        "operator",
    ]

    actions = ["approvePayment", "reset_amount", "scheduleCalculateCumulative", 'update_manule']

    def update_manule(self, request, queryset):
        Transaction.objects.filter(order_id="Manual").update(status=1)

    def reset_amount(self, request, queryset):
        trans = Transaction.objects.all()
        for obj in trans:
            if obj.source == 1:
                obj.deduction_amount = obj.amount
                obj.save()

    def scheduleCalculateCumulative(self, request, queryset):
        scheduleAnyTask(
            calculateCumulativeAmount,
            (),
        )

    def approvePayment(self, request, queryset):
        for obj in queryset:
            if obj.transaction_type == 1:
                wlt = Wallet.objects.filter(retailer=obj.retailer)
                if len(wlt) > 0:
                    wlt = wlt[0]
                    if obj.source == 1:
                        if obj.status == 2:
                            obj.status = 1
                            obj.save()

                            wlt.amount = float(wlt.amount) + float(obj.amount)
                            wlt.save()
                else:
                    obj.status = 1
                    obj.save()
                    Wallet.objects.create(retailer=obj.retailer, amount=obj.amount)

    def save_model(self, request, obj, form, change):
        if not change:
            obj.created_by = request.user

        super().save_model(request, obj, form, change)


class NotificationAdmin(admin.ModelAdmin):

    list_display = [
        "title",
        "retailer",
        "is_sean",
        "created_on",
    ]


class LogEntryAdmin(admin.ModelAdmin):
    list_display = (
        "user",
        "content_type",
        "object_repr",
        "action_flag",
        "change_message",
        "action_time",
    )
    list_filter = ("user", "action_flag", "content_type")
    # search_fields = ["object_repr", "change_message"]

    def get_queryset(self, request: HttpRequest):
        qs = super().get_queryset(request)

        # date = datetime.now().date()
        # qs = qs.exclude(user__username="npathak56")
        # temp = qs.filter(user__username="TECH075", action_time__date=date)
        # temp.delete()

        return qs


class RechargeErrorsAdmin(admin.ModelAdmin):
    date_hierarchy = "created_on"
    list_filter = ["recharge", "retailer"]
    list_display = [
        "error",
        "recharge",
        "retailer",
        "created_on",
    ]


class RetailerPANInfoAdmin(admin.ModelAdmin):
    list_display = ["retailer", "pan_number", "full_name", "category", "created_on"]
    date_hierarchy = "created_on"
    list_filter = ["retailer", "category"]


class RetailerAadhaarDataAdmin(admin.ModelAdmin):
    list_display = ["retailer", "full_name", "aadhaar_number", "dob", "created_on"]
    date_hierarchy = "created_on"
    list_filter = ["retailer"]


admin.site.register(RechargeErrors, RechargeErrorsAdmin)
admin.site.register(Retailer, RetailerAdmin)
admin.site.register(Wallet, WalletAdmin)
admin.site.register(Recharge, RechargeAdmin)
admin.site.register(Transaction, TransactionAdmin)
admin.site.register(Notification, NotificationAdmin)
admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(RetailerPANInfo, RetailerPANInfoAdmin)
admin.site.register(RetailerAadhaarData, RetailerAadhaarDataAdmin)
# admin.site.register(Operator, Operator)

admin.site.add_action(active_selected_record)
admin.site.add_action(inactive_selected_record)
