from django.db.models import Sum
from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth import authenticate, login as lg, logout as op
from django.contrib.auth.decorators import login_required
from xygaming_app.models import *
from django.contrib.auth.models import User
from django.utils.timezone import datetime
from datetime import date
from django.http import JsonResponse
from datetime import timedelta
from django.contrib.auth.decorators import user_passes_test
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib import messages


def index(request):
    if request.user.is_superuser:
        users = len(User.objects.all())
        orders = len(Order.objects.all())
        torders = len(Order.objects.filter(ordered_date=date.today()))
        products = len(Product.objects.all())
        contacts = len(Contact.objects.all())
        all = list(reversed(Order.objects.all()))[:100]

        ############################################
        total_sales = int(Order.objects.filter(status="delivered").aggregate(Sum("Amount"))["Amount__sum"])
        today_sales = int(Order.objects.filter(status="delivered", ordered_date=date.today()).aggregate(Sum("Amount"))["Amount__sum"])
        monthly_sales = int(Order.objects.filter(status="delivered", ordered_date__month=date.today().month).aggregate(Sum("Amount"))["Amount__sum"])
        ############################################

        context = {"Nusers": users, "Norders": orders, "Nproducts": products,
                   "all": all, "torders": torders, 'ncontacts': contacts, "total_sales": total_sales,
                   "today_sales": today_sales, "monthly_sales": monthly_sales}
        return render(request, "adminapp/index.html", context)
    else:
        return redirect("login")


def login(request):
    if request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(username=username, password=password)
        print(user)
        if user is not None:
            lg(request, user)
            return redirect("adminhomepage")
    return render(request, "adminapp/login.html")


@login_required
def logout(request):
    op(request)
    return redirect("/")


@user_passes_test(lambda u: u.is_superuser)
def allorders(request):
    if request.user.is_superuser:
        today = datetime.today()

        q = request.GET.get('q', None)
        if q is None:
            all = Order.objects.all()
            day = 0
        else:
            try:
                day = today - timedelta(days=int(q))
            except:
                day = today
            # day = today - timedelta(days=int(q))
            all = Order.objects.filter(ordered_date__gt=day)
            # return HttpResponse(day)
        return render(request, "adminApp/allorders.html", {"all": all, "day": day})
    else:
        return redirect("login")


@user_passes_test(lambda u: u.is_superuser)
def todaysorders(request):
    if request.user.is_superuser:
        all = list(reversed(Order.objects.filter(ordered_date=date.today())))
        return render(request, "adminApp/todaysorders.html", {"all": all})
    else:
        return redirect("login")


@user_passes_test(lambda u: u.is_superuser)
def updateorder(request, id):
    if request.user.is_superuser:
        order = Order.objects.get(id=id)
        if request.method == "POST":
            status = request.POST['status']
            order.status = status
            order.admin_username = request.user.username
            order.save()
            return redirect("allorders")
        return render(request, "adminApp/update/updateorder.html", {"o": order})
    else:
        return redirect("login")


@user_passes_test(lambda u: u.is_superuser)
def deleteorder(request, id):
    if request.user.is_superuser:
        try:
            o = Order.objects.get(id=id)
            o.delete()
        finally:
            return redirect("allorders")
    else:
        return redirect('login')


@user_passes_test(lambda u: u.is_superuser)
def vieworder(request, id):
    orderItem = OrderItem.objects.filter(order__id=id)
    order = Order.objects.get(id=id)
    profile = Profile.objects.get(
        user=User.objects.get(username=order.username))
    if profile.distributor:
        distributor = True
    else:
        distributor = False
    print(distributor)
    return render(request, "adminapp/vieworders.html", {"or": order, "ois": orderItem, "distributor": distributor})


@user_passes_test(lambda u: u.is_superuser)
def categories(request):
    if request.method == "POST":
        # header = request.POST['header']
        header = Header.objects.get(name=request.POST['header'])
        category = request.POST['category_name']
        slug = request.POST['slug']

        c = Category.objects.create(header=header, name=category, slug=slug)
        try:
            image = request.FILES['image']
            c.image = image
        finally:
            c.save()
    category = Category.objects.all()
    headers = Header.objects.all()
    context = {"category": category, 'headers': headers}
    return render(request, "adminApp/categories.html", context)


@user_passes_test(lambda u: u.is_superuser)
def updatecategory(request, id):
    category = Category.objects.get(id=id)
    now_header = category.header
    headers = Header.objects.all()
    if request.method == "POST":
        category.name = request.POST['category']
        category.featured = request.POST['featured']
        category.is_bestselling = request.POST['best_selling']
        category.slug = request.POST['slug']
        print(request.POST['header'])
        header = Header.objects.get(name=request.POST['header'])
        print(header)
        category.header = header
        try:
            image = request.FILES['image']
            category.image = image
            category.save()
        except:
            category.save()
        return redirect("categories")
    return render(request, "adminApp/update/updatecategories.html",
                  {"category": category, 'headers': headers, 'now_header': now_header})


@user_passes_test(lambda u: u.is_superuser)
def deletecategory(request, id):
    c = Category.objects.get(id=id)
    c.delete()
    return redirect("categories")


@user_passes_test(lambda u: u.is_superuser)
def subcategories(request):
    if request.method == "POST":
        category = Category.objects.get(name=request.POST['category'])
        slug = request.POST['slug']
        subcategory = request.POST['subcategory']
        try:
            image = request.FILES['img']
        except:
            image = None
        SubCategory.objects.create(
            category=category, name=subcategory, image=image, slug=slug)
    subcategory = SubCategory.objects.all()
    category = Category.objects.all()
    context = {"subcategory": subcategory, 'category': category}
    return render(request, "adminApp/subcategories.html", context)


@user_passes_test(lambda u: u.is_superuser)
def updatesubcategories(request, id):
    subcategory = SubCategory.objects.get(id=id)
    product = subcategory
    category = Category.objects.all()
    if request.method == "POST":
        subcategory.category = Category.objects.get(
            name=request.POST['category'])
        subcategory.name = request.POST['subcategory']
        subcategory.slug = request.POST['slug']
        try:
            subcategory.image = request.FILES['img']
        except:
            print('No image')
        subcategory.save()
        try:
            product.title = request.POST['title']
        except:
            product.title = None
        try:
            product.publisher = request.POST['publisher']
        except:
            product.publisher = None
        try:
            product.developer = request.POST['developer']
        except:
            product.developer = None
        try:
            product.release_date = request.POST['release_date']
        except:
            product.release_date = None
        try:
            product.genre = request.POST['genre']
        except:
            product.genre = None
        try:
            product.language = request.POST['language']
        except:
            product.language = None
        try:
            product.region = request.POST['region']
        except:
            product.region = None
        try:
            product.platform = request.POST['platform']
        except:
            product.platform = None
        try:
            product.delivery_time = request.POST['delivery_time']
        except:
            product.delivery_time = None
        try:
            product.delivery_mode = request.POST['delivery_platform']
        except:
            product.delivery_mode = None
        product.save()
        return redirect("subcategories")
    return render(request, "adminApp/update/updatesubcategories.html",
                  {"subcategory": subcategory, "category": category, "product": product})


@user_passes_test(lambda u: u.is_superuser)
def deletesubcategories(request, id):
    c = SubCategory.objects.get(id=id)
    c.delete()
    return redirect("subcategories")


@user_passes_test(lambda u: u.is_superuser)
def addproduct(request):
    if request.method == "POST":
        subcategory = SubCategory.objects.get(name=request.POST['subcategory'])
        name = request.POST['product_name']
        price = request.POST['normalprice']
        dprice = request.POST['distributorprice']
        image = request.FILES['img']
        description = request.POST['editor1']
        slug = request.POST['slug']
        try:
            points = request.POST['points']
        except:
            points = 0

        if request.POST['auto'] == "1":
            is_details = True
        else:
            is_details = False
        try:
            details_one = request.POST['d1']
        except:
            details_one = None
        try:
            details_two = request.POST['d2']
        except:
            details_two = None
        try:
            details_three = request.POST['d3']
        except:
            details_three = None
        u = Product.objects.create(subcategory=subcategory, name=name, price=price, dprice=dprice, image=image,
                                   is_details=is_details,
                                   detail_one=details_one, detail_two=details_two, detail_three=details_three,
                                   description=description, points=points, slug=slug)

        u.save()
        return redirect("products")
    subcategory = SubCategory.objects.all()
    context = {"subcategory": subcategory}
    return render(request, "adminApp/addproduct.html", context)


@user_passes_test(lambda u: u.is_superuser)
def products(request):
    products = Product.objects.all()
    context = {"products": products}
    return render(request, "adminApp/allproducts.html", context)


@user_passes_test(lambda u: u.is_superuser)
def deleteproduct(request, id):
    p = Product.objects.get(id=id)
    p.delete()
    return redirect("products")


@user_passes_test(lambda u: u.is_superuser)
def updateproduct(request, id):
    product = Product.objects.get(id=id)
    if request.method == "POST":

        product.name = request.POST['product_name']
        product.slug = request.POST['slug']
        product.subcategory = SubCategory.objects.get(
            name=request.POST['subcategory'])
        product.description = request.POST['editor1']
        product.price = request.POST['normalprice']
        product.dprice = request.POST['distributorprice']
        try:
            product.points = request.POST['points']
        except:
            print('no points')

        if request.POST['outofstock'] == "1":
            product.outofstock = True
        else:
            product.outofstock = False
        if request.POST['auto'] == "1":
            product.is_details = True
        else:
            product.is_details = False
        try:
            product.image = request.FILES['img']
        except:
            print('Exception')
        product.detail_one = request.POST['d1']
        product.detail_two = request.POST['d2']
        product.detail_three = request.POST['d3']
        product.save()

        return redirect("products")
    subcategory = SubCategory.objects.all()
    context = {"product": product, "subcategory": subcategory}
    return render(request, "adminApp/update/updateproduct.html", context)


@user_passes_test(lambda u: u.is_superuser)
def distributors(request):
    all = Profile.objects.filter(distributor=True)
    context = {"all": all}
    return render(request, "adminApp/distributors.html", context)


@user_passes_test(lambda u: u.is_superuser)
def normalusers(request):
    all = Profile.objects.filter(distributor=False)
    context = {"all": all}
    return render(request, "adminApp/normalusers.html", context)


@user_passes_test(lambda u: u.is_superuser)
def deleteuser(request, id):
    u = User.objects.get(id=id)
    u.delete()
    return redirect("normalusers")


@user_passes_test(lambda u: u.is_superuser)
def uploadcode(request):
    if request.method == "POST":
        product = request.POST['subcategory']
        code = request.POST['code']
        u = SerialCode.objects.create(
            product=Product.objects.get(name=product), serial_key=code)
        u.save()
    return render(request, "adminapp/uploadcode.html", {"subcategory": Product.objects.filter()})


@user_passes_test(lambda u: u.is_superuser)
def managecode(request):
    all = list(reversed(SerialCode.objects.all()))
    return render(request, "adminapp/managecode.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def managetestimonials(request):
    t = Testimonials.objects.all()
    if request.method == "POST":
        name = request.POST['name']
        image = request.FILES['img']
        rating = request.POST['rating']
        title = request.POST['title']
        review = request.POST['review']
        Testimonials.objects.create(
            image=image, rating=rating, date=date, title=title, review=review, name=name)
    return render(request, "adminapp/testimonials.html", {"t": t})


@user_passes_test(lambda u: u.is_superuser)
def deletetestimonials(request, id):
    if request.user.is_superuser:
        t = Testimonials.objects.get(id=id)
        t.delete()
    return redirect("managetestimonials")


@user_passes_test(lambda u: u.is_superuser)
def managereviews(request):
    t = list(reversed(Review.objects.all()))
    return render(request, "adminapp/managereviews.html", {"t": t})


@user_passes_test(lambda u: u.is_superuser)
def deletereviews(request, id):
    if request.user.is_superuser:
        t = Review.objects.get(id=id)
        t.delete()
    return redirect("managereviews")


@user_passes_test(lambda u: u.is_superuser)
def getordercount(request):
    count = len(Order.objects.filter(status="Pending"))
    return JsonResponse({"count": count})


@user_passes_test(lambda u: u.is_superuser)
def mainbanners(request):
    all = list(reversed(MainBanner.objects.all()))
    if request.method == "POST":
        MainBanner.objects.create(image=request.FILES['img'], link=request.POST['link'])
        return redirect("mainbanners")
    return render(request, "adminapp/mainbanner.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def deletemainbanners(request, id):
    if request.user.is_superuser:
        d = MainBanner.objects.get(id=id)
        d.delete()
    return redirect("mainbanners")


@user_passes_test(lambda u: u.is_superuser)
def subbanners(request):
    all = list(reversed(SubBanner.objects.all()))
    if request.method == "POST":
        SubBanner.objects.create(image=request.FILES['img'], link=request.POST['link'])
        return redirect("subbanners")
    return render(request, "adminapp/subbanner.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def deletesubbanners(request, id):
    if request.user.is_superuser:
        d = SubBanner.objects.get(id=id)
        d.delete()
    return redirect("subbanners")


@user_passes_test(lambda u: u.is_superuser)
def deletecode(request, id):
    c = SerialCode.objects.get(id=id)
    if request.user.is_superuser:
        c.delete()
    return redirect("managecode")


@user_passes_test(lambda u: u.is_superuser)
def navbanner(request):
    all = list(reversed(NavBanner.objects.all()))
    if request.method == "POST":
        NavBanner.objects.create(image=request.FILES['img'], link=request.POST['link'])
        return redirect("navbanner")
    return render(request, "adminapp/navbanner.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def deletenavbanner(request, id):
    if request.user.is_superuser:
        d = NavBanner.objects.get(id=id)
        d.delete()
    return redirect("navbanner")


@user_passes_test(lambda u: u.is_superuser)
def insertcode(request):
    user = User.objects.filter(is_superuser=False)
    q = request.GET.get('q', None)
    if q is None:
        q = User.objects.first().username
    msg = None
    if request.method == "POST":
        username = request.POST['username']
        u = User.objects.get(username=username)
        code = request.POST['code']
        category = request.POST['category']
        UserProfile.objects.create(user=u, category=category, code=code)
        msg = "Code sent successfully"
    alls = UserProfile.objects.filter()
    return render(request, "adminapp/insertcode.html", {"users": user, "msg": msg, "alls": alls, "username": q})


@user_passes_test(lambda u: u.is_superuser)
def addcoupon(request):
    if request.method == "POST":
        coupon = request.POST['coupon']
        price = request.POST['price']
        Coupons.objects.create(coupon=coupon, price=price)
    all = list(reversed(Coupons.objects.all()))
    return render(request, "adminapp/addcoupon.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def updatecoupon(request, id):
    c = Coupons.objects.get(id=id)
    if request.method == "POST":
        c.coupon = request.POST['coupon']
        c.price = request.POST['price']
        c.save()
        return redirect("addcoupon")
    return render(request, "adminapp/update/updatecoupon.html", {"c": c})


@user_passes_test(lambda u: u.is_superuser)
def deletecoupon(request, id):
    if request.user.is_superuser:
        c = Coupons.objects.get(id=id)
        c.delete()
    return redirect("addcoupon")


@user_passes_test(lambda u: u.is_superuser)
def codeshortage(request):
    all = list(reversed(ShortageRegister.objects.all()))
    return render(request, "adminapp/codeshortage.html", {"all": all})


@user_passes_test(lambda u: u.is_superuser)
def deletecodeshortage(request, id):
    ShortageRegister.objects.get(id=id).delete()
    return redirect("codeshortage")


@user_passes_test(lambda u: u.is_superuser)
def showrequestdistributor(request):
    r = RequestForDistributor.objects.all()
    return render(request, "adminapp/requestdistributor.html", {"r": r})


@user_passes_test(lambda u: u.is_superuser)
def acceptdistributorrequest(request, id):
    up = Profile.objects.get(user=User.objects.get(id=id))
    up.distributor = True
    up.save()
    zs = RequestForDistributor.objects.filter(
        user_profile__user=User.objects.get(id=id)).first()
    zs.delete()
    return redirect("showrequestdistributor")


@user_passes_test(lambda u: u.is_superuser)
def deletedistributorrequest(request, id):
    up = RequestForDistributor.objects.filter(
        user_profile__user=User.objects.get(id=id)).first()
    up.delete()
    return redirect("showrequestdistributor")


class AdminStaffRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_superuser


class ContactListView(AdminStaffRequiredMixin, ListView):
    paginate_by = 30
    model = Contact


class ContactDetailView(AdminStaffRequiredMixin, DetailView):
    model = Contact


@user_passes_test(lambda u: u.is_superuser)
def deleteContact(request, id):
    if request.method == "POST":
        Contact.objects.get(id=id).delete()
        return redirect('/admin/contact')
    else:
        contact = Contact.objects.get(id=id)
        return render(request, 'xygaming_app/contact_confirm_delete.html', {'contact': contact})


@user_passes_test(lambda u: u.is_superuser)
def delete_uploaded_code(request, id):
    if request.method == "POST":
        UserProfile.objects.get(id=id).delete()
        return redirect('/admin')
    else:
        code = UserProfile.objects.get(id=id)
        return render(request, 'xygaming_app/confirm_delete_uploaded_code.html')


@user_passes_test(lambda u: u.is_superuser)
def update_uploaded_code(request, id):
    result = UserProfile.objects.get(id=id)

    if request.method == "POST":
        code = request.POST['code']
        category = request.POST['category']
        result.code = code
        result.category = category
        result.save()
        messages.success(request, 'Code and Category are updated successfully.')

    return render(request, 'xygaming_app/update_uploaded_code.html', {'result': result})


@user_passes_test(lambda u: u.is_superuser)
def header(request):
    if request.method == "POST":
        header = request.POST['header']
        header_obj = Header.objects.create(name=header)
        header_obj.save()

    all_header = Header.objects.all().order_by('-time_stamp')
    context = {'all_header': all_header}
    return render(request, 'adminapp/header.html', context)


@user_passes_test(lambda u: u.is_superuser)
def deleteHeader(request, id):
    Header.objects.get(id=id).delete()

    return redirect('/admin/header')


@user_passes_test(lambda u: u.is_superuser)
def editHeader(request, id):
    header = Header.objects.get(id=id)
    if request.method == "POST":
        name = request.POST['header']
        header.name = name
        header.save()
        return redirect('/admin/header')
    return render(request, 'adminapp/update/updateheader.html', {'header': header})
