from django.shortcuts import render, redirect, HttpResponse, get_object_or_404
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 django.utils import timezone
from django.utils.dateparse import parse_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.utils.text import slugify
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
from django.db.models import Sum
from django.views.decorators.csrf import csrf_exempt

def index(request):
    if request.user.is_superuser or request.user.is_staff:
        users = User.objects.count()
        orders = Order.objects.count()
        torders = Order.objects.filter(ordered_date=date.today(), approved=True).count()
        products = Product.objects.count()
        contacts = Contact.objects.count()
        all = Order.objects.filter(approved=True).order_by('-id')[:50]
        insertcodes = OrderUserProfile.objects.values_list('order', flat=True)
        
        try:
            total_sales = int(Order.objects.filter(status="delivered").aggregate(Sum("Amount"))["Amount__sum"] or 0)
        except Exception:
            total_sales = 0

        try:
            today_sales = int(Order.objects.filter(status="delivered", ordered_date=date.today()).aggregate(Sum("Amount"))["Amount__sum"] or 0)
        except Exception:
            today_sales = 0
            
        try:
            monthly_sales = int(Order.objects.filter(status="delivered", ordered_date__month=date.today().month).aggregate(Sum("Amount"))["Amount__sum"] or 0)
        except Exception:
            monthly_sales = 0

        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,
            "insertcodes": insertcodes
        }
        return render(request, "adminApp/index.html", context)
    else:
        return redirect("login")



def login(request):
    if request.user.is_authenticated and (request.user.is_staff or request.user.is_superuser):
        return redirect("adminhomepage")
    if request.method == "POST":
        username = request.POST.get("username", "")
        password = request.POST.get("password", "")
        user = authenticate(username=username, password=password)
        if user is not None:
            lg(request, user)
            return redirect("adminhomepage")
        else:
            messages.error(request, "Invalid username or password.")
    return render(request, "adminApp/login.html")


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


@user_passes_test(lambda u: u.is_staff)
def allorders(request):
    if request.user.is_superuser or request.user.is_staff:
        today = datetime.today()
        q = request.GET.get('q', None)
        if q is None or q == '':
            all = Order.objects.all().order_by('-id')[:200]
            day = 0
        else:
            try:
                day = today - timedelta(days=int(q))
                all = Order.objects.filter(ordered_date__gt=day, approved=True).order_by('-id')
            except Exception:
                day = today
                all = Order.objects.all().order_by('-id')[:200]
        return render(request, "adminApp/allorders.html", {"all": all, "day": day})
    else:
        return redirect("login")
   
   
   
   
def approveorder(request):
    if request.user.is_superuser or request.user.is_staff:
        orders = Order.objects.filter(approved=False).order_by('-id')
        return render(request, "adminApp/approveorder.html", {"all": orders})
    else:
        return redirect("login")
        
        
        
@user_passes_test(lambda u: u.is_staff)
def approvedorder(request, id):
    if request.user.is_superuser or request.user.is_staff:
        order = Order.objects.get(id=id)
        order.approved = True
        order.save()
        return redirect('approveorder')
    else:
        return redirect("login")
        
@user_passes_test(lambda u: u.is_staff)
def deleteorderap(request, id):
    if request.user.is_superuser or request.user.is_staff:
        try:
            o = Order.objects.get(id=id)
            o.delete()
        finally:
            return redirect("approveorder")
    else:
        return redirect('login')
        

def createorder(request):
    users = User.objects.all()
    products = Product.objects.all()
    return render(request, 'adminapp/createorder.html', {"users": users, "products":products})




def confirmorder(request):
    # try:
    #     check_validation = request.session['validated_payment']
    #     del request.session['validated_payment']
    # except:
    #     check_validation = False
    #
    # if not check_validation:
    #     return redirect("cart_detail")
    u = Profile.objects.get(user=request.POST['username'])
    total = request.POST['amount']

    # try:
    #     total = request.POST['forcalonly']
    #     payment_getway = "Khalti"
    # except:
    # total = request.session['ime_pay_amount']
    # del request.session['ime_pay_amount']
    # payment_getway = "ImePay"
    # print("Total from except block:", total)
    #
    # payment_success = "Successful payment"
    # print("total:", total)
    # print(request.session['cart'])
    # print("debugggggg")
    user = User.objects.get(id=request.POST['username'])

    newOrder = Order.objects.create(username=user, Amount=total, item_length=1,approved=True)
    # ordersummary = OrderUserProfile.objects.create(order=newOrder, user=request.user)
    # newOrder.save()
    grabber = Order.objects.get(id=newOrder.id)
    print("grabber:", grabber)
    temp_products = ""
    temp_autocode = ""

    a = OrderItem.objects.create(product=Product.objects.get(
            id=request.POST['product']), order=grabber,
            quantity=int(request.POST['quantity']))
    temp_products = Product.objects.get(id=request.POST['product']).name
    a.save()
    for i in range(0, a.quantity):
        ordersummary = OrderUserProfile.objects.create(order=newOrder, user=user)
        ordersummary.category = temp_products
        ordersummary.code = request.POST['code']
        ordersummary.save()
    print(temp_products)

    # for key in request.session['cart']:
    #     u.points = int(u.points) + int(Product.objects.get(name=request.session['cart'][key]['name']).points)
    #     u.save()
    order_items = OrderItem.objects.filter(order=grabber)  # added during ime_pay
    # if request.method == "POST":
    #     # print("grabber:", grabber)
    #     # print("Inside post")
    #     # order_items = OrderItem.objects.filter(order=grabber)
    #     # print("lllllllll")
    #     # print(order_items)
    #     # print("pppppppp")
    try:
        for o in OrderItem.objects.filter(order=grabber):
            if "-destination_one" in request.POST.keys():
                o.destination_one = request.POST["-destination_one"]
                o.save()

        for o in OrderItem.objects.filter(order=grabber):
            if "-destination_two" in request.POST.keys():
                o.destination_two = request.POST["-destination_two"]
                o.save()

        for o in OrderItem.objects.filter(order=grabber):
            if "-destination_three" in request.POST.keys():
                o.destination_three = request.POST["-destination_three"]
                o.save()

    except Exception as e:

        print(e)
    #         for o in OrderItem.objects.filter(product__is_details=True, order=grabber):
    #             temp = list(SerialCode.objects.filter(
    #                 product__name=o.product.name, status="Active"))
    #
    #             limiter = o.quantity
    #             limiter = int(limiter)
    #             if limiter > len(temp):
    #                 result = limiter - int(len(temp))
    #             try:
    #                 comment = f"There is request of {limiter} number of code for {o.product.name}, we only have {len(temp)}. Total Shortage of {result}"
    #                 ShortageRegister.objects.create(user=request.user, product=o.product, req_for=limiter,
    #                                                 we_have=len(temp), remarks=comment)
    #             except:
    #                 print('registering failed')
    #             for s in temp[:limiter]:
    #                 # u = UserProfile.objects.create(
    #                 #     user=request.user, code=s.serial_key, category=s.product.name)
    #                 temp_autocode += s.serial_key + "\n"
    #                 u.save()
    #                 s.status = "Used"
    #                 s.save()
    #             ordersummary.code = temp_autocode
    #             ordersummary.save()
    #             print("temp_autocode:", temp_autocode)
    #             print("ordersummary.code:", ordersummary.code)
    #
    #
    #
    #     except Exception as e:
    #
    #         print(e)
    # cart = Cart(request)
    # cart.clear()
    try:
        discount = request.session['showdis']
    except:
        print("no showdis.")
        discount = 0.0
    print("Disount =>>>>>>>>>>>>>>>>>>>>>>>", discount)
    try:
        del request.session['validated_payment']
    except:
        print('validated_payment dummy')
    try:
        del request.session['showdis']
    except:
        print("showdis dummy")
    try:
        del request.session['discount']  # remember to add in production
    except:
        print("discount dummy")

    # send order email to orders@xygame.co
    # buyer_username = request.POST['username']
    # html_content = render_to_string("adminApp/admin_order_email.html",
    #                                 {'buyer_username': buyer_username, "orderid": newOrder.id})
    # text_content = strip_tags(html_content)
    # email = EmailMultiAlternatives(
    #     # subject
    #     f"Order received from {buyer_username}",
    #     # content
    #     text_content,
    #     # from email
    #     settings.EMAIL_HOST_USER,
    #     # list of recipient
    #     ['orders@xygame.co', ],
    # )
    # email.attach_alternative(html_content, "text/html")
    # email.send(fail_silently=True)

    ##################################################
    # price_before_discount = float(int(total) * 100) / (100 + 2)
    # online_txn_fee = float(total) - float(price_before_discount)
    # sub_total = float(price_before_discount) + float(discount)
    # number_of_products = order_items.count()
    ##################################################
    ##################################################
    # price_before_discount = round((float(total) * 100) / (100 + 2), 1)
    # online_txn_fee = round(float(total) - float(price_before_discount), 1)
    # sub_total = float(price_before_discount) + float(discount)
    #
    # number_of_products = order_items.count()
    # print("number_of_products:", number_of_products)

    ##################################################
    #
    # try:
    #     send_order_notification(request.user.username)
    # except:
    #     print("Something went wrong while sending notification")

    # context = {"total": total, "orderid": newOrder.id, "date": date.today,"discount":discount,"stotal":int(float(total)+float(discount))}
    # context = {"total": total, "orderid": newOrder.id, "date": date.today, "discount": float(discount),
    #            "stotal": (float(total) + float(discount)), 'items': order_items,
    #            'price_before_discount': price_before_discount, 'online_txn_fee': online_txn_fee, 'sub_total': sub_total,
    #            'payment_success': payment_success, 'number_of_products': number_of_products,
    #            'payment_method': newOrder.payment_getway}
    return render(request, "adminApp/createorder.html")


def getproduct(request, id):
    product = Product.objects.get(id=id)
    return JsonResponse({"d1": product.detail_one, "d2": product.detail_two, "d3": product.detail_three, "automable": product.is_details})


def userdetail(request, id):
    user = User.objects.get(id=id)
    verified = Profile.objects.get(user=user).is_verified
    return JsonResponse({"verified": verified})





@user_passes_test(lambda u: u.is_staff)
def todaysorders(request):
    if request.user.is_superuser or request.user.is_staff:
        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_staff)
def updateorder(request, id):
    if request.user.is_superuser or request.user.is_staff:
        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_staff)
def deleteorder(request, id):
    if request.user.is_superuser or request.user.is_staff:
        try:
            o = Order.objects.get(id=id)
            o.delete()
        finally:
            return redirect("allorders")
    else:
        return redirect('login')


@user_passes_test(lambda u: u.is_staff)
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_staff)
def categories(request):
    if request.method == "POST":
        header_name = request.POST.get('header')
        if not header_name or header_name.startswith('--'):
            header = Header.objects.first()
            if not header:
                header = Header.objects.create(name="Default")
        else:
            header, _ = Header.objects.get_or_create(name=header_name)
        category_name = request.POST.get('category_name', '')
        slug = request.POST.get('slug') or slugify(category_name)
        featured = request.POST.get('featured') == '1'
        is_bestselling = request.POST.get('is_bestselling') == '1'

        c = Category.objects.create(header=header, name=category_name, slug=slug, featured=featured, is_bestselling=is_bestselling)
        if 'image' in request.FILES:
            c.image = request.FILES['image']
        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_staff)
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.get('category', category.name)
        if 'featured' in request.POST:
            category.featured = (request.POST.get('featured') == '1')
        if 'is_bestselling' in request.POST:
            category.is_bestselling = (request.POST.get('is_bestselling') == '1')
        elif 'best_selling' in request.POST:
            category.is_bestselling = (request.POST.get('best_selling') == '1')
        slug = request.POST.get('slug') or slugify(category.name)
        category.slug = slug
        if 'header' in request.POST:
            header_name = request.POST['header']
            header = Header.objects.filter(name=header_name).first()
            if header:
                category.header = header

        if 'image' in request.FILES:
            category.image = request.FILES['image']
        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_staff)
def deletecategory(request, id):
    c = Category.objects.get(id=id)
    c.delete()
    return redirect("categories")


@user_passes_test(lambda u: u.is_staff)
def subcategories(request):
    if request.method == "POST":
        cat_name = request.POST.get('category')
        category = Category.objects.filter(name=cat_name).first()
        subcategory_name = request.POST.get('subcategory', '')
        slug = request.POST.get('slug') or slugify(subcategory_name)
        image = request.FILES.get('img')
        SubCategory.objects.create(
            category=category, name=subcategory_name, 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_staff)
def updatesubcategories(request, id):
    subcategory = SubCategory.objects.get(id=id)
    product = subcategory
    category = Category.objects.all()
    if request.method == "POST":
        if 'category' in request.POST:
            cat = Category.objects.filter(name=request.POST['category']).first()
            if cat:
                subcategory.category = cat
        subcategory.name = request.POST.get('subcategory', subcategory.name)
        slug = request.POST.get('slug') or slugify(subcategory.name)
        subcategory.slug = slug
        if 'img' in request.FILES:
            subcategory.image = request.FILES['img']
        subcategory.save()

        if 'title' in request.POST:
            product.title = request.POST['title']
        if 'publisher' in request.POST:
            product.publisher = request.POST['publisher']
        if 'developer' in request.POST:
            product.developer = request.POST['developer']
        if 'release_date' in request.POST:
            product.release_date = request.POST['release_date']
        if 'genre' in request.POST:
            product.genre = request.POST['genre']
        if 'language' in request.POST:
            product.language = request.POST['language']
        if 'region' in request.POST:
            product.region = request.POST['region']
        if 'platform' in request.POST:
            product.platform = request.POST['platform']
        if 'delivery_time' in request.POST:
            product.delivery_time = request.POST['delivery_time']
        if 'delivery_platform' in request.POST:
            product.delivery_mode = request.POST['delivery_platform']
        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_staff)
def deletesubcategories(request, id):
    c = SubCategory.objects.get(id=id)
    c.delete()
    return redirect("subcategories")


@user_passes_test(lambda u: u.is_staff)
def addproduct(request):
    if request.method == "POST":
        sub_val = request.POST.get('subcategory')
        subcategory = None
        if sub_val:
            if str(sub_val).isdigit():
                subcategory = SubCategory.objects.filter(id=int(sub_val)).first()
            if not subcategory:
                subcategory = SubCategory.objects.filter(name=sub_val).first()

        if not subcategory:
            messages.error(request, "Please select a valid SubCategory.")
            categories = Category.objects.all().prefetch_related('subcategory_set')
            subcategory_list = SubCategory.objects.all().select_related('category')
            return render(request, "adminApp/addproduct.html", {"subcategory": subcategory_list, "categories": categories})

        name = request.POST.get('product_name', '').strip()
        try:
            price = float(request.POST.get('normalprice', 0))
        except (ValueError, TypeError):
            price = 0.0

        try:
            dprice = float(request.POST.get('distributorprice', 0))
        except (ValueError, TypeError):
            dprice = 0.0

        image = request.FILES.get('img')
        description = request.POST.get('editor1', '')
        slug = request.POST.get('slug', '').strip()
        if not slug and name:
            slug = slugify(name)

        try:
            points = int(request.POST.get('points', 0))
        except (ValueError, TypeError):
            points = 0

        auto_val = request.POST.get('auto', '0')
        is_details = (auto_val == "1")

        details_one = request.POST.get('d1') or None
        details_two = request.POST.get('d2') or None
        details_three = request.POST.get('d3') or None

        tag = request.POST.get('tag', '0')
        popular = 1 if tag == "1" else 0

        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,
            popular=popular
        )
        u.save()
        messages.success(request, f"Product '{name}' added successfully!")
        return redirect("products")

    categories = Category.objects.all().prefetch_related('subcategory_set')
    subcategory = SubCategory.objects.all().select_related('category')
    context = {"subcategory": subcategory, "categories": categories}
    return render(request, "adminApp/addproduct.html", context)

@user_passes_test(lambda u: u.is_staff)
def products(request):
    products = Product.objects.all().select_related('subcategory', 'subcategory__category')
    displays = Product.objects.filter(display=False)
    show = displays.exists()
    context = {"products": products, "show": show}
    return render(request, "adminApp/allproducts.html", context)


@user_passes_test(lambda u: u.is_staff)
def hidecat(request, id):
    cat = Category.objects.get(id=id)
    subcat = SubCategory.objects.filter(category=cat)
    cat.display = False
    subcat.update(display=False)
    cat.save()
    for sbcat in subcat:
        products = Product.objects.filter(subcategory=sbcat)
        products.update(display=False)
    return redirect('categories')

@user_passes_test(lambda u: u.is_staff)
def showcat(request, id):
    cat = Category.objects.get(id=id)
    subcat = SubCategory.objects.filter(category=cat)
    cat.display = True
    subcat.update(display=True)
    cat.save()
    for sbcat in subcat:
        products = Product.objects.filter(subcategory=sbcat)
        products.update(display=True)
    return redirect('categories')


@user_passes_test(lambda u: u.is_staff)
def hidedigitalproduct(request):
    products = Product.objects.filter(isdigital=True)
    categories = Category.objects.filter(isdigital=True)
    subcategories = SubCategory.objects.filter(isdigital=True)
    products.update(display=False)
    categories.update(display=False)
    subcategories.update(display=False)
    return redirect('products')


@user_passes_test(lambda u: u.is_staff)
def showdigitalproduct(request):
    products = Product.objects.filter(isdigital=True)
    categories = Category.objects.filter(isdigital=True)
    subcategories = SubCategory.objects.filter(isdigital=True)
    products.update(display=True)
    categories.update(display=True)
    subcategories.update(display=True)
    return redirect('products')


@user_passes_test(lambda u: u.is_staff)
def deleteproduct(request, id):
    p = Product.objects.get(id=id)
    name = p.name
    p.delete()
    messages.success(request, f"Product '{name}' deleted successfully!")
    return redirect("products")


@user_passes_test(lambda u: u.is_staff)
def updateproduct(request, id):
    product = Product.objects.get(id=id)
    if request.method == "POST":
        product.name = request.POST.get('product_name', product.name).strip()
        slug = request.POST.get('slug', '').strip()
        if slug:
            product.slug = slug
        elif not product.slug and product.name:
            product.slug = slugify(product.name)

        if 'subcategory' in request.POST:
            sub_val = request.POST['subcategory']
            sub = None
            if str(sub_val).isdigit():
                sub = SubCategory.objects.filter(id=int(sub_val)).first()
            if not sub:
                sub = SubCategory.objects.filter(name=sub_val).first()
            if sub:
                product.subcategory = sub

        product.description = request.POST.get('editor1', product.description)
        if request.POST.get('normalprice'):
            try:
                product.price = float(request.POST['normalprice'])
            except (ValueError, TypeError):
                pass
        if request.POST.get('distributorprice'):
            try:
                product.dprice = float(request.POST['distributorprice'])
            except (ValueError, TypeError):
                pass

        try:
            if 'points' in request.POST and request.POST['points']:
                product.points = int(request.POST['points'])
        except (ValueError, TypeError):
            pass

        if request.POST.get('outofstock') == "1":
            product.outofstock = True
        else:
            product.outofstock = False

        if request.POST.get('auto') == "1":
            product.is_details = True
        else:
            product.is_details = False

        if 'img' in request.FILES:
            product.image = request.FILES['img']

        product.detail_one = request.POST.get('d1') or None
        product.detail_two = request.POST.get('d2') or None
        product.detail_three = request.POST.get('d3') or None

        if 'tag' in request.POST:
            product.popular = 1 if request.POST.get('tag') == "1" else 0

        product.save()
        messages.success(request, f"Product '{product.name}' updated successfully!")
        return redirect("products")

    categories = Category.objects.all().prefetch_related('subcategory_set')
    subcategory = SubCategory.objects.all().select_related('category')
    context = {"product": product, "subcategory": subcategory, "categories": categories}
    return render(request, "adminApp/update/updateproduct.html", context)


@user_passes_test(lambda u: u.is_staff)
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_staff)
def normalusers(request):
    all = Profile.objects.filter(distributor=False).order_by('-id')[:200]
    context = {"all": all}
    return render(request, "adminApp/normalusers.html", context)


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


@user_passes_test(lambda u: u.is_staff)
def enable_disable_user(request, id):
    user = User.objects.get(id=id)
    if request.method == 'POST':
        user.is_active = request.POST['is_active']
        user.save()
        return redirect("normalusers")
    context = {
        'user': user
    }

    return render(request, "adminApp/update/enabledisableuser.html", context)
    
    
@user_passes_test(lambda u: u.is_staff)
def order_history(request, id):
    user = User.objects.get(id=id)
    order = Order.objects.filter(username_id=id).order_by('-id')
    order_item = OrderItem.objects.filter(order__in=order)
    order_user_profile = OrderUserProfile.objects.filter(user_id=id)

    return render(request, "adminApp/order_history.html", {"user": user, "order": order, "order_item": order_item, "order_user_profile": order_user_profile})


@user_passes_test(lambda u: u.is_staff)
def getordercount(request):
    count = Order.objects.filter(approved=False).count()
    return JsonResponse({"count": count})
    
from adminapp.forms import StaffRegisterFormModelForm

@user_passes_test(lambda u: u.is_superuser)
def staffusers(request):
    print("User saved")
    if request.method == 'POST':
        print("inside")
        form = StaffRegisterFormModelForm(request.POST)
        if form.is_valid():
            user = User(
                first_name=request.POST['first_name'],
                last_name=request.POST['last_name'],
                username=request.POST['username'],
                email=request.POST['email'],
                is_staff=request.POST['is_staff'],
            )
            user.save()
            print("User saved1")
            user.set_password(request.POST['password1'])
            user.save()
            print("User saved2")
            phone_number = request.POST['phone_number'],
            print(phone_number)
            phone = phone_number[0]
            print("User saved3")
            Profile.objects.create(user=user, phone=phone)
            return redirect("staffusers")
    all = User.objects.filter(is_staff=True)
    form = StaffRegisterFormModelForm()
    context = {"all": all, 'form': form}
    return render(request, "adminApp/staffusers.html", context)


@user_passes_test(lambda u: u.is_staff)
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_staff)
def managecode(request):
    all = list(reversed(SerialCode.objects.all()))
    return render(request, "adminApp/managecode.html", {"all": all})


@user_passes_test(lambda u: u.is_staff)
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 = Testimonials.objects.create(image=image, rating=rating, date=date, title=title, review=review, name=name)
        testimonials.save()
    return render(request, "adminApp/testimonials.html", {"t": t})


@user_passes_test(lambda u: u.is_staff)
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_staff)
def managereviews(request):
    t = list(reversed(Review.objects.all()))
    return render(request, "adminApp/managereviews.html", {"t": t})


@user_passes_test(lambda u: u.is_staff)
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_staff)
def getordercount(request):
    count = len(Order.objects.filter(status="Pending"))
    return JsonResponse({"count": count})


@user_passes_test(lambda u: u.is_staff)
def mainbanners(request):
    all = list(reversed(MainBanner.objects.all()))
    if request.method == "POST":
        images = request.FILES.getlist('img')
        link = request.POST.get('link', '').strip()
        if not link:
            link = "https://xygame.co"
        elif not (link.startswith("http://") or link.startswith("https://") or link.startswith("/")):
            link = "https://" + link
        is_mobile = request.POST.get('is_mobileview', '0') == '1'
        count = 0
        for img in images:
            MainBanner.objects.create(image=img, link=link, is_mobileview=is_mobile)
            count += 1
        if count > 0:
            messages.success(request, f"{count} main banner(s) uploaded successfully!")
        else:
            messages.error(request, "Please select at least one image file.")
        return redirect("mainbanners")
    return render(request, "adminApp/mainbanner.html", {"all": all})


@user_passes_test(lambda u: u.is_staff)
def updatemainbanner(request, id):
    try:
        banner = MainBanner.objects.get(id=id)
    except MainBanner.DoesNotExist:
        messages.error(request, "Banner not found.")
        return redirect("mainbanners")

    if request.method == "POST":
        link = request.POST.get('link', '').strip()
        if link:
            if not (link.startswith("http://") or link.startswith("https://") or link.startswith("/")):
                link = "https://" + link
            banner.link = link
        is_mobile = request.POST.get('is_mobileview', '0') == '1'
        banner.is_mobileview = is_mobile
        if 'img' in request.FILES and request.FILES['img']:
            banner.image = request.FILES['img']
        banner.save()
        messages.success(request, "Banner updated successfully!")
        return redirect("mainbanners")

    return render(request, "adminApp/update/updatemainbanner.html", {"banner": banner})


@user_passes_test(lambda u: u.is_staff)
def deletemainbanners(request, id):
    if request.user.is_superuser or request.user.is_staff:
        try:
            d = MainBanner.objects.get(id=id)
            d.delete()
            messages.success(request, "Banner deleted successfully!")
        except MainBanner.DoesNotExist:
            messages.error(request, "Banner not found.")
    return redirect("mainbanners")


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


@user_passes_test(lambda u: u.is_staff)
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_staff)
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_staff)
def navbanner(request):
    all = list(reversed(NavBanner.objects.all()))
    if request.method == "POST":
        img = request.FILES.get('img')
        link = request.POST.get('link', '')
        if img:
            NavBanner.objects.create(image=img, link=link)
        return redirect("navbanner")
    return render(request, "adminApp/navbanner.html", {"all": all})


@user_passes_test(lambda u: u.is_staff)
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_staff)
def insertcode(request):
    user = User.objects.filter(is_superuser=False)
    q = request.GET.get('q', None)
    order_obj = OrderUserProfile.objects.filter(order_id=q).first()
    # if q is None:
    #     q = User.objects.first().username

    if request.method == "POST":
        # orderuserprofile = OrderUserProfile.objects.get(order_id=request.POST['order_id'])
        # orderuserprofile.code = request.POST['code']
        # orderuserprofile.category = request.POST['category']
        # orderuserprofile.save()
        
        form_value = request.POST.copy()
        form_value.getlist('odr_id')
        for key in form_value.getlist('odr_id'):

            order_obj = OrderUserProfile.objects.get(id=key)

            order_obj.code = request.POST['code'+key]
            order_obj.category = request.POST['category'+key]
            order_obj.save()

        # 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()
    # alls = OrderUserProfile.objects.all()
    alls = OrderUserProfile.objects.filter(user=order_obj.user)
    # return render(request, "adminApp/insertcode.html", {"users": user, "msg": msg, "alls": alls, "username": q})
    return render(request, "adminApp/insertcode.html", {"result": order_obj, "users": user, "alls": alls, "order_id": 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})

def _parse_coupon_dt(dt_str):
    if not dt_str:
        return None
    dt = parse_datetime(dt_str)
    if dt and timezone.is_naive(dt):
        dt = timezone.make_aware(dt)
    return dt


@user_passes_test(lambda u: u.is_staff)
def addcoupon(request):
    context = {}
    if request.method == "POST":
        product_id = request.POST.get('product')
        coupon_code = request.POST.get('coupon_code', '').strip().upper()
        discount_type = request.POST.get('discount_type', 'price')

        isprice_discount = (discount_type == 'price')
        ispercent_discount = (discount_type == 'percent')

        try:
            discount_price = float(request.POST.get('discount_price', 0) or 0)
        except (ValueError, TypeError):
            discount_price = 0.0

        try:
            discount_percent = int(request.POST.get('discount_percent', 0) or 0)
        except (ValueError, TypeError):
            discount_percent = 0

        valid_from = _parse_coupon_dt(request.POST.get('valid_from')) or timezone.now()
        valid_to = _parse_coupon_dt(request.POST.get('valid_to'))

        try:
            max_uses = int(request.POST.get('max_uses', 0) or 0)
        except (ValueError, TypeError):
            max_uses = 0

        try:
            max_uses_per_user = int(request.POST.get('max_uses_per_user', 1) or 1)
        except (ValueError, TypeError):
            max_uses_per_user = 1

        try:
            min_purchase_amount = float(request.POST.get('min_purchase_amount', 0) or 0)
        except (ValueError, TypeError):
            min_purchase_amount = 0.0

        isactive = (request.POST.get('isactive', '1') == '1')

        if not coupon_code:
            messages.error(request, "Coupon code is required.", extra_tags='admin')
        elif not product_id:
            messages.error(request, "Please select an item/product for this coupon.", extra_tags='admin')
        elif Coupons.objects.filter(coupon_code__iexact=coupon_code).exists():
            messages.error(request, f"Coupon code '{coupon_code}' already exists.", extra_tags='admin')
        else:
            Coupons.objects.create(
                product_id=product_id,
                coupon_code=coupon_code,
                isprice_discount=isprice_discount,
                ispercent_discount=ispercent_discount,
                discount_price=discount_price,
                discount_percent=discount_percent,
                valid_from=valid_from,
                valid_to=valid_to,
                max_uses=max_uses,
                max_uses_per_user=max_uses_per_user,
                min_purchase_amount=min_purchase_amount,
                isactive=isactive,
            )
            messages.success(request, f"Coupon '{coupon_code}' created successfully!", extra_tags='admin')
            return redirect("addcoupon")

    all_coupons = list(Coupons.objects.select_related('product', 'product__subcategory').order_by('-id'))
    allproducts = Product.objects.filter(display=True).select_related('subcategory').order_by('subcategory__name', 'name')
    context["products"] = allproducts
    context["all"] = all_coupons
    return render(request, "adminApp/addcoupon.html", context)


@user_passes_test(lambda u: u.is_staff)
def updatecoupon(request, id):
    coupon = get_object_or_404(Coupons, id=id)

    if request.method == "POST":
        product_id = request.POST.get('product')
        if product_id:
            coupon.product_id = product_id

        if 'coupon_code' in request.POST:
            code = request.POST['coupon_code'].strip().upper()
            if code and not Coupons.objects.filter(coupon_code__iexact=code).exclude(id=id).exists():
                coupon.coupon_code = code

        discount_type = request.POST.get('discount_type')
        if discount_type:
            coupon.isprice_discount = (discount_type == 'price')
            coupon.ispercent_discount = (discount_type == 'percent')

        if 'discount_price' in request.POST:
            try:
                coupon.discount_price = float(request.POST['discount_price'] or 0)
            except (ValueError, TypeError):
                pass

        if 'discount_percent' in request.POST:
            try:
                coupon.discount_percent = int(request.POST['discount_percent'] or 0)
            except (ValueError, TypeError):
                pass

        if request.POST.get('valid_from'):
            parsed_from = _parse_coupon_dt(request.POST['valid_from'])
            if parsed_from:
                coupon.valid_from = parsed_from
        if request.POST.get('valid_to'):
            parsed_to = _parse_coupon_dt(request.POST['valid_to'])
            if parsed_to:
                coupon.valid_to = parsed_to

        if 'max_uses' in request.POST:
            try:
                coupon.max_uses = int(request.POST['max_uses'] or 0)
            except (ValueError, TypeError):
                pass

        if 'max_uses_per_user' in request.POST:
            try:
                coupon.max_uses_per_user = int(request.POST['max_uses_per_user'] or 1)
            except (ValueError, TypeError):
                pass

        if 'min_purchase_amount' in request.POST:
            try:
                coupon.min_purchase_amount = float(request.POST['min_purchase_amount'] or 0)
            except (ValueError, TypeError):
                pass

        if 'isactive' in request.POST:
            coupon.isactive = (request.POST['isactive'] == '1')

        coupon.save()
        messages.success(request, f"Coupon '{coupon.coupon_code}' updated successfully.", extra_tags='admin')
        return redirect("addcoupon")

    allproducts = Product.objects.filter(display=True).select_related('subcategory').order_by('subcategory__name', 'name')
    return render(request, "adminApp/update/updatecoupon.html", {"coupon": coupon, "products": allproducts})


@user_passes_test(lambda u: u.is_staff)
def deletecoupon(request, id):
    if request.user.is_superuser or request.user.is_staff:
        c = Coupons.objects.filter(id=id).first()
        if c:
            c.delete()
            messages.success(request, "Coupon deleted successfully.", extra_tags='admin')
    return redirect("addcoupon")


@user_passes_test(lambda u: u.is_staff)
def coupon_redemptions(request):
    redemptions = list(CouponReedemBy.objects.select_related('coupon', 'user', 'order').order_by('-id')[:200])
    return render(request, "adminApp/coupon_redemptions.html", {"redemptions": redemptions})


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


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


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


@user_passes_test(lambda u: u.is_staff)
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_staff)
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_staff

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

class ContactDetailView(AdminStaffRequiredMixin,DetailView):
    model = Contact

@user_passes_test(lambda u: u.is_staff)
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_staff)
def delete_uploaded_code(request, id):
    if request.method == "POST":
        # UserProfile.objects.get(id=id).delete()
        OrderUserProfile.objects.get(id=id).delete()
        return redirect('/admin')
    else:
        # code = UserProfile.objects.get(id=id)
        code = OrderUserProfile.objects.get(id=id)
        return render(request, 'xygaming_app/confirm_delete_uploaded_code.html')

@user_passes_test(lambda u:u.is_staff)
def update_uploaded_code(request,id):
    result = OrderUserProfile.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_staff)
def header(request):
    if request.method == "POST":
        header_name = request.POST.get('header', '').strip()
        if header_name:
            Header.objects.create(name=header_name)
            messages.success(request, f"Header '{header_name}' added successfully.")

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

@user_passes_test(lambda u:u.is_staff)
def deleteHeader(request,id):
    try:
        header_obj = Header.objects.get(id=id)
        header_name = header_obj.name
        header_obj.delete()
        messages.success(request, f"Header '{header_name}' deleted successfully.")
    except Header.DoesNotExist:
        messages.error(request, f"Header #{id} does not exist.")

    return redirect('/admin/header')

@user_passes_test(lambda u:u.is_staff)
def editHeader(request,id):
    try:
        header = Header.objects.get(id=id)
    except Header.DoesNotExist:
        messages.error(request, f"Header #{id} does not exist.")
        return redirect('/admin/header')

    if request.method == "POST":
        name = request.POST.get('header', '').strip()
        if name:
            header.name = name
            header.save()
            messages.success(request, f"Header '{name}' updated successfully.")
        return redirect('/admin/header')

    try:
        return render(request, 'adminApp/update/updateheader.html', {'header': header})
    except Exception:
        return render(request, 'adminapp/update/updateheader.html', {'header': header})

@user_passes_test(lambda u:u.is_staff)
def addinfo(request):
    if request.method == 'POST':
        title = request.POST['title']
        description_text = request.POST['description_text']
        is_draft = request.POST['is_draft']
        last_update_by = request.user.id
        r = Info.objects.create(title=title, description_text=description_text, is_draft=is_draft, last_update_by_id=last_update_by)
        return redirect("publishedinfo")
    return render(request, 'adminapp/addinfo.html')
    
    
@user_passes_test(lambda u:u.is_staff)
def errorinfo(request):
    error = Error.objects.all()
    if request.method == 'POST':
        title = request.POST['title']
        description_text = request.POST['description_text']
        active = request.POST['is_active']
        if error:
            for err in error:
                err.title = title
                err.description_text = description_text
                err.is_active = active
                err.save()
                return redirect("errorinfo")
        r = Error.objects.create(title=title, description_text=description_text, is_active=active)
        return redirect("errorinfo")
    return render(request, 'adminapp/errorinfo.html', {"errors":error})
    
    
    

@user_passes_test(lambda u:u.is_staff)
def updateinfo(request, id=None):
    info = Info.objects.get(id=id)
    if request.method == 'POST':
        info.title = request.POST['title']
        info.description_text = request.POST['description_text']
        info.is_draft = request.POST['is_draft']
        info.last_update_by_id = request.user.id
        info.save()
        return redirect("publishedinfo")
    return render(request, 'adminapp/update/updateinfo.html', {'info': info})

@user_passes_test(lambda u:u.is_staff)
def publishedinfo(request):
    infos = Info.objects.exclude(is_draft=True)
    context = {
        'infos': infos,
    }
    return render(request, 'adminapp/publishedinfo.html', context)

@user_passes_test(lambda u:u.is_staff)
def draftinfo(request):
    infos = Info.objects.filter(is_draft=True)
    context = {
        'infos': infos,
    }
    return render(request, 'adminapp/draftinfo.html', context)

@user_passes_test(lambda u:u.is_staff)
def deleteinfo_draft(request, id=None):
    Info.objects.get(id=id).delete()
    return redirect("draftinfo")

@user_passes_test(lambda u:u.is_staff)
def deleteinfo_published(request, id=None):
    Info.objects.get(id=id).delete()
    return redirect("publishedinfo")
    

@csrf_exempt
@user_passes_test(lambda u: u.is_staff)
def bulkdeletereviews(request):
    if request.method == 'POST':
        review_ids = request.POST.getlist('id[]')
        print(review_ids)
        for id in review_ids:
            review = Review.objects.get(pk=id)
            review.delete()
        return redirect('managereviews')
        
        
@csrf_exempt
def superuser_fcmtoken_save(request):
    token = request.POST.get("token")
    print("token:", token)
    print("debugerr3")

    try:
        print("debugerr2")
        fcmtoken, _ = FcmToken.objects.get_or_create(user_id=request.user.id)
        print("fcmtoken:", fcmtoken)
        print("debugerr1")
        if str(fcmtoken.fcm_token) == str(token):
            print("Same Shoudl not save")
            return HttpResponse("True")
        fcmtoken.fcm_token = token
        print("debugerr999999")
        fcmtoken.save()
        print("debugerr666")
        return HttpResponse("True")
    except Exception as e:
        return HttpResponse("False")


@user_passes_test(lambda u: u.is_staff)
def manage_payment_qr(request):
    payment_qr = PaymentQR.objects.filter(is_active=True).first()
    if not payment_qr:
        payment_qr = PaymentQR.objects.first()

    if request.method == "POST":
        title = request.POST.get("title", "Official Payment QR Code")
        instructions = request.POST.get("instructions", "")
        
        if not payment_qr:
            payment_qr = PaymentQR(title=title, instructions=instructions, is_active=True)
        else:
            payment_qr.title = title
            payment_qr.instructions = instructions
            payment_qr.is_active = True
        
        if 'img' in request.FILES:
            payment_qr.image = request.FILES['img']
        
        payment_qr.save()
        messages.success(request, "Payment QR Code updated successfully!")
        return redirect("manage_payment_qr")

    return render(request, "adminApp/manage_payment_qr.html", {"payment_qr": payment_qr})
