import datetime
import json
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Count, Q
from django.views.decorators.http import require_POST
from django.http import JsonResponse
from .models import Category, WardrobeItem, Accessory, Outfit, OutfitFolder, CalendarAssignment
from .forms import WardrobeItemForm, AccessoryForm, OutfitForm

def home(request):
    """Dashboard view with current week calendar and total items count."""
    season_filter = request.GET.get('season', 'summer')
    
    total_wardrobe = WardrobeItem.objects.count()
    total_accessories = Accessory.objects.count()
    total_items = total_wardrobe + total_accessories

    today = datetime.date.today()
    start_of_week = today - datetime.timedelta(days=today.weekday())
    week_dates = [start_of_week + datetime.timedelta(days=i) for i in range(7)]
    
    day_names = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    
    calendar_data = []
    assignments = {a.date: a.outfit for a in CalendarAssignment.objects.filter(date__in=week_dates)}
    
    for i, date in enumerate(week_dates):
        calendar_data.append({
            'day': day_names[i],
            'date': date,
            'outfit': assignments.get(date)
        })

    # All outfits for the "quick add" modal on home screen
    all_outfits = Outfit.objects.all().order_by('-date_created')

    context = {
        'total_items': total_items,
        'calendar_data': calendar_data,
        'today': today,
        'season_filter': season_filter,
        'all_outfits': all_outfits,
        'week_dates_json': json.dumps([d.strftime('%Y-%m-%d') for d in week_dates]),
        'day_names': day_names,
    }
    return render(request, 'core/index.html', context)

@require_POST
def remove_assignment(request, date):
    CalendarAssignment.objects.filter(date=date).delete()
    return redirect('home')

@require_POST
def assign_outfit(request):
    outfit_id = request.POST.get('outfit_id')
    date_str = request.POST.get('date')
    if outfit_id and date_str:
        outfit = get_object_or_404(Outfit, id=outfit_id)
        try:
            date_obj = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
            CalendarAssignment.objects.update_or_create(
                date=date_obj,
                defaults={'outfit': outfit}
            )
        except ValueError:
            pass
    return redirect(request.META.get('HTTP_REFERER', 'home'))

def wardrobe_list(request):
    query = request.GET.get('q')
    main_category_id = request.GET.get('main_category')
    subcategory_id = request.GET.get('subcategory')
    
    main_categories = Category.objects.filter(item_type='wardrobe', parent=None).annotate(
        num_items=Count('wardrobe_items', distinct=True),
        num_child_items=Count('children__wardrobe_items', distinct=True)
    ).filter(Q(is_preset=True) | Q(num_items__gt=0) | Q(num_child_items__gt=0))
    
    subcategories = None
    current_main = None
    current_sub = None
    
    items = WardrobeItem.objects.all().order_by('-date_added')
    
    if main_category_id:
        current_main = get_object_or_404(Category, id=main_category_id, parent=None)
        subcategories = Category.objects.filter(parent=current_main).annotate(
            num_items=Count('wardrobe_items', distinct=True)
        ).filter(Q(is_preset=True) | Q(num_items__gt=0))
        
        items = items.filter(Q(category=current_main) | Q(category__parent=current_main))
        
        if subcategory_id:
            current_sub = get_object_or_404(Category, id=subcategory_id, parent=current_main)
            items = items.filter(category=current_sub)
    
    if query:
        items = items.filter(Q(name__icontains=query) | Q(category__name__icontains=query))
    
    context = {
        'main_categories': main_categories,
        'subcategories': subcategories,
        'current_main': current_main,
        'current_sub': current_sub,
        'items': items,
        'title': 'Wardrobe'
    }
    return render(request, 'core/wardrobe_list.html', context)

def add_wardrobe_item(request):
    if request.method == 'POST':
        form = WardrobeItemForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('wardrobe_list')
    else:
        form = WardrobeItemForm()
        
    return render(request, 'core/item_form.html', {'form': form, 'title': 'Add Wardrobe Item', 'type': 'wardrobe'})

def accessory_list(request):
    query = request.GET.get('q')
    main_category_id = request.GET.get('main_category')
    subcategory_id = request.GET.get('subcategory')
    
    main_categories = Category.objects.filter(item_type='accessory', parent=None).annotate(
        num_items=Count('accessories', distinct=True),
        num_child_items=Count('children__accessories', distinct=True)
    ).filter(Q(is_preset=True) | Q(num_items__gt=0) | Q(num_child_items__gt=0))
    
    subcategories = None
    current_main = None
    current_sub = None
    
    items = Accessory.objects.all().order_by('-date_added')
    
    if main_category_id:
        current_main = get_object_or_404(Category, id=main_category_id, parent=None)
        subcategories = Category.objects.filter(parent=current_main).annotate(
            num_items=Count('accessories', distinct=True)
        ).filter(Q(is_preset=True) | Q(num_items__gt=0))
        
        items = items.filter(Q(category=current_main) | Q(category__parent=current_main))
        
        if subcategory_id:
            current_sub = get_object_or_404(Category, id=subcategory_id, parent=current_main)
            items = items.filter(category=current_sub)
    
    if query:
        items = items.filter(Q(name__icontains=query) | Q(category__name__icontains=query))
    
    context = {
        'main_categories': main_categories,
        'subcategories': subcategories,
        'current_main': current_main,
        'current_sub': current_sub,
        'items': items,
        'title': 'Accessories'
    }
    return render(request, 'core/accessory_list.html', context)

def add_accessory_item(request):
    if request.method == 'POST':
        form = AccessoryForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('accessory_list')
    else:
        form = AccessoryForm()
        
    return render(request, 'core/item_form.html', {'form': form, 'title': 'Add Accessory', 'type': 'accessory'})

def outfit_list(request):
    query = request.GET.get('q')
    folder_id = request.GET.get('folder')
    
    def get_valid_folders(parent=None):
        return OutfitFolder.objects.filter(parent=parent).annotate(
            num_outfits=Count('outfits', distinct=True),
            num_child_outfits=Count('children__outfits', distinct=True)
        ).filter(Q(is_preset=True) | Q(num_outfits__gt=0) | Q(num_child_outfits__gt=0))

    folders = get_valid_folders(None)
    outfits = Outfit.objects.all().order_by('-date_created')

    if folder_id:
        current_folder = get_object_or_404(OutfitFolder, id=folder_id)
        folders = get_valid_folders(current_folder)
        if not folders.exists():
            folders = get_valid_folders(current_folder.parent)
        outfits = outfits.filter(Q(folder=current_folder) | Q(folder__parent=current_folder))
    else:
        current_folder = None

    if query:
        outfits = outfits.filter(Q(name__icontains=query))
    
    # For weekday assignment in the list view
    today = datetime.date.today()
    start_of_week = today - datetime.timedelta(days=today.weekday())
    week_dates = [start_of_week + datetime.timedelta(days=i) for i in range(7)]
    day_names = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    week_data = [{'day': day_names[i], 'date': week_dates[i].strftime('%Y-%m-%d')} for i in range(7)]

    context = {
        'outfits': outfits,
        'folders': folders,
        'current_folder': current_folder,
        'title': 'Outfits',
        'week_data': week_data,
    }
    return render(request, 'core/outfit_list.html', context)

def new_fit(request):
    date_str = request.GET.get('date')
    if request.method == 'POST':
        form = OutfitForm(request.POST)
        if form.is_valid():
            outfit = form.save()
            if date_str:
                try:
                    date_obj = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
                    CalendarAssignment.objects.update_or_create(
                        date=date_obj,
                        defaults={'outfit': outfit}
                    )
                    return redirect('home')
                except ValueError:
                    pass
            return redirect('outfit_list')
    else:
        form = OutfitForm()
        
    wardrobe_items = WardrobeItem.objects.all()
    accessories = Accessory.objects.all()
    
    return render(request, 'core/new_fit.html', {
        'form': form, 
        'title': f'New Fit for {date_str}' if date_str else 'New Fit',
        'wardrobe_items': wardrobe_items,
        'accessories': accessories,
        'date_str': date_str
    })

def get_subcategories(request):
    parent_id = request.GET.get('parent_id')
    if parent_id:
        subcategories = Category.objects.filter(parent_id=parent_id).values('id', 'name')
        return JsonResponse(list(subcategories), safe=False)
    return JsonResponse([], safe=False)

def wardrobe_item_detail(request, pk):
    item = get_object_or_404(WardrobeItem, pk=pk)
    return render(request, 'core/item_detail.html', {'item': item, 'type': 'wardrobe'})

def accessory_item_detail(request, pk):
    item = get_object_or_404(Accessory, pk=pk)
    return render(request, 'core/item_detail.html', {'item': item, 'type': 'accessory'})

def cleanup_category(category):
    if category and not category.is_preset:
        if not category.wardrobe_items.exists() and not category.accessories.exists() and not category.children.exists():
            parent = category.parent
            category.delete()
            if parent:
                cleanup_category(parent)

def cleanup_folder(folder):
    if folder and not folder.is_preset:
        if not folder.outfits.exists() and not folder.children.exists():
            parent = folder.parent
            folder.delete()
            if parent:
                cleanup_folder(parent)

@require_POST
def delete_wardrobe_item(request, pk):
    item = get_object_or_404(WardrobeItem, pk=pk)
    category = item.category
    item.delete()
    cleanup_category(category)
    return redirect('wardrobe_list')

@require_POST
def delete_accessory_item(request, pk):
    item = get_object_or_404(Accessory, pk=pk)
    category = item.category
    item.delete()
    cleanup_category(category)
    return redirect('accessory_list')

@require_POST
def delete_outfit(request, pk):
    outfit = get_object_or_404(Outfit, pk=pk)
    folder = outfit.folder
    outfit.delete()
    cleanup_folder(folder)
    return redirect('outfit_list')