import json
from django.shortcuts import render, get_object_or_404, redirect
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from financial.models import Contract, ChargeNumber
from .models import Item

def is_developer(user):
    return user.is_active and (user.is_superuser or user.groups.filter(name__iexact='developer').exists())

def developer_required(view_func):
    def _wrapped_view(request, *args, **kwargs):
        if is_developer(request.user):
            return view_func(request, *args, **kwargs)
        raise PermissionDenied
    return _wrapped_view

@login_required
def board_view(request):
    items = Item.objects.select_related('charge_number', 'charge_number__contract').all()
    todo_items = items.filter(status=Item.Status.TODO)
    in_progress_items = items.filter(status=Item.Status.IN_PROGRESS)
    done_items = items.filter(status=Item.Status.DONE)
    
    context = {
        'todo_items': todo_items,
        'in_progress_items': in_progress_items,
        'done_items': done_items,
        'statuses': Item.Status.choices,
        'qbd_charge_numbers': ChargeNumber.objects.filter(charge_number_type='QBD'),
        'is_developer': is_developer(request.user),
    }
    return render(request, 'planning/board.html', context)

@login_required
def backlog_view(request):
    items = Item.objects.select_related('charge_number', 'charge_number__contract').all().order_by('-created_at')
    
    status_filter = request.GET.get('status')
    if status_filter and status_filter in dict(Item.Status.choices):
        items = items.filter(status=status_filter)
        
    context = {
        'items': items,
        'statuses': Item.Status.choices,
        'qbd_charge_numbers': ChargeNumber.objects.filter(charge_number_type='QBD'),
        'is_developer': is_developer(request.user),
    }
    return render(request, 'planning/backlog.html', context)

@login_required
@developer_required
@require_POST
def create_item(request):
    title = request.POST.get('title')
    description = request.POST.get('description', '')
    charge_number_id = request.POST.get('charge_number')
    next_url = request.POST.get('next', 'planning:board_view')
    if title:
        max_order = Item.objects.filter(status=Item.Status.TODO).count()
        item = Item.objects.create(title=title, description=description, status=Item.Status.TODO, order=max_order)
        if charge_number_id:
            item.charge_number_id = charge_number_id
            item.save()
    return redirect(next_url)

@login_required
def item_detail(request, pk):
    item = get_object_or_404(Item.objects.select_related('charge_number', 'charge_number__contract'), pk=pk)
    context = {
        'item': item,
        'statuses': Item.Status.choices,
        'qbd_charge_numbers': ChargeNumber.objects.filter(charge_number_type='QBD'),
        'is_developer': is_developer(request.user),
    }
    return render(request, 'planning/partials/item_detail.html', context)

@login_required
@developer_required
@require_POST
def edit_item(request, pk):
    item = get_object_or_404(Item, pk=pk)
    item.title = request.POST.get('title', item.title)
    item.description = request.POST.get('description', item.description)
    item.status = request.POST.get('status', item.status)
    charge_number_id = request.POST.get('charge_number')
    if charge_number_id:
        item.charge_number_id = charge_number_id
    else:
        item.charge_number = None
    item.save()
    next_url = request.POST.get('next', 'planning:board_view')
    return redirect(next_url)

@login_required
@developer_required
@require_POST
def delete_item(request, pk):
    item = get_object_or_404(Item, pk=pk)
    item.delete()
    next_url = request.POST.get('next', 'planning:board_view')
    return redirect(next_url)

@login_required
@developer_required
@require_POST
def update_item_status(request, pk):
    try:
        data = json.loads(request.body)
        new_status = data.get('status')
        new_order = data.get('order')
        
        item = get_object_or_404(Item, pk=pk)
        
        if new_status and new_status in dict(Item.Status.choices):
            item.status = new_status
            if new_order is not None:
                item.order = new_order
            item.save()
            return JsonResponse({'status': 'success'})
        return JsonResponse({'status': 'error', 'message': 'Invalid status'}, status=400)
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
