from django.contrib.auth.views import LoginView
from django.views.generic import *
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
from archive.models import *
from django.db.models import Q
from django.urls import reverse_lazy
from django.urls import reverse
from django.http import JsonResponse
from persiantools.jdatetime import JalaliDate
from jalali_date import date2jalali
 
class CustomLoginView(LoginView):
    template_name = 'dashboard/login.html'
    
    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect('dashboard')   
        return super().dispatch(request, *args, **kwargs)

    

class DashboardTemplateView(LoginRequiredMixin, ListView):
    model = Ceremony
    template_name = 'dashboard/dashboard.html'
    context_object_name = 'ceremonies'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by

    def get_queryset(self):
        q = self.request.GET.get('q')
        filter_type = self.request.GET.get('filter')

        ceremonies = Ceremony.objects.select_related('category').order_by('-id')

        if q:
            if filter_type == 'category':
                ceremonies = ceremonies.filter(
                    Q(category__name__icontains=q) |
                    Q(category__parent__name__icontains=q)
                )
            else:
                ceremonies = ceremonies.filter(title__icontains=q)

        return ceremonies
    
    
    
    
    
from django import forms
class CeremonyForm(forms.ModelForm):
    date = forms.CharField(required=True)

    class Meta:
        model = Ceremony
        fields = '__all__'

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)

    #     choices = []
    #     for cat in CeremonyCategory.objects.all():
    #         parents = cat.get_parents()
    #         name = " → ".join([p.name for p in parents])
    #         choices.append((cat.id, name))

    #     self.fields['category'].choices = choices


    
 
class CeremonyCreateView(CreateView):
    model = Ceremony
    form_class = CeremonyForm
    template_name = 'dashboard/ceremony_form.html'

    def form_valid(self, form):
        # تبدیل تاریخ
        date_str = self.request.POST.get("date", "").strip()

        try:
            date_str = date_str.replace("-", "/")
            y, m, d = map(int, date_str.split("/"))
            form.instance.date = JalaliDate(y, m, d).to_gregorian()
        except:
            form.add_error("date", "تاریخ نامعتبر است")
            return self.form_invalid(form)

        response = super().form_valid(form)

        # گرفتن فایل‌ها
        ceremony = self.object

        file_types = self.request.POST.getlist('file_type[]')
        file_styles = self.request.POST.getlist('file_style[]')
        file_titles = self.request.POST.getlist('file_title[]')
        is_pins = self.request.POST.getlist('is_pin[]')
        file_paths = self.request.POST.getlist('file_path[]')
        cover_paths = self.request.POST.getlist('cover_path[]')
        cover_desktop_paths = self.request.POST.getlist('cover_desktop_path[]')
        file_tags = self.request.POST.getlist('tags[]')
        
        thumbnails = self.request.POST.getlist('thumbnail[]')
        file_occasions = self.request.POST.getlist('file_occasion[]')
        
        

        for i in range(len(file_types)):
            if file_paths[i]:

                is_pin = is_pins[i] == 'True' if i < len(is_pins) else False

                obj = CeremonyFile.objects.create(
                    ceremony=ceremony,
                    file_type=file_types[i],
                    file_style=file_styles[i],
                    title=file_titles[i],
                    is_pin = is_pin,
                    file=file_paths[i],
                    poster = cover_paths[i],
                    poster_desktop = cover_desktop_paths[i],
                    thumbnail=thumbnails[i] if i < len(thumbnails) else None,  # 👈 thumbnail
                    occasion_id=file_occasions[i] or None,
                    

                )
         
            if file_tags:
                 obj.tags.set(file_tags)
        
        return response

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["occasions"] = Occasion.objects.all()
        return context
    def get_success_url(self):
        return reverse('dashboard')



class CeremonyUpdateView(UpdateView):
    model = Ceremony
    form_class = CeremonyForm
    template_name = 'dashboard/ceremony_update.html'

    def form_valid(self, form):
        date_str = self.request.POST.get("date", "").strip()

        try:
            date_str = date_str.replace("-", "/")
            y, m, d = map(int, date_str.split("/"))
            form.instance.date = JalaliDate(y, m, d).to_gregorian()
        except:
            form.add_error("date", "تاریخ نامعتبر است")
            return self.form_invalid(form)

        response = super().form_valid(form)

        ceremony = self.object

        # =========================
        # FILES
        # =========================

        file_ids = self.request.POST.getlist('file_id[]')

        file_types = self.request.POST.getlist('file_type[]')
        file_styles = self.request.POST.getlist('file_style[]')

        file_titles = self.request.POST.getlist('file_title[]')
        is_pins = self.request.POST.getlist('is_pin[]')

        file_paths = self.request.POST.getlist('file_path[]')
        cover_paths = self.request.POST.getlist('cover_path[]')
        cover_desktop_paths = self.request.POST.getlist('cover_desktop_path[]')
        thumbnails = self.request.POST.getlist('thumbnail[]')
        file_occasions = self.request.POST.getlist('file_occasion[]')
        
 
        row_ids = self.request.POST.getlist('row_id[]')
        used_ids = []

        for i in range(len(file_types)):
            row_id = row_ids[i]

            tags = self.request.POST.getlist(
                f'tags_{row_id}[]'
            )

            file_id = file_ids[i].strip()

            file_type = file_types[i]
            file_style = file_styles[i]
            file_title = file_titles[i]
            file_path = file_paths[i]
            cover_path = cover_paths[i]
            cover_desktop_path = cover_desktop_paths[i]
          
            # پیش‌فرض: مقدار قبلی
            is_pin = is_pins[i] == 'True' if i < len(is_pins) else None                        

            if not file_path:
                continue

            # =========================
            # UPDATE OLD FILE
            # =========================
            if file_id:

                try:
                    obj = CeremonyFile.objects.get(
                        id=file_id,
                        ceremony=ceremony
                    )

                    obj.file_type = file_type
                    obj.file_style = file_style
                    obj.title = file_title
                    obj.file = file_path
                    obj.poster = cover_path
                    obj.poster_desktop = cover_desktop_path
                    obj.occasion_id=file_occasions[i] or None
                    
                    obj.thumbnail = thumbnails[i] if i < len(thumbnails) else obj.thumbnail
                    
                    if i < len(is_pins):
                              obj.is_pin = (is_pins[i] == 'True')

                    
                    

                    obj.save()
                    
                    obj.tags.set(tags)

                
                    used_ids.append(obj.id)

                except CeremonyFile.DoesNotExist:
                    pass

            # =========================
            # CREATE NEW FILE
            # =========================
            else:

                obj = CeremonyFile.objects.create(
                    ceremony=ceremony,
                    file_type=file_type,
                    file_style=file_style,
                    title=file_title,
                    is_pin = (is_pins[i] == 'True') if i < len(is_pins) else False,
                    file=file_path,
                    poster = cover_path,
                    poster_desktop=cover_desktop_path,
                    thumbnail=thumbnails[i] if i < len(thumbnails) else None,
                    occasion_id=file_occasions[i] or None
                )
                obj.tags.set(tags)


                used_ids.append(obj.id)

        # =========================
        # DELETE REMOVED FILES
        # =========================
        removed_files = CeremonyFile.objects.filter(
            ceremony=ceremony
        ).exclude(
            id__in=used_ids
        )

        for obj in removed_files:
            obj.delete()
        return response

    def get_success_url(self):
        return reverse('dashboard')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # اگر خواستی بعداً در JS فایل‌های قبلی رو نمایش بدی
        context['files'] = CeremonyFile.objects.filter(ceremony=self.object)
        context["occasions"] = Occasion.objects.all()
        context["all_tags"] = Tag.objects.all()
        if self.object.date:
            context["jalali_date"] = date2jalali(self.object.date).strftime("%Y-%m-%d")
 
        return context



     

def build_tree(parent=None):
    nodes = []
    categories = CeremonyCategory.objects.filter(parent=parent)

    for cat in categories:
        children = build_tree(cat)

        nodes.append({
            "id": cat.id,
            "text": cat.name,
            "children": children,
            "disabled": len(children) > 0  # اگر بچه داشت = غیرقابل انتخاب
        })

    return nodes


def category_tree_json(request):
    data = build_tree()
    return JsonResponse(data, safe=False)



 
class CeremonyDeleteView(DeleteView):
    model = Ceremony
    success_url = reverse_lazy('dashboard')
    
    
    
from archive.models import CeremonyCategory
from django.views.generic import ListView
from django.db.models import Q

class DashboardCategorys(ListView):
    model = CeremonyCategory
    template_name = 'dashboard/category_dashboard.html'
    context_object_name = 'categorys'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by


    def get_queryset(self):
        q = self.request.GET.get('q')

        if not q:
            return CeremonyCategory.objects.all()

        # 1. دسته‌هایی که match شدند
        matched = CeremonyCategory.objects.filter(name__icontains=q)

        # 2. جمع کردن والدها
        all_categories = set()

        for cat in matched:
            current = cat
            while current:
                all_categories.add(current)
                current = current.parent

        return CeremonyCategory.objects.filter(id__in=[c.id for c in all_categories])
    
    


    
from django.views.generic import CreateView, UpdateView
from django.urls import reverse_lazy
from archive.models import CeremonyCategory


class CategoryCreateView(CreateView):
    model = CeremonyCategory
    fields = ['name', 'parent']
    template_name = 'dashboard/category_form.html'

    def get_success_url(self):
        return reverse_lazy('category_dashboard')


class CategoryUpdateView(UpdateView):
    model = CeremonyCategory
    fields = ['name', 'parent']
    template_name = 'dashboard/category_form.html'

    def get_success_url(self):
        return reverse_lazy('category_dashboard')
    
    
class CeremonyCategoryDeleteView(DeleteView):
    model = CeremonyCategory
    success_url = reverse_lazy('category_dashboard')
    
    
class DashboardOccasions(ListView):
    model = Occasion
    template_name = 'dashboard/occasion_dashboard.html'
    context_object_name = 'occasions'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by


    def get_queryset(self):

        q = self.request.GET.get('q')

        queryset = Occasion.objects.all()

        if q:
            queryset = queryset.filter(
                title__icontains=q
            )

        return queryset
    
    
    
class OccasionsCreateView(CreateView):
    model = Occasion
    fields = ['title' ,'is_active_video','is_active_audio']
    template_name = 'dashboard/occasion_form.html'

    def get_success_url(self):
        return reverse_lazy('occasion_dashboard')


class OccasionsUpdateView(UpdateView):
    model = Occasion
    fields = ['title' ,'is_active_video','is_active_audio']
    template_name = 'dashboard/occasion_form.html'

    def get_success_url(self):
        return reverse_lazy('occasion_dashboard')
    
    
class OccasionsDeleteView(DeleteView):
    model = Occasion
    success_url = reverse_lazy('occasion_dashboard')



class DashboardRingbackTones(ListView):
    model = RingbackTone
    template_name = 'dashboard/ring_back_tone_dashboard.html'
    context_object_name = 'ring_back_tones'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by


    def get_queryset(self):

        q = self.request.GET.get('q')

        queryset = RingbackTone.objects.all()

        if q:
            queryset = queryset.filter(
                title__icontains=q
            )

        return queryset
    
    
    
class RingbackTonesCreateView(CreateView):
    model = RingbackTone
    fields = ['title' ,'code_mtn','code_mci','occasion','cover','audio_file']
    template_name = 'dashboard/ring_back_tone_form.html'

    def get_success_url(self):
        return reverse_lazy('ring_back_tone_dashboard')


class RingbackTonesUpdateView(UpdateView):
    model = RingbackTone
    fields = ['title' ,'code_mtn','code_mci','occasion','cover','audio_file']
    template_name = 'dashboard/ring_back_tone_form.html'

    def get_success_url(self):
        return reverse_lazy('ring_back_tone_dashboard')
    
    
class RingbackTonesDeleteView(DeleteView):
    model = RingbackTone
    success_url = reverse_lazy('ring_back_tone_dashboard')



class DashboardTags(ListView):
    model = Tag
    template_name = 'dashboard/tag_dashboard.html'
    context_object_name = 'tags'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by


    def get_queryset(self):

        q = self.request.GET.get('q')

        queryset = Tag.objects.all()

        if q:
            queryset = queryset.filter(
                name__icontains=q
            )

        return queryset
    
class TagsCreateView(CreateView):
    model = Tag
    fields = ['name']
    template_name = 'dashboard/tag_form.html'

    def get_success_url(self):
        return reverse_lazy('tag_dashboard')


class TagsUpdateView(UpdateView):
    model = Tag
    fields = ['name']
    template_name = 'dashboard/tag_form.html'

    def get_success_url(self):
        return reverse_lazy('tag_dashboard')
    
class TagsDeleteView(DeleteView):
    model = Tag
    success_url = reverse_lazy('tag_dashboard')



from website.models import ContactData
class DashboardContacts(ListView):
    model = ContactData
    template_name = 'dashboard/contact_dashboard.html'
    context_object_name = 'contacts'
    paginate_by = 8

    def get_paginate_by(self, queryset):
        try:
            return int(self.request.GET.get('page_size', self.paginate_by))
        except (TypeError, ValueError):
            return self.paginate_by


    def get_queryset(self):

        q = self.request.GET.get('q')

        queryset = ContactData.objects.all()

        if q:
            queryset = queryset.filter(
                name__icontains=q
            )

        return queryset
    
    
class ContactsDeleteView(DeleteView):
    model = ContactData
    success_url = reverse_lazy('contact_dashboard')

