from django.shortcuts import render , redirect
import requests
from rest_framework import viewsets
from .models import *
from .serializers import FoodSerializer , SettingsSerializer 
from django.contrib.auth.decorators import user_passes_test

from rest_framework.response import Response
from rest_framework.decorators import api_view

from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import user_passes_test
import datetime
from django.utils import timezone
from django.http import JsonResponse
from django.template.loader import render_to_string
# اگر پکیج jdatetime را ندارید: pip install jdatetime
import jdatetime 
from django.core.paginator import Paginator # این را به ابتدای فایل اضافه کنید
from django.db import transaction
from django.db.models import Count
from django.db.models import ProtectedError





@api_view(['GET'])
def get_menu_data(request , cafe_slug):
    device_id = getattr(request, 'device_id', request.COOKIES.get('device_id', None))
    personal_discounts = {}
    recommendations = {} # تغییر از لیست به دیکشنری
    is_journalist = False

    if device_id:
        device_profile = DeviceProfile.objects.filter(device_id=device_id ,  cofe_owner__slug=cafe_slug).first()
        if device_profile and device_profile.is_journalist:
            is_journalist = True

        user_purchase_history = OrderItem.objects.filter(
            cofe_owner__slug=cafe_slug,
            order__device_id=device_id,
            order__status__in=['delivered', 'paid']
        ).values('food_id').annotate(times_bought=Count('order__id'))
        
        history_dict = {item['food_id']: item['times_bought'] for item in user_purchase_history}

        active_rules = SmartRule.objects.filter(is_active=True, cofe_owner__slug=cafe_slug)
        for rule in active_rules:
            times_bought = history_dict.get(rule.target_food_id, 0)
            if times_bought >= rule.min_purchases:
                if rule.rule_type == 'discount' and rule.discount_percent > 0 and not rule.suggested_food.is_deleted and rule.suggested_food.is_available:
                    personal_discounts[rule.target_food_id] = rule.discount_percent
                    
                if rule.rule_type == 'recommend' and rule.suggested_food and not rule.suggested_food.is_deleted and rule.suggested_food.is_available:
                    # استفاده از id برای جلوگیری از تکرار و تداخل آبجکت‌ها
                    recommendations[rule.suggested_food.id] = rule.suggested_food

    menu_data_for_response = [] 

    # ==========================================
    # اضافه کردن پیشنهادهای هوشمند به عنوان اولین دسته‌بندی
    # ==========================================
    if recommendations:
        serialized_recs = FoodSerializer(recommendations.values(), many=True).data

        rec_list = []
        for item in serialized_recs:
            rec_dict = dict(item)
            f_id = rec_dict['id']
            
            personal_discount = personal_discounts.get(f_id, 0)
            if is_journalist and personal_discount < 20:
                personal_discount = 20
                
            base_price = rec_dict['price']
            if personal_discount > 0:
                final_price = int(base_price - (base_price * personal_discount / 100))
                rec_dict['old_price_formatted'] = "{:,}".format(base_price) # قیمت خط‌خورده
            else:
                final_price = base_price
                
            rec_dict['price_formatted'] = "{:,}".format(final_price) # قیمت نهایی برای نمایش
            rec_list.append(rec_dict)
            
        menu_data_for_response.append({
            'category_id': 0,
            'category_name': '⭐ پیشنهاد ویژه',
            'category_icon': None,
            'category_fa': 'fa-star',
            'items': rec_list  # کلید items دقیقاً مطابق درخواست جاوااسکریپت
        })

    # ==========================================
    # اضافه کردن دسته‌های اصلی منو
    # ==========================================
    categories = category.objects.all().order_by('priority').filter(cofe_owner__slug=cafe_slug , is_deleted=False)
    for cat in categories:
        foods = cat.food_set.filter(is_available=True, is_deleted=False)
        
        if foods.exists():
            serialized_foods = FoodSerializer(foods, many=True).data
            food_list_for_cat = []
            
            for item in serialized_foods:
                food_dict = dict(item)
                f_id = food_dict['id']
                
                personal_discount = personal_discounts.get(f_id, 0)
                if is_journalist and personal_discount < 20:
                    personal_discount = 20
                
                base_price = food_dict['price']
                if personal_discount > 0:
                    final_price = int(base_price - (base_price * personal_discount / 100))
                    # در صورت داشتن تخفیف هوشمند، قیمت پایه را برای خط‌خوردن می‌فرستیم
                    food_dict['old_price_formatted'] = "{:,}".format(base_price) 
                else:
                    final_price = base_price
                
                # جاگذاری قیمت نهایی روی price_formatted تا فرانت شما آن را بخواند
                food_dict['price_formatted'] = "{:,}".format(final_price) 
                food_dict['price'] = final_price
                food_list_for_cat.append(food_dict)
            
            menu_data_for_response.append({
                'category_id': cat.id,
                'category_name': cat.name,
                'category_icon': cat.icon.url if cat.icon and cat.icon.name else None,
                'category_fa': cat.fa_icon,
                'items': food_list_for_cat # کلید items دقیقاً مطابق درخواست جاوااسکریپت
            })
                # 2. ایجاد دسته "پیشنهاد ویژه"
            # پیدا کردن غذاهایی که تخفیف دارند (قیمت قبلی بزرگتر از قیمت فعلی است)
    # special_offers = Food.objects.filter(is_available=True, old_price__gt=F('price'))
    
    # if special_offers.exists():
    #     special_serializer = FoodSerializer(special_offers, many=True)
    #     # اضافه کردن این دسته به ابتدای لیست (یا انتها، بسته به سلیقه شما)
    #     menu_data_for_response.insert(0, {
    #         "category_id": "special_offers", # یک شناسه یکتا
    #         "category_name": "پیشنهاد ویژه",
    #         "category_icon": None,
    #         "category_fa": 'fa fa-star ',
    #         "items": special_serializer.data
    #     })


    # بازگرداندن آرایه مستقیم (بدون دیکشنری ریشه) برای رفع خطای JS
    return Response(menu_data_for_response)
# ویوی صفحه ورود

def login_view(request, cafe_slug):
    # اگر کاربر از قبل لاگین کرده باشد
    if request.user.is_authenticated:
        # اگر سوپریوزر بود یا ادمینِ همین کافه بود، مستقیم برود به داشبورد
        if request.user.is_superuser or request.user.cofe_owner.slug == cafe_slug:
            return redirect('admin_dashboard', cafe_slug=cafe_slug)
        else:
            # اگر لاگین بود ولی مال این کافه نبود
            return render(request, 'login/login.html', {'error': 'شما به این کافه دسترسی ندارید.', 'cafe_slug': cafe_slug})

    error = None
    if request.method == "POST":
        user_p = request.POST.get('username')
        pass_p = request.POST.get('password')
        
        # ۱. ابتدا فقط نام کاربری و رمز عبور را برای صحت‌سنجی می‌فرستیم
        user = authenticate(request, username=user_p, password=pass_p)
        
        if user is not None:
            # ۲. حالا که رمز درست است، بررسی می‌کنیم اجازه ورود به این URL را دارد یا خیر
            is_allowed = False
            
            # اگر سوپریوزر باشد -> اجازه دارد
            if user.is_superuser:
                is_allowed = True
            
            # اگر سوپریوزر نبود، چک می‌کنیم آیا کافه اختصاصی‌اش با آدرس درخواستی یکی است؟
            # (استفاده از hasattr برای جلوگیری از ارور در صورت نداشتن فیلد cofe_owner)
            elif user.cofe_owner and user.cofe_owner.slug == cafe_slug:
                is_allowed = True
                
            # ۳. در نهایت اگر مجاز بود لاگین می‌شود
            if is_allowed:
                login(request, user)
                return redirect('admin_dashboard', cafe_slug=cafe_slug)
            else:
                error = "شما اجازه دسترسی به پنل این کافه را ندارید."
        else:
            error = "نام کاربری یا رمز عبور اشتباه است."
            
    return render(request, 'login/login.html', {'error': error, 'cafe_slug': cafe_slug})
# ویوی خروج
def logout_view(request , cafe_slug):
    logout(request)
    return redirect('login_view' , cafe_slug=cafe_slug)


@api_view(['GET'])
def get_settings(request , cafe_slug):
    setting = Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()
    if not setting:
        coffe_obj=CoffeShops.objects.get(slug=cafe_slug)
        # اگر دیتایی نبود، یک مقدار پیش‌فرض بساز
        setting = Core_Settings.objects.create(title="کافه من" ,cofe_owner=coffe_obj)
    serializer = SettingsSerializer(setting)
    return Response(serializer.data)


class MenuViewSet(viewsets.ReadOnlyModelViewSet):
    # اضافه کردن فیلتر is_available=True
    serializer_class = FoodSerializer
    pagination_class = None

    def get_queryset(self):
        # دریافت cafe_slug از آدرس URL
        cafe_slug = self.kwargs.get('cafe_slug')

        # فیلتر کردن غذاها بر اساس کافه و موجود بودن
        # توجه: در اینجا فرض کردم مدل Food شما از طریق فیلد cafe (یا مشابه آن) به کافه متصل است
        queryset = Food.objects.filter(
            cofe_owner__slug=cafe_slug,   # <--- اتصال به کافه
            is_available=True
        ).select_related('category').order_by('-id')
        
        return queryset


# Create your views here.

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import user_passes_test
from .models import Core_Settings, Food, category

def admin_dashboard(request , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    settings, created = Core_Settings.objects.get_or_create( defaults={'title': 'مدیریت کافه', 'theme': 'theme-1'} , cofe_owner=cafe)
    categories = category.objects.all().filter(cofe_owner__slug=cafe_slug , is_deleted=False)
    
    # فیلتر کردن غذاها بر اساس دسته‌بندی (اگر پارامتر cat در URL باشد)
    cat_id = request.GET.get('cat')
    search_query = request.GET.get('search')

    foods_query = Food.objects.filter(cofe_owner__slug=cafe_slug, is_deleted=False)

    # ۲. فیلترهای سرچ و دسته‌بندی را اعمال می‌کنیم
    if cat_id:
        foods_query = foods_query.filter(category_id=cat_id)
    if search_query:
        foods_query = foods_query.filter(name__icontains=search_query)

    # ۳. پیدا کردن دسته‌بندی‌هایی که تو این سرچ/فیلتر، غذایی برای نمایش دارند
    valid_category_ids = foods_query.values_list('category_id', flat=True).distinct()

    # ۴. دسته‌بندی‌ها را می‌گیریم (تا روی آن‌ها صفحه‌بندی کنیم)
    cats_queryset = category.objects.filter(id__in=valid_category_ids).order_by('-id')

    # ۵. صفحه‌بندی روی دسته‌بندی‌ها! (مثلا ۳ دسته‌بندی کامل در هر صفحه نمایش داده شود)
    # عدد 3 رو میتونید بسته به نیازتون کم یا زیاد کنید
    paginator = Paginator(cats_queryset, 3) 
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)


    # صفحه‌بندی: ۱۰ آیتم در هر صفحه
    categories_in_page = page_obj.object_list
    category_ids = list(categories_in_page.values_list('id', flat=True))  # اجرای اولیه کوئری
    foods_in_page = list(foods_query.filter(category__in=category_ids).order_by('-category_id', '-id'))

    # ۷. ترفند اصلی: لیست آیتم‌های صفحه را با غذاها جایگزین می‌کنیم
    # با این کار قالب HTML شما فکر میکنه داره غذاها رو صفحه بندی میکنه و خراب نمیشه
    page_obj.object_list = foods_in_page


    if request.method == "POST":
            
        user = request.user
        if not request.user.is_superuser:    

            if user.role not in  CustomUser.ROLE_MANAGER :
                return redirect("no_permission" , cafe_slug)  # یا 403

        # ۱. بروزرسانی تنظیمات
        if "update_settings" in request.POST:
            settings.title = request.POST.get('title')
            settings.desc = request.POST.get('desc')
            settings.theme = request.POST.get('theme')

            # ===== شروع کدهای جدید =====
            settings.music_theme = request.POST.get('music_theme') # ذخیره تم آهنگ
            settings.receipt_title = request.POST.get('receipt_cafe_name') # ذخیره نام کافه در فیش
            
            name_customer_fish = request.POST.get('name_customer_fish')
            
            # ... کدهای قبلی که فیلدهای دیگر را ذخیره می‌کنند ...

            # اختصاص مقدار جدید به آبجکت settings
            settings.name_customer_fish = name_customer_fish

            
            # ذخیره وضعیت چک‌باکس‌های فیش
            settings.enable_hafez_fal = 'enable_hafez_fal' in request.POST
            settings.enable_creation_poems = 'enable_creation_poems' in request.POST
            
            # ذخیره عکس بارکد (فقط اگر فایل جدیدی آپلود شده بود)
            if request.FILES.get('receipt_barcode_image'):
                settings.receipt_barcode_image = request.FILES.get('receipt_barcode_image')
            # ===== پایان کدهای جدید =====


            if settings.plan_level >= 2:
                settings.order_enabled = 'order_enabled' in request.POST
            else:
                settings.order_enabled = False # اگر اشتراک نداشت، اجباراً خاموش بماند

            if settings.plan_level >= 3:
                settings.analysis_enabled = 'analysis_enabled' in request.POST
            else:
                settings.analysis_enabled = False # اگر اشتراک نداشت، اجباراً خاموش بماند

            if settings.plan_level >= 4:
                settings.club_enabled = 'club_enabled' in request.POST
            else:
                settings.club_enabled = False




            if request.FILES.get('logo'): settings.logo = request.FILES.get('logo')
            if request.FILES.get('header-pic'): settings.image = request.FILES.get('header-pic')
            settings.save()
        
        # ۲. اضافه کردن دسته‌بندی جدید
        elif "add_category" in request.POST:
            name = request.POST.get('cat_name')
            icon = request.FILES.get('cat_icon')
            fa_icon = request.POST.get('fa_icon') # این مورد هم اضافه شد تا در دیتابیس ثبت شود
            
            # دریافت مقدار اولویت (اگر خالی بود یا عدد نبود، 0 در نظر گرفته می‌شود)
            priority_val = request.POST.get('priority')
            priority = int(priority_val) if priority_val and priority_val.isdigit() else 0

            if name and icon:
                category.objects.create(name=name, icon=icon, fa_icon=fa_icon, priority=priority, cofe_owner=cafe)
            elif name:
                category.objects.create(name=name, fa_icon=fa_icon, priority=priority, cofe_owner=cafe)

        
        # ۳. اضافه کردن غذای جدید
        elif "add_food" in request.POST:
            Food.objects.create(
                name=request.POST.get('food_name'),
                category_id=request.POST.get('food_cat'),
                price=request.POST.get('food_price'),
                cost_price=request.POST.get('cost_price') or 0, # اضافه شد
                desc=request.POST.get('food_desc'),
                img=request.FILES.get('food_img'),
                cofe_owner=cafe
            )
        
        # ۴. حذف غذا
        elif "delete_food" in request.POST:
            food_id = request.POST.get('food_id')
            food_to_delete = get_object_or_404(Food, id=food_id)
            
            try:
                food_to_delete.delete()
            except ProtectedError:
                # اگر در سفارشی ثبت شده بود، فقط برچسب حذف می‌خورد و از منو هم خارج می‌شود
                food_to_delete.is_deleted = True
                food_to_delete.is_available = False 
                food_to_delete.save()

            


        elif "delete_category" in request.POST:
            c_id = request.POST.get('cat_id')
            cat = get_object_or_404(category, id=c_id, cofe_owner=cafe)
            try:
                cat.delete()
            except ProtectedError:
                # اگر دسته بخاطر داشتن غذاهای ثبت شده در سفارشات قابل حذف کامل نیست:
                cat.is_deleted = True
                cat.save()


        elif "toggle_available" in request.POST:
            f_id = request.POST.get('food_id')
            food = get_object_or_404(Food, id=f_id , cofe_owner=cafe)
            food.is_available = not food.is_available
            food.save()

        # تغییر وضعیت موجودی (is_finish)
        elif "toggle_finish" in request.POST:
            f_id = request.POST.get('food_id')
            food = get_object_or_404(Food, id=f_id , cofe_owner=cafe)
            food.is_finish = not food.is_finish
            food.save()

        # ویرایش دسته‌بندی
        elif "edit_category" in request.POST:
            c = get_object_or_404(category, id=request.POST.get('cat_id'), cofe_owner=cafe)
            c.name = request.POST.get('cat_name')
            c.fa_icon = request.POST.get('fa_icon')
            
            # دریافت و آپدیت مقدار اولویت
            priority_val = request.POST.get('priority')
            c.priority = int(priority_val) if priority_val and priority_val.isdigit() else 0

            if request.FILES.get('cat_icon'):
                c.icon = request.FILES.get('cat_icon')
            c.save()

        # ویرایش غذا
        elif "edit_food" in request.POST:
            f = get_object_or_404(Food, id=request.POST.get('food_id') , cofe_owner=cafe)
            f.name = request.POST.get('food_name')
            f.category_id = request.POST.get('food_cat')
            f.price = request.POST.get('food_price')
            f.cost_price = request.POST.get('cost_price') or 0 # اضافه شد
            f.old_price = request.POST.get('old_price') or None
            f.desc = request.POST.get('food_desc')
            if request.FILES.get('food_img'):
                f.img = request.FILES.get('food_img')
            f.save()

        return redirect('admin_dashboard' , cafe_slug=cafe_slug)

    return render(request, 'panel/dashboard.html', {
        'settings': settings,
        'categories': categories,
        'foods': page_obj,
        'current_cat': int(cat_id) if cat_id else None,
        'cafe_slug':cafe_slug
    })

# def menu(request):
#     table_number = request.GET.get('table') # گرفتن شماره میز از آدرس
#     context = {
#         'table_number': table_number
#     }
#     return render(request, 'menu/index.html', context)

def check_new_orders(request , cafe_slug):
    count = Order.objects.filter(status='pending' , cofe_owner__slug=cafe_slug).count()
    return JsonResponse({'count': count})


def menu(request , cafe_slug):
    
    model_obj=Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()

    if model_obj.theme is not None:
        return render (request , 'menu/index.html' ,{'theme':model_obj.theme , 'cafe_slug':cafe_slug}  )
    else:
        return render (request , 'menu/index.html' ,{'theme':'theme-1' , 'cafe_slug':cafe_slug}  )


from django.db import transaction
from rest_framework.response import Response
from rest_framework.decorators import api_view
import jdatetime
from django.db.models import F  # <--- این را اضافه کنید


@api_view(['POST'])
def submit_order(request, cafe_slug):
    try:
        data = request.data
        phone = data.get('phone', '00000000000')
        email = data.get('email', '')
        birth_date = data.get('birth_date', None)
        table_num = data.get('table_number', 0)
        cart_items = data.get('cart', [])
        print(cart_items)
        cafe = CoffeShops.objects.get(slug=cafe_slug)

        device_id = getattr(request, 'device_id', request.COOKIES.get('device_id', ''))
        
        with transaction.atomic():
            print('submit1')
            # ۱. مدیریت کاربر
            # ۱. مدیریت کاربر
            user_obj = None # مقدار اولیه
            is_new_user = False
            if phone and phone != '00000000000':
                print('submit2')

                # الف: کاربر را فقط بر اساس شماره موبایل پیدا کن (چون در کل سیستم یکتاست)
                user_obj = CustomUser.objects.filter(phone=phone , cofe_owner__slug=cafe_slug).first()
                
                # ب: اگر کاربری با این شماره در هیچ کافه‌ای نبود، آن را بساز
                if not user_obj:
                    print('submit user')
                    user_obj = CustomUser.objects.create(
                        phone=phone,
                        cofe_owner=cafe,
                        username=f"{phone}@{cafe_slug}"
                    )
                    is_new_user = True # <---- اضافه شد: یعنی کاربر الان ساخته شد
                print('submit3')

                user_obj.visit_count += 1
                if email: user_obj.first_name = email
                print('submit4')

                if birth_date: 
                    try:
                        y, m, d = map(int, birth_date.split('/'))
                        user_obj.birth_date = jdatetime.date(y, m, d).togregorian()
                    except:
                        pass
                user_obj.save()
                print('submi5')

            elif device_id:
                device_profile = DeviceProfile.objects.select_related('user').filter(device_id=device_id, cofe_owner=cafe).first()
                print('visitcount')
                # اگر دستگاه قبلا ثبت شده و به کاربری متصل است
                if device_profile and device_profile.user:
                    user_obj = device_profile.user
                    # این یک بازدید مجدد است، پس شمارنده را زیاد کن
                    user_obj.visit_count = F('visit_count') + 1
                    user_obj.save()

            # ۲. ساخت یا به‌روزرسانی پروفایل دستگاه
            if device_id:
                # الف: دستگاه را فقط بر اساس شناسه‌اش پیدا کن (چون در دیتابیس یکتاست)
                device_profile = DeviceProfile.objects.filter(device_id=device_id , cofe_owner=cafe).first()
                
                # ب: اگر دستگاه قبلاً ثبت نشده بود، آن را بساز
                if not device_profile:
                    device_profile = DeviceProfile.objects.create(
                        device_id=device_id, 
                        cofe_owner=cafe
                    )
                
                # ج: اگر کاربر در این سفارش شماره موبایل داد، دستگاه را به کاربر متصل کن
                if user_obj and not device_profile.user:
                    device_profile.user = user_obj
                    device_profile.save()

            # ۳. مدیریت میز (بدون خطای دیتابیس)
            try: 
                table_num = int(table_num)
            except: 
                table_num = 0
            
            table_obj = Table.objects.filter(number=table_num).first()
            if not table_obj:
                table_obj = Table.objects.create(number=table_num, cofe_owner=cafe)
            elif table_obj.cofe_owner != cafe:
                pass
            
            # ۴. ساخت سفارش
            new_order = Order.objects.create(
                table=table_obj, 
                status='pending',
                total_price=0,
                device_id=device_id,
                cofe_owner=cafe
            )
            
            total = 0
            for item in cart_items:
                food = Food.objects.get(id=item['id'], cofe_owner__slug=cafe_slug)
                qty = int(item['quantity'])
                OrderItem.objects.create(
                    order=new_order,
                    food=food,
                    quantity=qty,
                    price_at_order=food.price,
                    cost_price_at_order=food.cost_price, 
                    old_price_at_order=food.old_price,  
                    cofe_owner=cafe
                )
                total += (food.price * qty)
            
            print(total)
            # ۵. آپدیت قیمت نهایی
            new_order.total_price = total
            print('111')
            new_order.save()
            print('555')
        return Response({"status": "success"  ,"is_new_user": is_new_user, "phone": phone})
    
    except Exception as e:
        import traceback
        print(traceback.format_exc()) # برای اینکه در ترمینال سرور هم ارور را کامل ببینید
        return Response({"status": "error", "message": str(e)}, status=400)
    
import random

def live_orders(request , cafe_slug):

    CREATION_POEMS = [
        'می خوانمت الوهیم پرتوی بنفش،تا دگرگونی الهی را بر سرتاسر وجودم فروریزی',
        'می خوانمت ای پرتوی یاقوت ارغوانی تا ذره ذره ی کالبدهایم هر سلول و هر اتم را به نوری برتر دگرگون سازی',
        'می خوانمت شعله ی بنفش تا در جانم زبانه کشی و بسوزانی هر حجابی را که میان من و روح هستی فاصله می افکند',
        'می خوانمت شعله ی بنفش تا خاکستر کنی پندارهایم را تا خاکستر کنی ستیزه هایم را و از خاکستر ترسم عشق بیافرینی',
        'من حافظ شعله مقدسم و آن را به هر کران این جهان می برم',
        'من حافظ شعله مقدسم و آن را در تار و پود وجودم می تنم',
        'مشعل مقدس خداوند را بر فراز دستانم نگاه می دارم تا نور درخشان طرح ازلی بر همگان پدیدار گردد',
        'من حافظ شعله مقدسم و این امانت را به دیگر عوالم می برم تا همه نور را بشناسند و این شعله را از پی خویش روشن نگاه دارند',
        'الوهیم پرتوی زرین تو را می خوانم تا خرد الهی را بر پهنه ی آگاهی ام جاری کنی',
        'الوهیم پرتوی زرین تو را می خوانم تا راز سنگ ها و پیمانه ها را بر من بگشایی راز تعادل و توازن کائنات را ',
        'الوهیم پرتوی زرین تو را می خوانم که اندیشه ام را روشن سازی تا غرق شود در نور فهم در آرامشی ژرف',
        'باشد که کردارم حکیمانه ، احساسم متعادل و اندیشه ام غرق آرامش شود',
        'من استادم که در میان ابعاد به رقص آمده است من خالق ممکن هایم که فرداها را در اکنون می بافم',
        'من استاد تعادلم چون بندبازی بر ریسمان زندگی من استادم و قدرتم در شفقت من است',
        'من استادم سرگرم بی کران من استادم و ستارگان را قلقلک می دهم',
        'الوهیم پرتوی سیمین رحمت الهی را در کالبدهایم جاری کن',
        'الوهیم پرتوی سیمین گره های کارمایی ام را تمام بگشا و کانون های کینه را به کمال تطهیر کن تا دریابم شادی چیست',
        'الوهیم پرتوی سیمین هستی ام را از بخشایش لبریز،حیاتم را با سپاسگزاری آراسته و قلبم را غرق جشنی باشکوه ساز',
        'الوهیم پرتوی سیمین من تو را فرا می خوانم تا از اسارت حقارت هایم رهایم کنی،یوغ نفرت را در هم شکسته و روحم را آزاد سازی',
        'الوهیم فیض و رحمت را فرا می خوانم تا در همین لحظه مرا از سرور زندگی پر کند',
        'شوقی در پایم می دود که می خواندم به پای کوفتن در کوچه ها',
        'قاه قاهی مستانه در دلم وا می داردم در آغوش بگیرم همه را چشمه ی جوشان قلبم عشق می پاشد بر جهان',
        'می خندم از ژرفای روح حال که می فهمم سرور روح هستی را حالا که زندگی سروری است دم به دم باید که جشن به پا کنم',
    ]
    HAFEZ_COUPLETS = [
        "یوسف گمگشته بازآید به کنعان غم مخور",
        "کلبه احزان شود روزی گلستان غم مخور",
        "صلاح کار کجا و من خراب کجا",
        "ببین تفاوت ره از کجاست تا به کجا",
        "در کار گلاب و گل حکم ازلی این بود",
        "کاین شاهد بازاری وان پرده نشین باشد",
        "مزرع سبز فلک دیدم و داس مه نو",
        "یادم از کشته خویش آمد و هنگام درو",
        "دارم از زلف سیاهش گله چندان که مپرس",
        "که چنان زو شده‌ام بی سر و سامان که مپرس",
        "گفتم غم تو دارم گفتا غمت سر آید",
        "گفتم که ماه من شو گفتا اگر برآید",
        "از صدای سخن عشق ندیدم خوشتر",
        "یادگاری که در این گنبد دوار بماند",
        "هرگز نمیرد آنکه دلش زنده شد به عشق",
        "ثبت است بر جریده عالم دوام ما",
        "دوش وقت سحر از غصه نجاتم دادند",
        "واندر آن ظلمت شب آب حیاتم دادند",
        "ما ز یاران چشم یاری داشتیم",
        "خود غلط بود آنچه ما پنداشتیم",
        "درخت دوستی بنشان که کام دل به بار آرد",
        "نهال دشمنی برکن که رنج بی‌شمار آرد",
        "الا یا ایها الساقی ادر کأسا و ناولها",
        "که عشق آسان نمود اول ولی افتاد مشکل‌ها",
        "باغبان گر پنج روزی صحبت گل بایدش",
        "بر جفای خار هجران صبر بلبل بایدش",
        "رسید مژده که ایام غم نخواهد ماند",
        "چنان نماند چنین نیز هم نخواهد ماند",
    ]
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_WAITER, CustomUser.ROLE_MANAGER]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    settings = Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()
    # اگر سطح اشتراک کمتر از ۳ بود، اجازه ورود نده
    if settings.plan_level < 2:
        return render(request, 'panel/403.html', {"msg": "این بخش در اشتراک شما نیست." , 'cafe_slug':cafe_slug})

    # ================== ADD THIS LOGIC BLOCK ==================
    hafez_fal_text = []
    creation_poems_text = []
    # Check if the feature is enabled in settings, then pick a random couplet
    if settings and settings.enable_hafez_fal:
        # ensure_ascii=False برای پشتیبانی از حروف فارسی الزامی است
        hafez_fal_text = json.dumps(HAFEZ_COUPLETS, ensure_ascii=False)

    if settings and settings.enable_creation_poems:
        creation_poems_text = json.dumps(CREATION_POEMS, ensure_ascii=False)

    # ----- این خط را برای گرفتن آدرس عکس اضافه کنید -----
    receipt_barcode_url = settings.receipt_barcode_image.url if settings and settings.receipt_barcode_image else None
    # ----------------------------------------------------


    # سفارشات جاری (جدید)
    live_orders = Order.objects.filter(status='pending' ,cofe_owner__slug=cafe_slug).order_by('-created_at')
    # تاریخ امروز به شمسی برای نمایش اولیه
    today_jalali = jdatetime.date.today().strftime('%Y/%m/%d')
    all_foods = Food.objects.filter(is_available=True , cofe_owner__slug=cafe_slug)
    cafe_club = Core_Settings.objects.get(cofe_owner__slug=cafe_slug)
    return render(request, 'panel/live_orders.html', {
        'live_orders': live_orders,
        'today_jalali': today_jalali,
        'all_foods': all_foods,
        'cafe_slug':cafe_slug,
        'tables':Table.objects.all().filter(cofe_owner__slug=cafe_slug),
        'club_enabled':cafe_club.club_enabled,

        'settings': settings,
        'hafez_fal': hafez_fal_text,
        'creation_poems_text': creation_poems_text,
        'receipt_barcode_url': receipt_barcode_url,

    })


@api_view(['POST'])
def add_item_to_existing_order(request, order_id , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_WAITER, CustomUser.ROLE_MANAGER]:
            return redirect("no_permission" , cafe_slug)  # یا 403
        
    order = get_object_or_404(Order, id=order_id)
    food_id = request.data.get('food_id')
    food = get_object_or_404(Food, id=food_id)
    cafe=CoffeShops.objects.get(slug=cafe_slug)
    # چک می‌کنیم آیا این غذا از قبل در سفارش هست؟ اگر هست تعداد را زیاد کن
    item, created = OrderItem.objects.get_or_create(
        order=order, 
        food=food,
        defaults={'price_at_order': food.price, 'quantity': 1},
        cofe_owner=cafe
    )
    if not created:
        item.quantity += 1
        item.save()
    
    # آپدیت قیمت کل سفارش
    order.total_price = sum(i.quantity * i.price_at_order for i in order.items.all())
    order.save()
    
    return Response({"status": "success"})


import traceback # این را به بالای فایل views.py اضافه کنید (اگر نیست)


try:
    import zoneinfo
    tehran_tz = zoneinfo.ZoneInfo('Asia/Tehran')
except ImportError:
    # اگر پایتون قدیمی بود از pytz استفاده می‌کنیم
    import pytz
    tehran_tz = pytz.timezone('Asia/Tehran')

from django.utils import timezone
from datetime import datetime
import jdatetime
from django.template.loader import render_to_string
from django.http import JsonResponse
from rest_framework.decorators import api_view

@api_view(['GET'])
def get_history_by_date(request, cafe_slug):
    jalali_date = request.GET.get('date')
    
    try:
        # این بخش را نگه داشتم تا ساختار قبلی شما حفظ شود
        year, month, day = map(int, jalali_date.split('/'))
        g_date = jdatetime.date(year, month, day).togregorian()

        naive_start = datetime(g_date.year, g_date.month, g_date.day, 0, 0, 0)
        naive_end = datetime(g_date.year, g_date.month, g_date.day, 23, 59, 59)

        start_datetime = timezone.make_aware(naive_start)
        end_datetime = timezone.make_aware(naive_end)

        # گرفتن تمام سفارشات بدون فیلتر تاریخ دیتابیس
        all_orders = Order.objects.filter(
            cofe_owner__slug=cafe_slug,
            status__in=['paid', 'cancelled'],
        ).order_by('-created_at')

        # === پیاده‌سازی الگوریتم شما ===
        filtered_orders = []
        # زمان حال به ثانیه
        current_time_seconds = timezone.now().timestamp()

        for order in all_orders:
            # زمان created_at به ثانیه
            created_at_seconds = order.created_at.timestamp()
            # به علاوه 24 ساعت به ثانیه (86400)
            summed_time_seconds = created_at_seconds + 86400
            
            # اگر زمان حال کمتر از زمان جمع شده بود
            if current_time_seconds < summed_time_seconds:
                filtered_orders.append(order)
        # ================================

        # --- کدهای جدید برای محاسبه آمار (روی لیست فیلتر شده) ---
        paid_orders = [o for o in filtered_orders if o.status == 'paid']
        cancelled_orders = [o for o in filtered_orders if o.status == 'cancelled']
        
        total_sales = sum(o.total_price for o in paid_orders)
        success_count = len(paid_orders)
        cancelled_loss = sum(o.total_price for o in cancelled_orders)
        # ------------------------------------

        html = render_to_string('panel/partials/history_list.html', {
            'history_orders': filtered_orders
        })
        
        # افزودن دیتاهای آماری به ریسپانس بدون حذف هیچ کلیدی
        return JsonResponse({
            'status': 'success', 
            'html': html,
            'total_sales': total_sales,
            'success_count': success_count,
            'cancelled_loss': cancelled_loss,
            'cafe_slug': cafe_slug
        })
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': 'تاریخ نامعتبر'}, status=400)

        
        
@api_view(['POST'])
def cancel_order(request, order_id , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_WAITER, CustomUser.ROLE_MANAGER]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    order = get_object_or_404(Order, id=order_id)
    order.status = 'cancelled'
    order.save()
    return Response({"status": "success"})


@api_view(['POST'])
def update_order_item(request, item_id , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_WAITER, CustomUser.ROLE_MANAGER]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    item = get_object_or_404(OrderItem, id=item_id)
    delta = int(request.data.get('delta', 0))
    
    if item.quantity + delta <= 0:
        item.delete()
    else:
        item.quantity += delta
        item.save()
    
    # آپدیت قیمت کل سفارش
    order = item.order
    total = sum(i.quantity * i.price_at_order for i in order.items.all())
    order.total_price = total
    order.save()
    
    return Response({"status": "success"})

# این تابع را جایگزین change_status قبلی کنید یا اصلاح کنید
@api_view(['POST'])
def change_order_status(request, order_id , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_WAITER, CustomUser.ROLE_MANAGER]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    order = get_object_or_404(Order, id=order_id)
    new_status = request.data.get('status') # 'paid' or 'pending'
    order.status = new_status
    order.save()
    return Response({"status": "success"})

from django.http import HttpResponse
from django.db.models import Sum, F

from django.http import HttpResponse, JsonResponse
from django.db.models import Sum, F, Count
import jdatetime
from datetime import datetime

from openpyxl import Workbook
from django.http import HttpResponse
from django.shortcuts import render
from django.db.models import Sum
# مطمئن شوید که سایر import های شما (مثل jdatetime, Order, OrderItem و ...) سر جایشان هستند

def financial_report(request , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    

        if user.role not in [CustomUser.ROLE_MANAGER, CustomUser.ROLE_ACCOUNTANT]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    settings = Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()
    # اگر سطح اشتراک کمتر از ۳ بود، اجازه ورود نده
    if settings.plan_level < 3:
        return render(request, 'panel/403.html', {"msg": "این بخش در اشتراک شما نیست." , 'cafe_slug':cafe_slug})

    start_jalali = request.GET.get('start')
    end_jalali = request.GET.get('end')
    
    orders = Order.objects.filter(status='paid' , cofe_owner__slug=cafe_slug)

    if start_jalali and end_jalali:
        try:
            s_y, s_m, s_d = map(int, start_jalali.split('/'))
            e_y, e_m, e_d = map(int, end_jalali.split('/'))
            start_date = jdatetime.date(s_y, s_m, s_d).togregorian()
            end_date = jdatetime.date(e_y, e_m, e_d).togregorian()
            orders = orders.filter(created_at__date__range=[start_date, end_date])
        except:
            pass

    total_revenue = orders.aggregate(total=Sum('total_price'))['total'] or 0
    total_orders = orders.count()
    
    total_profit = 0
    total_discount = 0
    items_report = {} 

    order_items = OrderItem.objects.filter(order__in=orders , cofe_owner__slug=cafe_slug).select_related('food')
    
    for item in order_items:
        profit = (item.price_at_order - item.cost_price_at_order) * item.quantity
        total_profit += profit
        
        if item.old_price_at_order and item.old_price_at_order > item.price_at_order:
            total_discount += (item.old_price_at_order - item.price_at_order) * item.quantity

        f_name = item.food.name
        if f_name not in items_report:
            items_report[f_name] = {'qty': 0, 'sales': 0, 'profit': 0}
        items_report[f_name]['qty'] += item.quantity
        items_report[f_name]['sales'] += (item.price_at_order * item.quantity)
        items_report[f_name]['profit'] += profit

    for name, data in items_report.items():
        if total_profit > 0:
            data['share'] = round((data['profit'] / total_profit) * 100, 1)
        else:
            data['share'] = 0

    # --- بخش تولید اکسل با openpyxl ---
    if 'excel' in request.GET:
        wb = Workbook()
        ws = wb.active
        ws.title = "Finance Report"

        headers = [
            'تاریخ میلادی',
            'تاریخ شمسی',
            'میز',
            'محصول',
            'تعداد',
            'قیمت واحد (فروش)',
            'تخفیف روی واحد',
            'قیمت تمام شده واحد',
            'سود کل این ردیف',
            'سود ناخالص'
        ]

        ws.append(headers)

        for item in order_items:
            discount_val = (item.old_price_at_order - item.price_at_order) if item.old_price_at_order else 0
            
            ws.append([
                item.order.created_at.strftime('%Y-%m-%d'),
                jdatetime.date.fromgregorian(date=item.order.created_at.date()).strftime('%Y/%m/%d'),
                item.order.table.number if item.order.table else 'بیرون‌بر',
                item.food.name,
                item.quantity,
                item.price_at_order,
                discount_val,
                item.cost_price_at_order,
                (item.price_at_order - item.cost_price_at_order) * item.quantity,
                item.price_at_order * item.quantity
            ])

        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=Finance_Report.xlsx'
        
        wb.save(response)
        return response

    # --- این بخش در کد شما جا افتاده بود یا تورفتگی اشتباه داشت ---
    # این return باید دقیقاً هم‌تراز با if 'excel' in request.GET باشد
    return render(request, 'panel/financial.html', {
        'revenue': total_revenue,
        'profit': total_profit,
        'discount': total_discount,
        'orders_count': total_orders,
        'items_report': items_report,
        'start_date': start_jalali,
        'end_date': end_jalali,
        'cafe_slug':cafe_slug
    })



from datetime import timedelta
from django.core.mail import send_mail


# @user_passes_test(lambda u: u.is_superuser)
# def club_dashboard(request):

#     settings = Core_Settings.objects.first()
#     # اگر سطح اشتراک کمتر از ۳ بود، اجازه ورود نده
#     if settings.plan_level < 4:
#         return render(request, 'panel/403.html', {"msg": "این بخش در اشتراک شما نیست."})


#     users = CustomUser.objects.all()
    
#     # فیلترها
#     total_members = users.count()
#     recent_users = users.filter(last_visit__gte=timezone.now() - timedelta(days=7))
#     loyal_users = users.filter(visit_count__gte=3) # وفادار: بیش از ۳ بار خرید

#     if request.method == "POST":
#         target = request.POST.get('target')
#         message = request.POST.get('message')
#         subject = "پیام از طرف باشگاه مشتریان کافه"

#         # انتخاب مخاطبین
#         if target == "recent":
#             selected_users = recent_users
#         elif target == "loyal":
#             selected_users = loyal_users
#         else:
#             selected_users = users

#         # عملیات ارسال (ایمیل در کنسول و شبیه‌سازی پیامک)
#         emails = [user.email for user in selected_users if user.email]
#         if emails:
#             send_mail(subject, message, 'admin@cafe.com', emails)
        
#         # در اینجا متد Kavenegar شما برای پیامک می‌تواند صدا زده شود
#         for u in selected_users:
#             print(f"SMS SENT TO {u.phone}: {message}")

#         return JsonResponse({"status": "success", "count": selected_users.count()})

#     return render(request, 'panel/club_dashboard.html', {
#         'total': total_members,
#         'recent': recent_users.count(),
#         'loyal': loyal_users.count(),
#         'users': users.order_by('-last_visit')
#     })

import http.client
import json
import json
import http.client
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.utils import timezone
from datetime import timedelta


def personalize_sms_text(template_text, user_name, cafe_name):
    """جایگزینی [name] و [cafe_name] در متن پیامک"""
    if not template_text:
        return ""
    user_name = user_name or ""
    cafe_name = cafe_name or ""
    text = template_text.replace("[name]", user_name)
    text = text.replace("[cafe_name]", cafe_name)
    return text

def get_sms_credit(api_key):
    """تابع دریافت موجودی پنل پیامک با API Key اختصاصی"""
    if not api_key: return 0
    try:
        conn = http.client.HTTPSConnection("api.sms.ir")
        headers = {'X-API-KEY': api_key}
        conn.request("GET", "/v1/credit", '', headers)
        res = conn.getresponse()
        data = json.loads(res.read().decode("utf-8"))
        if data.get("status") == 1:
            # نکته: خروجی api.sms.ir معمولا موجودی به ریال است. 
            # اگر می‌خواهید تعداد پیامک را نشان دهید باید این عدد را بر هزینه هر پیامک تقسیم کنید.
            return data.get("data")
        return 0
    except Exception:
        return 0

def send_bulk_sms(api_key, line_number, mobiles, message_text):
    """تابع ارسال پیامک گروهی با اطلاعات اختصاصی"""
    if not api_key or not line_number:
        return {"status": 0, "message": "اطلاعات پنل پیامک ثبت نشده است."}
    try:
        conn = http.client.HTTPSConnection("api.sms.ir")
        payload = json.dumps({
            "lineNumber": int(line_number),
            "messageText": message_text,
            "mobiles": mobiles,
            "sendDateTime": None
        })
        headers = {
            'X-API-KEY': api_key,
            'Content-Type': 'application/json'
        }
        conn.request("POST", "/v1/send/bulk", payload, headers)
        res = conn.getresponse()
        data = json.loads(res.read().decode("utf-8"))
        return data
    except Exception as e:
        return {"status": 0, "message": str(e)}


import openpyxl

# در بالای فایل views.py، این ایمپورت‌ها را اضافه یا مطمئن شوید که وجود دارند
from django.utils import timezone
from datetime import timedelta, datetime # <<< NEW: datetime اضافه شد
import openpyxl
from django.http import HttpResponse, JsonResponse


# ... (بقیه کدهای شما) ...

# ... (تمامی import های شما باید در بالای فایل باشند)
from django.shortcuts import render, redirect
from django.contrib import messages
from django.utils import timezone
from datetime import timedelta, datetime
import openpyxl
from django.http import HttpResponse, JsonResponse
from .models import Core_Settings, SMS_Template, CustomUser, CoffeShops, ScheduledMessage


import jdatetime # حتما برای تبدیل تاریخ شمسی زمان‌بندی نیاز است
from django.shortcuts import render, redirect
from django.utils import timezone
from datetime import timedelta
import openpyxl
from django.http import HttpResponse, JsonResponse
import json
import http.client
from django.core.paginator import Paginator
from django.db.models import Q

# اضافه شدن مدل‌های جدید CustomSMSTemplate و SMSHistory به ایمپورت‌ها

def club_dashboard(request, cafe_slug):
    # --- بخش 1: بررسی دسترسی و دریافت آبجکت‌های اصلی ---
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe:
                return redirect("no_permission", cafe_slug)
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission", cafe_slug)

    cafe_obj = CoffeShops.objects.get(slug=cafe_slug)
    
    core = Core_Settings.objects.filter(cofe_owner=cafe_obj).first()
    if core is None:
        core = Core_Settings.objects.create(cofe_owner=cafe_obj)

    settings = SMS_Template.objects.filter(cofe_owner=cafe_obj).first()
    if settings is None:
        settings = SMS_Template.objects.create(cofe_owner=cafe_obj)

    if settings and core.plan_level < 4:
        return render(request, 'panel/403.html', {"msg": "این بخش در اشتراک شما نیست.", 'cafe_slug': cafe_slug})

    # --- بخش 2: آمارها و اطلاعات اولیه ---
    users = CustomUser.objects.all().filter(cofe_owner=cafe_obj)
    total_users = CustomUser.objects.all().filter(cofe_owner=cafe_obj)

    # --- بخش جستجو ---
    search_query = request.GET.get('q', '')
    if search_query:
        # جستجو در نام، نام خانوادگی یا شماره موبایل
        users = users.filter(
            Q(first_name__icontains=search_query) | 
            Q(last_name__icontains=search_query) | 
            Q(phone=search_query)
        )

    # --- محاسبه آمارها (باید قبل از صفحه‌بندی باشد) ---
    # در اینجا users هنوز یک QuerySet است و متد filter و count دارد
    total_members = total_users.count() 
    recent_users = total_users.filter(last_visit__gte=timezone.now() - timedelta(days=7))
    loyal_users = total_users.filter(visit_count__gte=5)

    # --- بخش صفحه‌بندی ---
    paginator = Paginator(users, 10) # نمایش ۱۰ کاربر در هر صفحه
    page_number = request.GET.get('page')
    users = paginator.get_page(page_number) # از اینجا به بعد users تبدیل به Page می‌شود

    cafe_api_key = settings.sms_api_key if settings else None
    cafe_line_number = settings.sms_line_number if settings else None

    current_credit = get_sms_credit(cafe_api_key)

    # --- بخش 3: ساخت اکسل ---
    if request.GET.get('export') == 'excel':
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "لیست مشتریان"
        ws.sheet_view.rightToLeft = True
        ws.append(["شماره موبایل", "نام مشتری", "تعداد مراجعه", "آخرین بازدید"])
        for u in users:
            last_visit_str = u.last_visit.strftime("%Y/%m/%d") if u.last_visit else "ندارد"
            ws.append([
                u.phone,
                u.first_name if u.first_name else "ناشناس",
                u.visit_count,
                last_visit_str
            ])
        response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = f'attachment; filename=customers_{cafe_slug}.xlsx'
        wb.save(response)
        return response

    # --- بخش 4: مدیریت درخواست‌های POST ---
    if request.method == "POST":
        action = request.POST.get('action')

        # 4.1: ذخیره تنظیمات API پیامک
        if action == "save_settings":
            new_api_key = request.POST.get('api_key')
            new_line_number = request.POST.get('line_number')
            if settings:
                settings.sms_api_key = new_api_key
                settings.sms_line_number = new_line_number
                settings.save()
                return JsonResponse({"status": "success", "msg": "تنظیمات پیامک شما با موفقیت ذخیره شد."})
            return JsonResponse({"status": "error", "msg": "تنظیمات کافه یافت نشد."})

        # 4.2: تنظیمات پیام خوش‌آمدگویی
        elif action == "save_welcome_settings":
            if not core:
                return JsonResponse({"status": "error", "msg": "تنظیمات اصلی کافه یافت نشد."})
            core.send_welcome_sms = request.POST.get('send_welcome_sms') == 'on'
            core.welcome_sms_template = request.POST.get('welcome_sms_template', '')
            core.save()
            return JsonResponse({"status": "success", "msg": "تنظیمات پیام خوش آمدگویی با موفقیت ذخیره شد."})

        # 4.3: ارسال پیامک دستی + ثبت تاریخچه (تغییر یافته)
# جایگزینی کل بخش ارسال پیامک با این کد:

        elif action == "send_sms":
            if not cafe_api_key or not cafe_line_number:
                return JsonResponse({"status": "error", "msg": "ابتدا توکن و شماره خط خود را ذخیره کنید."})
            
            target = request.POST.get('target')
            message_template = request.POST.get('message')
            if not message_template:
                return JsonResponse({"status": "error", "msg": "متن پیام نمی‌تواند خالی باشد."})
            
            # لیست نهایی (شماره، نام کاربر، متن شخصی‌سازی شده)
            recipients = []
            
            if target == "single_member":
                member_phone = request.POST.get('member_phone')
                if member_phone:
                    user = CustomUser.objects.filter(phone=member_phone, cofe_owner=cafe_obj).first()
                    if user:
                        personalized = personalize_sms_text(message_template, user.first_name, cafe_obj.name)
                        recipients.append((member_phone, personalized))
                target_display_name = "یک عضو خاص"
            elif target == "custom_number":
                custom_phone = request.POST.get('custom_phone')
                if custom_phone and len(custom_phone) == 11:
                    personalized = personalize_sms_text(message_template, None, cafe_obj.name)
                    recipients.append((custom_phone, personalized))
                else:
                    return JsonResponse({"status": "error", "msg": "شماره موبایل نامعتبر است."})
                target_display_name = "شماره دلخواه"
            else:
                # گروه‌های مختلف
                if target == "recent":
                    selected_users = recent_users
                    target_display_name = "بازدیدهای اخیر"
                elif target == "loyal":
                    selected_users = loyal_users
                    target_display_name = "مشتریان وفادار (VIP)"
                elif target == "birthday":
                    today = timezone.now().date()
                    selected_users = CustomUser.objects.filter(
                        cofe_owner=cafe_obj,
                        birth_date__month=today.month,
                        birth_date__day=today.day
                    )
                    target_display_name = "متولدین امروز"
                else: # all
                    selected_users = CustomUser.objects.filter(cofe_owner=cafe_obj)
                    target_display_name = "همه اعضا"
                
                for user in selected_users:
                    if user.phone and len(user.phone) == 11:
                        personalized = personalize_sms_text(message_template, user.first_name, cafe_obj.name)
                        recipients.append((user.phone, personalized))
            
            if not recipients:
                return JsonResponse({"status": "error", "msg": "مخاطبی یافت نشد."})
            
            # بررسی موجودی (تعداد پیامک‌ها = تعداد گیرندگان)
            if current_credit is not None and current_credit < len(recipients):
                return JsonResponse({"status": "error", "msg": f"موجودی شما کافی نیست. تعداد پیامک مورد نیاز: {len(recipients)}"})
            
            # ارسال تک تک پیامک‌ها
            success_count = 0
            failed_list = []
            for phone, personalized_msg in recipients:
                api_response = send_bulk_sms(cafe_api_key, cafe_line_number, [phone], personalized_msg)
                if api_response.get("status") == 1:
                    success_count += 1
                else:
                    failed_list.append(phone)
            
            # ثبت تاریخچه کلی
            SMSHistory.objects.create(
                cafe=cafe_obj,
                message_text=message_template,  # ذخیره قالب اصلی
                target_group_display=target_display_name,
                recipients_count=len(recipients),
                status='موفق' if not failed_list else 'ناقص'
            )
            
            if failed_list:
                return JsonResponse({"status": "error", "msg": f"از {len(recipients)} نفر، {len(failed_list)} نفر ناموفق بود."})
            else:
                return JsonResponse({"status": "success", "msg": f"پیامک به {success_count} نفر با موفقیت ارسال شد."})        # 4.4: تنظیمات تبریک تولد
        elif action == "save_birthday_settings":
            if not core:
                return JsonResponse({"status": "error", "msg": "تنظیمات اصلی کافه یافت نشد."})
            core.auto_birthday_sms = request.POST.get('auto_birthday_sms') == 'on'
            core.birthday_sms_template = request.POST.get('birthday_sms_template', '')
            core.save()
            return JsonResponse({"status": "success", "msg": "تنظیمات تبریک تولد با موفقیت ذخیره شد."})

        # --- 4.10: ویرایش اطلاعات کاربر ---
        elif action == "edit_member":
            user_id = request.POST.get('user_id')
            new_first_name = request.POST.get('first_name', '').strip()
            new_last_name = request.POST.get('last_name', '').strip()
            new_phone = request.POST.get('phone', '').strip()

            if not user_id:
                return JsonResponse({"status": "error", "msg": "شناسه کاربر مشخص نشده است."})
            
            try:
                user = CustomUser.objects.get(id=user_id, cofe_owner=cafe_obj)
            except CustomUser.DoesNotExist:
                return JsonResponse({"status": "error", "msg": "کاربر یافت نشد."})

            # اعتبارسنجی شماره موبایل (اختیاری)
            if new_phone and (len(new_phone) != 11 or not new_phone.startswith('09')):
                return JsonResponse({"status": "error", "msg": "شماره موبایل نامعتبر است."})
            
            # بررسی یکتایی شماره (به جز خود کاربر)
            if new_phone and CustomUser.objects.filter(phone=new_phone).exclude(id=user_id).exists():
                return JsonResponse({"status": "error", "msg": "این شماره موبایل قبلاً ثبت شده است."})

            # اعمال تغییرات
            user.first_name = new_first_name
            user.last_name = new_last_name
            if new_phone:
                user.phone = new_phone
                user.username = new_phone  # چون username همان شماره است
            user.save()

            # دریافت تعداد کل اعضا برای به‌روزرسانی در قالب
            total_members = CustomUser.objects.filter(cofe_owner=cafe_obj).count()

            return JsonResponse({
                "status": "success",
                "msg": "اطلاعات کاربر با موفقیت به‌روزرسانی شد.",
                "first_name": user.first_name,
                "last_name": user.last_name,
                "phone": user.phone,
                "total_members": total_members
            })

        # --- 4.11: حذف کاربر ---
        elif action == "delete_member":
            user_id = request.POST.get('user_id')
            if not user_id:
                return JsonResponse({"status": "error", "msg": "شناسه کاربر مشخص نشده است."})
            
            try:
                user = CustomUser.objects.get(id=user_id, cofe_owner=cafe_obj)
            except CustomUser.DoesNotExist:
                return JsonResponse({"status": "error", "msg": "کاربر یافت نشد."})
            
            # حذف کاربر (در صورت وجود ارتباطات خارجی، ابتدا وابستگی‌ها را پاک کنید)
            # به عنوان مثال: DeviceProfile.objects.filter(user=user).update(user=None)
            user.delete()
            
            total_members = CustomUser.objects.filter(cofe_owner=cafe_obj).count()
            
            return JsonResponse({
                "status": "success",
                "msg": "کاربر با موفقیت حذف شد.",
                "total_members": total_members
            })
        # 4.5: زمان‌بندی یک پیام جدید
        elif action == "schedule_message":
            message_text = request.POST.get('message_text')
            send_time_str = request.POST.get('scheduled_time')
            target_type = request.POST.get('target_type', 'all')
            
            if not message_text or not send_time_str:
                return JsonResponse({"status": "error", "msg": "لطفاً متن پیام و زمان ارسال را مشخص کنید."})

            try:
                # استفاده از jdatetime برای تبدیل تاریخ شمسی به میلادی
                send_time_obj = jdatetime.datetime.strptime(send_time_str, '%Y/%m/%d %H:%M').togregorian()
                
                # ساخت پیام زمان‌بندی شده جدید با مقادیر هدف
                scheduled_msg = ScheduledMessage(
                    cafe=cafe_obj,
                    message_text=message_text,
                    scheduled_time=send_time_obj,
                    target_type=target_type
                )
                
                if target_type == 'single_member':
                    member_phone = request.POST.get('target_member_phone')
                    # پیدا کردن کاربر مورد نظر
                    target_user = CustomUser.objects.filter(phone=member_phone, cofe_owner=cafe_obj).first()
                    scheduled_msg.target_member = target_user
                elif target_type == 'custom_number':
                    custom_phone = request.POST.get('target_custom_phone')
                    scheduled_msg.target_custom_phone = custom_phone

                scheduled_msg.save()

                return JsonResponse({"status": "success", "msg": "پیام شما با موفقیت زمان‌بندی شد."})
            except (ValueError, TypeError):
                return JsonResponse({"status": "error", "msg": "فرمت تاریخ و زمان نامعتبر است."})

        # 4.6: حذف پیام زمان‌بندی شده
        elif action == "delete_scheduled_message":
            message_id = request.POST.get('message_id')
            if not message_id:
                return JsonResponse({"status": "error", "msg": "شناسه پیام مشخص نشده است."})
            try:
                msg_to_delete = ScheduledMessage.objects.get(id=message_id, cafe=cafe_obj)
                msg_to_delete.delete()
                return JsonResponse({"status": "success", "msg": "پیام زمان‌بندی شده با موفقیت حذف شد."})
            except ScheduledMessage.DoesNotExist:
                return JsonResponse({"status": "error", "msg": "چنین پیامی یافت نشد."})

        # 4.7: ذخیره قالب آماده (NEW)
        elif action == "save_template":
            title = request.POST.get('title')
            message_text = request.POST.get('message')
            if not title or not message_text:
                return JsonResponse({"status": "error", "msg": "عنوان و متن قالب الزامی است."})
            
            CustomSMSTemplate.objects.create(cafe=cafe_obj, title=title, message_text=message_text)
            return JsonResponse({"status": "success", "msg": "قالب جدید با موفقیت ذخیره شد."})

        # 4.8: حذف قالب آماده (NEW)
        elif action == "delete_template":
            template_id = request.POST.get('template_id')
            try:
                CustomSMSTemplate.objects.get(id=template_id, cafe=cafe_obj).delete()
                return JsonResponse({"status": "success", "msg": "قالب با موفقیت حذف شد."})
            except CustomSMSTemplate.DoesNotExist:
                return JsonResponse({"status": "error", "msg": "قالب یافت نشد."})



        # --- 4.9: افزودن دستی عضو به باشگاه (مشتری جدید) ---
        elif action == "add_member":
            member_name = request.POST.get('member_name', '').strip()
            member_phone = request.POST.get('member_phone', '').strip()

            if not member_phone or len(member_phone) != 11 or not member_phone.startswith('09'):
                return JsonResponse({"status": "error", "msg": "شماره موبایل نامعتبر است (باید ۱۱ رقم باشد و با 09 شروع شود)."})

            # از آنجایی که فیلد phone در مدل CustomUser یکتا (unique) است، چک می‌کنیم قبلا ثبت نشده باشد
            if CustomUser.objects.filter(phone=member_phone).exists():
                return JsonResponse({"status": "error", "msg": "این شماره موبایل از قبل در سیستم ثبت شده است."})

            try:
                # چون از AbstractUser ارث‌بری شده، فیلد username اجباری است (ما همان شماره را می‌گذاریم)
                new_user = CustomUser.objects.create(
                    username=member_phone,
                    phone=member_phone,
                    first_name=member_name,
                    cofe_owner=cafe_obj,
                    role=CustomUser.ROLE_CUSTOMER,
                    is_club_member=True,
                    visit_count=0  # چون کاربر دستی اضافه شده
                )
                new_user.set_unusable_password()  # نیازی به رمز عبور ندارد
                new_user.save()
                return JsonResponse({"status": "success", "msg": f"کاربر {member_name} با موفقیت به باشگاه اضافه شد."})
            except Exception as e:
                return JsonResponse({"status": "error", "msg": f"خطا در ثبت اطلاعات: {str(e)}"})

    # --- بخش 5: آماده‌سازی Context برای ارسال به Template ---
    
    # دریافت لیست‌ها برای نمایش در پنل
    scheduled_messages = ScheduledMessage.objects.filter(cafe=cafe_obj).order_by('scheduled_time')
    custom_templates = CustomSMSTemplate.objects.filter(cafe=cafe_obj).order_by('-id')
    history_page_number = request.GET.get('history_page', 1)
    all_sms_history = SMSHistory.objects.filter(cafe=cafe_obj).order_by('-sent_at')
    history_paginator = Paginator(all_sms_history, 10)  # 10 مورد در هر صفحه
    sms_history_page = history_paginator.get_page(history_page_number)

    # تنظیمات Core
    auto_sms_enabled = core.auto_birthday_sms if core else False
    birthday_template = core.birthday_sms_template if core else ""
    send_welcome_sms_enabled = core.send_welcome_sms if core else False
    welcome_sms_template = core.welcome_sms_template if core else ""

    context = {
        'total_members': total_members,
        'recent_count': recent_users.count(),
        'vips': loyal_users.count(),
        'users': users, # ارسال همه کاربرها برای لیست و دراپ‌داون انتخاب کاربر
        'sms_credit': current_credit,
        'cafe_api_key': cafe_api_key,
        'cafe_line_number': cafe_line_number,
        'cafe_slug': cafe_slug,
        
        # متغیرهای مربوط به امکانات جدید
        'scheduled_messages': scheduled_messages,
        'custom_templates': custom_templates,
        'sms_history': sms_history_page,
        
        # تنظیمات سوییچ‌ها و تکست‌باکس‌ها
        'auto_sms_enabled': auto_sms_enabled,
        'birthday_template': birthday_template,
        'send_welcome_sms_enabled': send_welcome_sms_enabled,
        'welcome_sms_template': welcome_sms_template,
        'search_query': search_query, # برای حفظ متن سرچ شده در اینپوت

    }

    return render(request, 'panel/club_dashboard.html', context)

# def club_dashboard(request , cafe_slug):
#     # ... (بررسی‌های دسترسی شما که در کد اصلی بود) ...
#     try:
#         current_coffe = request.user.cofe_owner.slug
#         if not request.user.is_superuser:
#             if cafe_slug != current_coffe :
#                 return redirect("no_permission" , cafe_slug) 
#     except:
#         if request.user.is_superuser:
#             pass
#         else:
#             return redirect("no_permission" , cafe_slug) 
        
#     core = Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()
#     settings = SMS_Template.objects.filter(cofe_owner__slug=cafe_slug).first()
#     if settings is None:
#         cafe = CoffeShops.objects.get(slug=cafe_slug)
#         settings = SMS_Template.objects.create(cofe_owner= cafe)

#     if settings and core.plan_level < 4:
#         return render(request, 'panel/403.html', {"msg": "این بخش در اشتراک شما نیست." , 'cafe_slug':cafe_slug})

#     users = CustomUser.objects.all().filter(cofe_owner__slug=cafe_slug)

    
#     total_members = users.count()
#     recent_users = users.filter(last_visit__gte=timezone.now() - timedelta(days=7))
#     loyal_users = users.filter(visit_count__gte=5) 
    
#     # گرفتن اطلاعات پیامک کاربر از تنظیمات
#     cafe_api_key = settings.sms_api_key if settings else None
#     cafe_line_number = settings.sms_line_number if settings else None
    
#     current_credit = get_sms_credit(cafe_api_key)

    
    
#     # ------------------ اضافه کردن بخش ساخت اکسل ------------------
#     if request.GET.get('export') == 'excel':
#         # ساخت یک ورک‌بوک اکسل
#         wb = openpyxl.Workbook()
#         ws = wb.active
#         ws.title = "لیست مشتریان"
#         ws.sheet_view.rightToLeft = True # راست‌چین کردن فایل اکسل
        
#         # اضافه کردن هدر (عناوین ستون‌ها)
#         ws.append(["شماره موبایل", "نام مشتری", "تعداد مراجعه", "آخرین بازدید"])
        
#         # پر کردن ردیف‌ها با داده‌های کاربران
#         for u in users:
#             # تبدیل تاریخ به رشته (اگر تاریخ نداشت مقدار 'ندارد' قرار می‌گیرد)
#             last_visit_str = u.last_visit.strftime("%Y/%m/%d") if u.last_visit else "ندارد"
            
#             ws.append([
#                 u.phone, 
#                 u.first_name if u.first_name else "ناشناس", 
#                 u.visit_count, 
#                 last_visit_str
#             ])
            
#         # آماده‌سازی پاسخ HTTP برای دانلود فایل
#         response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
#         response['Content-Disposition'] = f'attachment; filename=customers_{cafe_slug}.xlsx'
        
#         # ذخیره اطلاعات در response
#         wb.save(response)
#         return response
#     # --------------------------------------------------------------

#     # --- (بقیه کدهای شما شامل total_members و بخش POST) ---

#     if request.method == "POST":
#         action = request.POST.get('action')

#         # 1. بخش ذخیره تنظیمات پیامک (توکن و شماره خط)
#         if action == "save_settings":
#             new_api_key = request.POST.get('api_key')
#             new_line_number = request.POST.get('line_number')
            
#             if settings:
#                 settings.sms_api_key = new_api_key
#                 settings.sms_line_number = new_line_number
#                 settings.save()
#                 return JsonResponse({"status": "success", "msg": "تنظیمات پیامک شما با موفقیت ذخیره شد."})
#             return JsonResponse({"status": "error", "msg": "تنظیمات کافه یافت نشد."})

#         # 2. بخش ارسال پیامک
#         elif action == "send_sms":
#             if not cafe_api_key or not cafe_line_number:
#                 return JsonResponse({"status": "error", "msg": "ابتدا توکن و شماره خط خود را در همین صفحه ذخیره کنید."})

#             target = request.POST.get('target')
#             message = request.POST.get('message')
            
#             if not message:
#                 return JsonResponse({"status": "error", "msg": "متن پیام نمی‌تواند خالی باشد."})

#             mobiles = []

#             if target == "single_member":
#                 member_phone = request.POST.get('member_phone')
#                 if member_phone: mobiles = [member_phone]
#             elif target == "custom_number":
#                 custom_phone = request.POST.get('custom_phone')
#                 if custom_phone and len(custom_phone) == 11: mobiles = [custom_phone]
#                 else: return JsonResponse({"status": "error", "msg": "شماره موبایل نامعتبر است."})
#             else:
#                 selected_users = users.none()
#                 if target == "recent": selected_users = recent_users
#                 elif target == "loyal": selected_users = loyal_users
#                 elif target == "birthday":
#                     today = timezone.now().date()
#                     selected_users = users.filter(birth_date__month=today.month, birth_date__day=today.day)
#                 elif target == "all": selected_users = users

#                 mobiles = list(selected_users.values_list('phone', flat=True))
#                 mobiles = [m for m in mobiles if m and len(m) == 11]

#             if not mobiles:
#                 return JsonResponse({"status": "error", "msg": "مخاطبی یافت نشد."})

#             # بررسی موجودی پنل (فرض بر این است که current_credit تعداد است، اگر مبلغ به ریال است فرمول را تغییر دهید)
#             if current_credit < len(mobiles):
#                 return JsonResponse({"status": "error", "msg": f"موجودی شما کافی نیست. تعداد مخاطبین {len(mobiles)} نفر است."})

#             # ارسال پیامک با توکن و خط خود کافه
#             api_response = send_bulk_sms(cafe_api_key, cafe_line_number, mobiles, message)
            
#             if api_response.get("status") == 1:
#                 return JsonResponse({
#                     "status": "success", 
#                     "msg": f"پیامک با موفقیت به {len(mobiles)} نفر ارسال شد."
#                 })
#             else:
#                 return JsonResponse({
#                     "status": "error", 
#                     "msg": f"خطا در سرور پیامک: {api_response.get('message', 'نامشخص')}"
#                 })

#     return render(request, 'panel/club_dashboard.html', {
#         'total_members': total_members,
#         'recent_count': recent_users.count(),
#         'vips': loyal_users.count(),
#         'users': users.order_by('-last_visit')[:3],
#         'sms_credit': current_credit,
#         'cafe_api_key': cafe_api_key,
#         'cafe_line_number': cafe_line_number,
#         'cafe_slug': cafe_slug
#     })



def manage_smart_rules(request , cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission" , cafe_slug)  # یا 403

    if request.method == 'POST':
        action = request.POST.get('action')
        
        # ثبت قانون جدید
        if action == 'add':
            name = request.POST.get('name')
            rule_type = request.POST.get('rule_type')
            target_food_id = request.POST.get('target_food')
            min_purchases = request.POST.get('min_purchases')
            cafe = CoffeShops.objects.get(slug=cafe_slug)
            rule = SmartRule(
                name=name,
                rule_type=rule_type,
                target_food_id=target_food_id,
                min_purchases=min_purchases,
                cofe_owner=cafe
            )
            
            if rule_type == 'discount':
                rule.discount_percent = request.POST.get('discount_percent', 0)
            elif rule_type == 'recommend':
                rule.suggested_food_id = request.POST.get('suggested_food')
                
            rule.save()
            
        # تغییر وضعیت فعال/غیرفعال
        elif action == 'toggle':
            rule_id = request.POST.get('rule_id')
            rule = SmartRule.objects.filter(id=rule_id, cofe_owner__slug=cafe_slug).first()
            if rule:
                rule.is_active = not rule.is_active
                rule.save()
                
        # حذف قانون
        elif action == 'delete':
            rule_id = request.POST.get('rule_id')
            SmartRule.objects.filter(id=rule_id , cofe_owner__slug=cafe_slug).delete()
            
        return redirect('smart_rules' , cafe_slug=cafe_slug) # رفرش صفحه پس از عملیات

    # دریافت اطلاعات برای نمایش در صفحه
    rules = SmartRule.objects.all().order_by('-id').filter(cofe_owner__slug=cafe_slug)
    foods = Food.objects.filter(cofe_owner__slug=cafe_slug , is_deleted=False)
    site_settings = Core_Settings.objects.filter(cofe_owner__slug=cafe_slug).first()
    
    return render(request, 'panel/smart_rules.html', {
        'rules': rules,
        'foods': foods,
        'site_settings': site_settings,
        'cafe_slug':cafe_slug
    })






from django.shortcuts import redirect
from django.urls import reverse
# در صورت نیاز مدل کافه را ایمپورت کنید تا از وجود آن مطمئن شوید
# from .models import Cofe 

def qr_redirect_view(request, cafe_slug, table_number):
    """
    ویوی مخصوص اسکن QR Code
    آدرس ورودی: /qr/<cafe_slug>/<table_number>/
    """
    
    # (اختیاری) می‌توانید اینجا چک کنید که آیا کافه‌ای با این اسلاگ وجود دارد یا خیر
    # cafe = get_object_or_404(Cofe, slug=cafe_slug)
    
    # ۱. تولید آدرس صفحه منوی رستوران
    # فرض می‌کنیم اسم ویوی منوی شما در urls.py برابر با 'cafe_menu' است
    # اگر اسم ویو چیز دیگری است، آن را جایگزین کنید یا مستقیماً آدرس را رشته‌ای بدهید: f"/{cafe_slug}/"
    try:
        menu_url = reverse('cafe_menu', kwargs={'cafe_slug': cafe_slug})
    except:
        # اگر نام ویو تنظیم نشده بود، آدرس پیش‌فرض می‌سازیم
        menu_url = f"/{cafe_slug}/"
    
    # ۲. اضافه کردن شماره میز به صورت Query Parameter (مثلاً: /cafe-pars/?table=5)
    redirect_url = f"{menu_url}?table_number={table_number}"
    
    # ۳. ایجاد ریسپانسِ ریدایرکت
    response = redirect(redirect_url)
    
    # ۴. (پیشنهاد ویژه): ذخیره شماره میز در کوکی‌ها (Cookies)
    # با این کار حتی اگر مشتری بعداً به لینک بدون ?table=5 برود، سایت همچنان می‌داند میز او چند است.
    
    return response

def qr_playlist_redirect_view(request, cafe_slug, table_number):
    """
    ویوی مخصوص اسکن QR Code برای پلی‌لیست آهنگ‌ها (همراه با شماره میز)
    آدرس ورودی: /qr/playlist/<cafe_slug>/<table_number>/
    """
    
    # آدرس صفحه پلی‌لیست (با ارسال شماره میز به عنوان پارامتر)
    # اینطوری بعداً در فرانت‌اند یا بک‌اند می‌توانید بگویید اگر میز ۵ بود آهنگ X پخش شود
    playlist_url = f"/{cafe_slug}/music/playlist/?table_number={table_number}"
    
    response = redirect(playlist_url)
    
    # شماره میز را اینجا هم در کوکی ذخیره می‌کنیم
    # تا اگر مشتری اول آهنگ را اسکن کرد، میز او برای سفارش غذا هم ثبت شده باشد!
    
    return response



def print_receipt(request, order_id , cafe_slug):


    Cafe = CoffeShops.objects.get(slug=cafe_slug)
    order = Order.objects.get(id=order_id , cafe=Cafe)

    return render(request,'receipt.html',{
        'order':order
    })


def no_permission(request , cafe_slug):
    referer = request.META.get('HTTP_REFERER')

    # if not referer:
    #     return redirect('menu' , cafe_slug)

    return render(request , 'no_permission.html')

from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages

# CREATE MANUAL ORDER
@api_view(['POST'])
def create_manual_order(request, cafe_slug):
    try:
        current_coffe = request.user.cofe_owner.slug
        if not request.user.is_superuser:
            if cafe_slug != current_coffe :
                return redirect("no_permission" , cafe_slug) 
    except:
        if request.user.is_superuser:
            pass
        else:
            return redirect("no_permission" , cafe_slug) 

    if not request.user.is_superuser:    
        user = request.user
        if user.role not in [CustomUser.ROLE_MANAGER,CustomUser.ROLE_WAITER]:
            return redirect("no_permission" , cafe_slug)  # یا 403

    data = request.data

    table_number = data.get('table_number')
    items = data.get('items', [])
    customer_data = data.get('customer', None)
    cafe= CoffeShops.objects.get(slug=cafe_slug)

    if not table_number:
        return Response({'status': 'error', 'message': 'شماره میز الزامی است'}, status=400)

    if not items or len(items) == 0:
        return Response({'status': 'error', 'message': 'هیچ آیتمی انتخاب نشده'}, status=400)

    # پیدا کردن میز
    try:
        table = Table.objects.get(number=table_number, cofe_owner__slug=cafe_slug)
    except Table.DoesNotExist:
        table = Table.objects.create(number=table_number, cofe_owner=cafe)


    # اگر مشتری پر شده باشد → ثبت/جستجو
    customer = None
    if customer_data and customer_data.get('phone'):
        customer, _ = CustomUser.objects.get_or_create(
            phone=customer_data['phone'],
            defaults={
                'name': customer_data.get('name', ''),
                'birthdate': customer_data.get('birthdate', None),
                'cofe_owner': table.cofe_owner
            }
        )

    # ایجاد سفارش
    with transaction.atomic():

        order = Order.objects.create(
            table=table,
            status='pending',
            cofe_owner=table.cofe_owner,
            total_price=0,
        )

        total_price = 0

        # ایجاد آیتم‌های سفارش
        for item in items:
            food_id = item.get('id')
            qty = int(item.get('quantity', 1))

            try:
                food = Food.objects.get(
                    id=food_id, cofe_owner__slug=cafe_slug, is_deleted=False
                )
            except Food.DoesNotExist:
                continue

            line_total = food.price * qty

            OrderItem.objects.create(
                order=order,
                food=food,
                quantity=qty,
                price_at_order=line_total,
                cofe_owner=table.cofe_owner
            )

            total_price += line_total

        order.total_price = total_price
        order.save()

    return Response({'status': 'success', 'order_id': order.id})




from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.hashers import make_password
# حتما مدل‌های کافه و یوزر خودتان را ایمپورت کنید
# from .models import CustomUser, CoffeShops 

@login_required
@user_passes_test(lambda u: u.is_superuser)
def add_user_view(request ,  cafe_slug):
    # دریافت لیست تمام کافه‌ها برای نمایش در Select Box (ویژه ادمین کل)
    cafes = CoffeShops.objects.all()

    if request.method == 'POST':
        username = request.POST.get('username')
        phone = request.POST.get('phone')
        password = request.POST.get('password')
        email = request.POST.get('email')
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        role = request.POST.get('role')
        cofe_owner_id = request.POST.get('cofe_owner')
        birth_date = request.POST.get('birth_date')

        # ۱. اعتبارسنجی ساده
        if CustomUser.objects.filter(phone=phone).exists():
            messages.error(request, 'خطا: کاربری با این شماره تماس از قبل وجود دارد.')
            return redirect('add_user' , cafe_slug) # نام URL اختصاصی خودتان را بگذارید
            
        if CustomUser.objects.filter(username=username).exists():
            messages.error(request, 'خطا: این نام کاربری قبلا ثبت شده است.')
            return redirect('add_user' , cafe_slug)

        try:
            # ۲. ساخت کاربر با متد مخصوص جنگو
            user = CustomUser.objects.create_user(
                username=username,
                phone=phone,
                password=password,  # create_user خودش پسورد را هَش می‌کند
                email=email,
                first_name=first_name,
                last_name=last_name,
                role=role,
                is_club_member=False  # پرسنل ادمین/ویتر نیازی به باشگاه مشتریان ندارند
            )
            
            # ۳. اتصال به کافه در صورت انتخاب
            if cofe_owner_id:
                user.cofe_owner_id = cofe_owner_id
                
            # ۴. مدیریت تاریخ تولد (اختیاری)
            # اگر کتابخانه jdatetime دارید باید تاریخ شمسی ورودی را به میلادی تبدیل کنید
            # user.birth_date = convert_to_gregorian(birth_date) 
            
            user.save()
            messages.success(request, f'کاربر {first_name} {last_name} با نقش تخصیص داده شده با موفقیت ساخته شد.')
            return redirect('add_user' , cafe_slug)
            
        except Exception as e:
            messages.error(request, f'خطای سیستمی در ساخت کاربر: {str(e)}')

    context = {
        'cafes': cafes
    }
    return render(request, 'add_user.html', context)


@login_required
@user_passes_test(lambda u: u.is_superuser)
def cafe_list_view(request):
    # دریافت تمام کافه‌ها از دیتابیس
    cafes = CoffeShops.objects.all()
    
    context = {
        'cafes': cafes
    }
    return render(request, 'cafe_list.html', context)


@login_required
@user_passes_test(lambda u: u.is_superuser)
def export_club_sql_view(request, cafe_id):
    # پیدا کردن کافه مورد نظر
    try:
        cafe = CoffeShops.objects.get(id=cafe_id)
    except CoffeShops.DoesNotExist:
        return HttpResponse("کافه پیدا نشد.", status=404)

    # دریافت تمام کاربرانی که عضو باشگاه مشتریان این کافه هستند
    # فرض بر این است که اعضای باشگاه is_club_member=True دارند
    club_members = CustomUser.objects.filter(cofe_owner=cafe, is_club_member=True)

    # ساخت محتوای فایل SQL به صورت دستی (دستورات INSERT)
    sql_lines = []
    sql_lines.append(f"-- ===========================================")
    sql_lines.append(f"-- دیتای باشگاه مشتریان کافه : {cafe.name}")
    sql_lines.append(f"-- تعداد اعضا: {club_members.count()}")
    sql_lines.append(f"-- ===========================================\n")

    for member in club_members:
        # جلوگیری از خطای سینتکس در SQL در صورت وجود کاراکتر کوتیشن در نام
        first_name = member.first_name.replace("'", "''") if member.first_name else ""
        last_name = member.last_name.replace("'", "''") if member.last_name else ""
        phone = member.phone if member.phone else ""
        
        # ساخت کوئری اینسرت (نام جدول را بسته به نیاز خودتان میتوانید در خط زیر تغییر دهید)
        sql_lines.append(
            f"INSERT INTO customer_club (phone, first_name, last_name, cafe_id) "
            f"VALUES ('{phone}', '{first_name}', '{last_name}', {cafe.id});"
        )

    sql_content = "\n".join(sql_lines)

    # تنظیم ریسپانس برای دانلود به عنوان فایل sql
    response = HttpResponse(sql_content, content_type='application/sql')
    response['Content-Disposition'] = f'attachment; filename="club_members_{cafe.id}.sql"'
    return response

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
# from .models import CustomUser

@login_required
def add_staff_view(request, cafe_slug, staff_id=None): # 🔴 staff_id=None اضافه شد
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission", cafe_slug)  

    # دریافت کافه
    current_cafe = get_object_or_404(CoffeShops, slug=cafe_slug)

    # 🔴 اگر staff_id داشته باشیم، یعنی در حال ویرایش هستیم
    staff_instance = None
    if staff_id:
        staff_instance = get_object_or_404(CustomUser, id=staff_id, cofe_owner=current_cafe)

    if request.method == 'POST':
        username = request.POST.get('username')
        phone = request.POST.get('phone')
        password = request.POST.get('password')
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        role = request.POST.get('role')

        # ۱. اعتبارسنجی (باید چک کنیم شماره یا یوزرنیم مال شخص دیگری نباشد)
        # استفاده از exclude باعث می‌شود شماره و یوزرنیم خود شخصِ در حال ویرایش، خطا ندهد
        if CustomUser.objects.filter(phone=phone).exclude(id=staff_id).exists():
            messages.error(request, 'خطا: کاربری با این شماره تماس از قبل وجود دارد.')
            return redirect(request.path) # برگشت به همین صفحه‌ای که هستیم
            
        if CustomUser.objects.filter(username=username).exclude(id=staff_id).exists():
            messages.error(request, 'خطا: این نام کاربری قبلا ثبت شده است.')
            return redirect(request.path)

        try:
            if staff_instance:
                # 🔴 حالت ویرایش: به‌روزرسانی اطلاعات پرسنل موجود
                staff_instance.username = username
                staff_instance.phone = phone
                staff_instance.first_name = first_name
                staff_instance.last_name = last_name
                staff_instance.role = role
                
                # فقط اگر رمز عبور جدید وارد شده بود، آن را تغییر بده
                if password: 
                    staff_instance.set_password(password)
                    
                staff_instance.save()
                messages.success(request, f'اطلاعات {first_name} {last_name} با موفقیت ویرایش شد.')
                
            else:
                # 🔴 حالت افزودن: ساخت کاربر (پرسنل) جدید
                new_user = CustomUser.objects.create_user(
                    username=username,
                    phone=phone,
                    password=password,
                    first_name=first_name,
                    last_name=last_name,
                    role=role,
                    cofe_owner=current_cafe,
                    is_club_member=False 
                )
                messages.success(request, f'{first_name} {last_name} به عنوان {new_user.get_role_display()} به کافه شما اضافه شد.')
                
            # بعد از موفقیت، کاربر را به صفحه لیست پرسنل هدایت کنید (نام url لیست خودتان را جایگزین کنید)
            # return redirect('staff_list_view_name', cafe_slug) 
            return redirect(request.path) # فعلا به همین صفحه برمی‌گردد
            
        except Exception as e:
            messages.error(request, f'خطای سیستمی: {str(e)}')

    # ارسال اطلاعات به قالب (در حالت افزودن staff_instance برابر None است)
    context = {
        'cafe_name': current_cafe.name if current_cafe else "کافه نامشخص",
        'staff': staff_instance, # 🔴 ارسال پرسنل به قالب برای پر کردن فرم ویرایش
        'cafe_slug': cafe_slug
    }
    return render(request, 'add_staff.html', context)


from django.core import serializers

@login_required
@user_passes_test(lambda u: u.is_superuser)
def export_cafe_all_data_view(request, cafe_id):

    cafe_sluger = CoffeShops.objects.get(id=cafe_id)
    user = request.user
    if not request.user.is_superuser:    

        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe_sluger)  # یا 403


    # ۱. دریافت کافه
    cafe = get_object_or_404(CoffeShops, id=cafe_id)
    
    # ۲. پیدا کردن تمام اطلاعات مربوط به این کافه
    # فرض می‌کنیم مدل‌های شما فیلدی به نام cafe یا cofe_owner دارند
    users = CustomUser.objects.filter(cofe_owner=cafe)
    categories = category.objects.filter(cofe_owner=cafe)
    menu_items = OrderItem.objects.filter(cofe_owner=cafe) # یا filter(cafe=cafe) اگر فیلدش را دارید
    orders = Order.objects.filter(cofe_owner=cafe)
    
    # ترکیب همه آبجکت‌ها در یک لیست (می‌توانید مدل‌های دیگر را هم اضافه کنید)
    all_objects = list([cafe]) + list(users) + list(categories) + list(menu_items) + list(orders)
    
    # ۳. تبدیل اطلاعات به فرمت JSON (استاندارد جنگو)
    data = serializers.serialize("json", all_objects, indent=4)
    
    # ۴. ایجاد فایل دانلودی
    response = HttpResponse(data, content_type='application/json')
    # نام فایل شامل اسم کافه خواهد بود تا قاطی نشود
    filename = f"backup_{cafe.slug}_all_data.json"
    response['Content-Disposition'] = f'attachment; filename="{filename}"'
    
    return response



@login_required
@user_passes_test(lambda u: u.is_superuser)
def add_cafe_with_owner_view(request):
    if request.method == 'POST':
        # اطلاعات کافه
        cafe_name = request.POST.get('cafe_name')
        cafe_slug = request.POST.get('cafe_slug')
        
        # اطلاعات مدیر/صاحب کافه
        username = request.POST.get('owner_username')
        password = request.POST.get('owner_password')
        first_name = request.POST.get('owner_first_name')
        last_name = request.POST.get('owner_last_name')
        phone_number = request.POST.get('owner_phone')
        
                # ۱. چک کردن تکراری نبودن اسلاگ کافه
        if CoffeShops.objects.filter(slug=cafe_slug).exists():
            messages.error(request, 'این شناسه (اسلاگ) انگلیسی قبلاً برای کافه دیگری ثبت شده است.')
            return redirect('نام_ویوی_همین_صفحه') # مثلا 'cafe_list'

        # ۲. چک کردن تکراری نبودن نام کاربری
        if CustomUser.objects.filter(username=username).exists():
            messages.error(request, 'این نام کاربری قبلاً در سیستم ثبت شده است. لطفاً نام دیگری انتخاب کنید.')
            return redirect('نام_ویوی_همین_صفحه')

        if CustomUser.objects.filter(phone=phone_number).exists():
            messages.error(request, 'این شماره تماس قبلاً در سیستم ثبت شده است.')
            return redirect('نام_ویوی_همین_صفحه')


        try:
            # استفاده از transaction تا در صورت بروز خطا در ساخت کاربر، کافه هم ساخته نشود
            with transaction.atomic():
                # ۱. ساخت کافه جدید
                new_cafe = CoffeShops.objects.create(
                    name=cafe_name,
                    slug=cafe_slug
                )
                
                # ۲. ساخت کاربر به عنوان صاحب/مدیر این کافه
                new_user = CustomUser.objects.create_user(
                    username=username,
                    password=password,
                    first_name=first_name,
                    last_name=last_name,
                    phone=phone_number,
                    role='manager', # نقش را روی مدیر تنظیم می‌کنیم (دقیقاً مثل مقداری که در مدل خود دارید)
                    cofe_owner=new_cafe # اختصاص این کاربر به کافه جدید
                )
                
                Core_Settings.objects.create(
                    cafe_owner=new_cafe
                )
            messages.success(request, f'کافه "{cafe_name}" و مدیر آن با موفقیت ایجاد شدند.')
        except Exception as e:
            messages.error(request, f'خطا در ثبت اطلاعات. احتمالاً نام کاربری یا شناسه کافه تکراری است.')
            
    # در هر صورت (موفقیت یا شکست) کاربر را به همان صفحه لیست کافه‌ها برمی‌گردانیم
    return redirect('cafe_list')



# views.py


# ... سایر ویوهای شما ...

# ویوی جدید برای نمایش کاربران یک کافه
@user_passes_test(lambda u: u.is_superuser)
def cafe_user_list(request, cafe_slug):
    # ابتدا کافه مورد نظر را پیدا می‌کنیم
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    
    # سپس تمام کاربرانی که به این کافه تعلق دارند را فیلتر می‌کنیم
    users = CustomUser.objects.filter(cofe_owner=cafe)
    
    context = {
        'cafe': cafe,
        'users': users,
        'cafe_slug': cafe_slug,
    }
    # این context را به یک تمپلیت جدید به نام cafe_user_list.html ارسال می‌کنیم
    return render(request, 'panel/cafe_user_list.html', context)


# ویوی جدید برای تغییر پلن کافه
def update_cafe_plan(request, cafe_slug):
    if request.method == 'POST':
        # کافه مورد نظر را پیدا می‌کنیم
        cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
        
        # پلن جدید را از فرم دریافت می‌کنیم
        new_plan = request.POST.get('plan_level')
        
        # تنظیمات مربوط به کافه را پیدا کرده و پلن را آپدیت می‌کنیم
        settings, created = Core_Settings.objects.get_or_create(cofe_owner=cafe)
        settings.plan_level = int(new_plan)
        settings.save()
        
        # کاربر را به همان صفحه لیست کافه‌ها برمی‌گردانیم
        # *** توجه: 'admin_dashboard' نام ویوی لیست کافه‌ها است، اگر نام دیگری دارد آن را جایگزین کنید ***
        return redirect('cafe_list' ) 
        
    # اگر متد GET بود، به صفحه‌ی اصلی برگردان
    return redirect('cafe_list')



@api_view(['POST'])
def check_club_status(request, cafe_slug):
    """ بررسی می‌کند که آیا فرم باشگاه باید به این دستگاه نمایش داده شود یا خیر """
    print('222')
    device_id = request.data.get('device_id') or request.COOKIES.get('device_id')

    print('333')
    
    if not device_id:
        return Response({'show_form': False})

    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    
    # --- اصلاح مشکل یکتا بودن دستگاه ---
    device = DeviceProfile.objects.filter(device_id=device_id , cofe_owner = cafe).first()
    if not device:
        device = DeviceProfile.objects.create(device_id=device_id, cofe_owner=cafe)
    # -----------------------------------

    # ۱. اگر این دستگاه قبلا به یک کاربر (عضو باشگاه) متصل شده، دیگر فرم را نشان نده
    if device.user is not None:
        return Response({'show_form': False})

    # ۲. بررسی قانون ۲ هفته سکوت
    if device.club_form_ignored_at:
        two_weeks_ago = timezone.now() - timedelta(days=14)
        # اگر تاریخ انصراف بزرگتر از دو هفته پیش است (یعنی هنوز ۲ هفته نگذشته)
        if device.club_form_ignored_at > two_weeks_ago:
            return Response({'show_form': False})

    # در غیر این صورت، فرم را نشان بده
    return Response({'show_form': True})


@api_view(['POST'])
def ignore_club_form(request, cafe_slug):
    """ زمانی که کاربر دکمه رد کردن را می‌زند، تاریخ فعلی را ثبت می‌کند """
    device_id = request.data.get('device_id') or request.COOKIES.get('device_id')
    
    if device_id:
        # --- اصلاح: دستگاه را فقط با شناسه‌اش جستجو می‌کنیم ---
        device = DeviceProfile.objects.filter(device_id=device_id).first()
        
        if device:
            device.club_form_ignored_at = timezone.now()
            device.save()
            
    return Response({'status': 'ignored'})


@login_required
def staff_list_view(request , cafe_slug):
    cafe_sluger = CoffeShops.objects.get(slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe_sluger)  # یا 403

    # فرض بر این است که شما پرسنل را بر اساس کافه‌ی صاحب‌کافه فیلتر می‌کنید
    # این کوئری را بر اساس ساختار مدل‌های خودتان تنظیم کنید
    staff_members = CustomUser.objects.filter(
                cofe_owner=cafe_sluger,
                role__in=[CustomUser.ROLE_WAITER, CustomUser.ROLE_ACCOUNTANT]
            ).order_by('-id') # مرتب‌سازی از جدیدترین به قدیمی‌ترین   
     
    
    context = {
        'staff_members': staff_members,
        'cafe_slug':cafe_slug
    }
    return render(request, 'staff_list.html', context)




@login_required
def toggle_staff_status_view(request, staff_id , cafe_slug):
    cafe_sluger = CoffeShops.objects.get(slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe_sluger)  # یا 403

    # پرسنل را پیدا می‌کنیم (فقط پرسنلی که برای کافه همین مدیر هستند)
    staff = get_object_or_404(CustomUser, id=staff_id, cofe_owner=cafe_sluger)
    
    # تغییر وضعیت (معکوس کردن مقدار فعلی)
    staff.is_active = not staff.is_active
    staff.save()
    
    # پیام موفقیت
    status_text = "فعال" if staff.is_active else "غیرفعال"
    messages.success(request, f"وضعیت {staff.get_full_name() or staff.username} با موفقیت {status_text} شد.")
    
    # بازگشت به صفحه لیست پرسنل (نام URL لیست پرسنل خود را اینجا بنویسید)
    return redirect('staff_list_view' , cafe_slug)




from django.shortcuts import render, redirect, get_object_or_404
from .models import CoffeShops, TableMusic

# 1. صفحه ورود شماره میز
def music_table_entry(request, cafe_slug):
    cafe_sluger = CoffeShops.objects.get(slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe_sluger)  # یا 403

    # دریافت اطلاعات کافه
    # cofe = get_object_or_404(Cofe, slug=cafe_slug) 
    
    # دریافت تمام آهنگ‌های این کافه
    all_tracks = TableMusic.objects.filter(cofe_owner__slug=cafe_slug).order_by('table_number', 'order')
    
    # گروه‌بندی آهنگ‌ها بر اساس شماره میز (تا در HTML راحت نمایش دهیم)
    tables_data = {}
    for track in all_tracks:
        if track.table_number not in tables_data:
            tables_data[track.table_number] = []
        tables_data[track.table_number].append(track)
        
    context = {
        'cafe_slug': cafe_slug,
        'tables_data': tables_data,
    }
    return render(request, 'music_table_entry.html', context)

# در فایل views.py

from django.shortcuts import render, get_object_or_404
from .models import CoffeShops, TableMusic # مدل‌های خود را import کنید
# views.py

from django.http import JsonResponse, HttpResponseBadRequest
from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
# ایمپورت مدل‌های TableMusic و CoffeShops فراموش نشود

@login_required
def music_upload_page(request, cafe_slug, table_number):
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403

    # این ویو فقط برای دریافت فایل از طریق AJAX است
    table_number_str = str(table_number)

    if request.method == 'POST':
        audio = request.FILES.get('audio_file')
        title = request.POST.get('title', 'موزیک ناشناس')
        
        if audio:
            last_order_obj = TableMusic.objects.filter(cofe_owner=cafe, table_number=table_number_str).order_by('-order').first()
            new_order = (last_order_obj.order + 1) if last_order_obj and last_order_obj.order is not None else 1

            TableMusic.objects.create(
                cofe_owner=cafe,
                table_number=table_number_str,
                title=title,
                audio_file=audio,
                order=new_order
            )
            # فقط یک تاییدیه موفقیت برمی‌گردانیم
            return JsonResponse({'status': 'success'})
        
        return JsonResponse({'status': 'error', 'message': 'فایلی یافت نشد'}, status=400)
            
    return HttpResponseBadRequest("درخواست نامعتبر است.")

# 3. صفحه پخش و دانلود آهنگ (پلی‌لیست)
def table_playlist(request, cafe_slug, table_number):
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    core_setting = Core_Settings.objects.filter(cofe_owner = cafe).first()
    # دریافت آهنگ‌های این میز از جدیدترین به قدیمی‌ترین
    tracks = TableMusic.objects.filter(cofe_owner=cafe, table_number=table_number).order_by('order')
    
    return render(request, 'music_playlist.html', {
        'cafe_slug': cafe_slug, 
        'table_number': table_number,
        'tracks': tracks,
        'core_setting': core_setting
    })



from django.shortcuts import get_object_or_404, redirect

def delete_music(request, cafe_slug , track_id):
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403

    if not request.user.is_authenticated:
        return redirect('login')
    
    track = get_object_or_404(TableMusic, id=track_id, cofe_owner__slug=cafe_slug)
    table_number = track.table_number
    cafe_slug = track.cofe_owner.slug
    
    # حذف فایل از هاست دانلود (اختیاری اما توصیه می‌شود)
    track.audio_file.delete() 
    # حذف رکورد از دیتابیس
    track.delete()
    
    return redirect('table_playlist', cafe_slug=cafe_slug, table_number=table_number)



import json
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from .models import TableMusic # مدل خود را ایمپورت کنید


@login_required
@require_POST
def bulk_delete_music(request, cafe_slug):
    """ویو برای حذف گروهی چند آهنگ به صورت AJAX"""
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403

    try:
        data = json.loads(request.body)
        track_ids = data.get('track_ids', [])
        
        if not track_ids:
            return JsonResponse({'success': False, 'error': 'هیچ آهنگی انتخاب نشده است.'}, status=400)

        # فیلتر کردن آهنگ‌های متعلق به این کافه و حذف آن‌ها
        tracks = TableMusic.objects.filter(id__in=track_ids, cofe_owner__slug=cafe_slug)
        
        deleted_count = 0
        for track in tracks:
            track.audio_file.delete() # حذف فایل از هاست دانلود
            track.delete()            # حذف رکورد
            deleted_count += 1
            
        return JsonResponse({'success': True, 'deleted_count': deleted_count})
    except Exception as e:
        return JsonResponse({'success': False, 'error': str(e)}, status=500)

@login_required
@require_POST
def update_music_order(request, cafe_slug):
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403

    try:
        data = json.loads(request.body)
        order_data = data.get('order_data', [])
        
        # آپدیت کردن ترتیب آهنگ‌ها در دیتابیس
        for item in order_data:
            music_id = item.get('id')
            new_order = item.get('order')
            
            # جستجوی آهنگ و آپدیت فیلد 'order'
            music = TableMusic.objects.get(id=music_id , cofe_owner__slug=cafe_slug)
            if music:
                music.order = new_order
                music.save()
                
        return JsonResponse({'status': 'success', 'message': 'ترتیب با موفقیت به‌روزرسانی شد.'})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
    


from django.shortcuts import redirect, get_object_or_404
from django.contrib import messages
from .models import TableMusic, CoffeShops # مطمئن شوید مدل‌هایتان ایمپورت شده‌اند

def music_table_entry_origin(request, cafe_slug):
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403

    if request.method == 'POST':
        table_number = request.POST.get('table_number')
        
        # پیدا کردن کافه مربوطه با استفاده از slug
        # (اگر فیلد شما در مدل کافه نام دیگری دارد آن را جایگزین کنید)
        cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
        
        # بررسی اینکه آیا این میز از قبل وجود دارد یا خیر
        table_number = request.POST.get('table_number')
        
        if table_number:
            # بررسی اینکه آیا این میز قبلا ایجاد شده است یا خیر (اختیاری)
            table_exists = TableMusic.objects.filter(cofe_owner=cafe, table_number=table_number).exists()
            
            if not table_exists:
                # ایجاد یک میز خالی
                TableMusic.objects.create(
                    cofe_owner=cafe,
                    table_number=table_number
                )
                messages.success(request, f'میز شماره {table_number} با موفقیت ایجاد شد.')
            else:
                messages.warning(request, f'میز شماره {table_number} از قبل وجود دارد.')
                
            return redirect('music_table_entry', cafe_slug=cafe_slug) # یا ریدایرکت به داشبورد
            
        # ریدایرکت به همان صفحه داشبورد (نام ویوی داشبورد خود را جایگزین کنید، مثلا 'music_dashboard')
        return redirect('music_table_entry', cafe_slug=cafe_slug)




# views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.views.decorators.http import require_POST
# ... سایر import های شما

# ... سایر ویوهای شما ...

@login_required
@require_POST # این دکوریتور تضمین می‌کند که این ویو فقط با متد POST فراخوانی شود
def delete_table(request, cafe_slug, table_number):

    # پیدا کردن کافه
    cafe = get_object_or_404(CoffeShops, slug=cafe_slug)
    user = request.user
    if not request.user.is_superuser:    
        if user.role not in CustomUser.ROLE_MANAGER:
            return redirect("no_permission"  , cafe)  # یا 403
    
    # پیدا کردن و حذف تمام آهنگ‌های مربوط به این میز
    tracks_to_delete = TableMusic.objects.filter(cofe_owner=cafe, table_number=table_number)
    
    if tracks_to_delete.exists():
        tracks_to_delete.delete()
        messages.success(request, f'میز شماره {table_number} و تمام آهنگ‌های آن با موفقیت حذف شدند.')
    else:
        messages.warning(request, f'میزی با شماره {table_number} برای حذف وجود نداشت.')
        
    # ریدایرکت به داشبورد اصلی
    return redirect('music_table_entry', cafe_slug=cafe.slug) # نام URL داشبورد خود را جایگزین کنید


from django.http import FileResponse
from django.shortcuts import get_object_or_404
# در صورت نیاز مدل Food را ایمپورت کنید

import os
import requests
from django.http import StreamingHttpResponse
from django.shortcuts import get_object_or_404
# در صورت نیاز مدل TableMusic را ایمپورت کنید

def force_download_audio(request, cafe_slug, track_id):
    # پیدا کردن آهنگ بر اساس ID
    track = get_object_or_404(TableMusic, cofe_owner__slug=cafe_slug, id=track_id)
    
    # گرفتن لینک مستقیم فایل از FTP
    file_url = track.audio_file.url
    
    # استخراج نام فایل
    filename = os.path.basename(track.audio_file.name)
    
    # دریافت فایل از سرور FTP به صورت تکه‌تکه (Stream)
    r = requests.get(file_url, stream=True)
    
    # ساختن پاسخ استریم برای کاربر
    response = StreamingHttpResponse(
        r.iter_content(chunk_size=8192), 
        content_type=r.headers.get('content-type', 'audio/mpeg')
    )
    
    # تنظیم هدرها برای دانلود اجباری
    response['Content-Disposition'] = f'attachment; filename="{filename}"'
    
    # (اختیاری) تنظیم حجم فایل برای اینکه مرورگر بتواند درصد دانلود را نشان دهد
    if 'content-length' in r.headers:
        response['Content-Length'] = r.headers['content-length']
        
    return response



# In cafe/views.py

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json

@csrf_exempt
def send_welcome_sms_view(request, cafe_slug):
    if request.method == 'POST':
        try:
            cafe_obj = CoffeShops.objects.get(slug=cafe_slug)
            settings = SMS_Template.objects.filter(cofe_owner=cafe_obj).first()
            print('1')
            if settings is None:
                settings = SMS_Template.objects.create(cofe_owner=cafe_obj)
            print(2)
            cafe_api_key = settings.sms_api_key if settings else None
            cafe_line_number = settings.sms_line_number if settings else None


            data = json.loads(request.body)
            phone_number = data.get('phone_number')

            print(phone_number)
            
            if not phone_number or phone_number == '00000000000':
                return JsonResponse({'status': 'ignored'})

            cafe = CoffeShops.objects.get(slug=cafe_slug)
            settings = Core_Settings.objects.get(cofe_owner=cafe)

            # ۱. بررسی فعال بودن تنظیمات پیام خوش‌آمدگویی
            if not getattr(settings, 'send_welcome_sms', False):
                return JsonResponse({'status': 'ignored', 'msg': 'disabled'})

            # ۲. بررسی اینکه قبلا پیام به این شماره داده نشده باشد
            if WelcomeSMSSentLog.objects.filter(cafe=cafe, phone_number=phone_number).exists():
                return JsonResponse({'status': 'ignored', 'msg': 'already sent'})

            print('resid inja')
            # ۳. ارسال پیام
            user = CustomUser.objects.filter(phone=phone_number).first()
            user_name = user.first_name if (user and user.first_name) else "مشتری عزیز"
            
            # جایگذاری متغیرها در متن پیام
            template = getattr(settings, 'welcome_sms_template', 'به کافه ما خوش آمدید')
            message = template.replace('[name]', user_name).replace('[cafe_name]', cafe.name)
            
            # TODO: تابع ارسال پیامک خودتان را اینجا صدا بزنید
            send_bulk_sms(cafe_api_key , cafe_line_number , [phone_number] ,message )
            print('resid ta inajjjjjjjaaaaaaaaaaa')
            # ۴. ثبت در لاگ برای جلوگیری از ارسال مجدد  
            WelcomeSMSSentLog.objects.create(cafe=cafe, phone_number=phone_number)

            return JsonResponse({'status': 'success'})
        except Exception as e:
            return JsonResponse({'status': 'error', 'msg': str(e)}, status=400)
