""" Admin views """
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import permission_required

from accounts.utils import get_subscriptions

from catalog.models import Item, Book, Map, Movie, Person, Subscription, ZipCode
from store_order.models import Order, OrderItem
from catalog.forms import (
    MovieForm,
    MapForm,
    PersonForm,
    BookForm,
    SubscriptionForm,
    PostalCodeForm,
)


@staff_member_required
@permission_required("pbp_core.store_admin_login")
def store_admin_home(request):
    """ Store Admin Home page """
    # TODO: security, etc
    return render_to_response(
        "pbp_store/store_admin/home.html", context_instance=RequestContext(request)
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_subscription(
    request, sku=None, template="pbp_store/store_admin/add_edit.html"
):
    """ Add catalogs form """
    return add_edit(
        request,
        Subscription,
        SubscriptionForm,
        "Subscription",
        sku=sku,
        template=template,
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_book(request, sku=None, template="pbp_store/store_admin/add_edit.html"):
    """ Add / edit book """
    return add_edit(request, Book, BookForm, "Book", sku=sku, template=template)


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_map(request, sku=None, template="pbp_store/store_admin/add_edit.html"):
    """ Add / edit map """
    return add_edit(request, Map, MapForm, "Map", sku=sku, template=template)


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_movie(request, sku=None, template="pbp_store/store_admin/add_edit.html"):
    """ Add / edit movie """
    return add_edit(request, Movie, MovieForm, "Movie", sku=sku, template=template)


def add_edit(request, model, modelform, title, sku=None, template=None):
    """ Add edit item """
    item = None
    edit_mode = False
    if sku:
        item = get_object_or_404(model, sku=sku)
        edit_mode = True

    form = modelform(request.POST or None, request.FILES or None, instance=item)
    if form.is_valid():
        item = form.save(commit=False)
        if not edit_mode:
            item.created_by = request.user
        item.last_updated_by = request.user
        item.save()
        if item.is_book:
            form.save_m2m()
        return HttpResponseRedirect(reverse("catalog_list"))

    cancel_url = reverse("catalog_list")

    return render_to_response(
        template,
        {
            "form": form,
            "edit_mode": edit_mode,
            "item_type": title,
            "cancel_url": cancel_url,
        },
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def delete_item(request, sku, template="pbp_store/store_admin/delete_confirm.html"):
    """ Add movie """
    item = get_object_or_404(Item, sku=sku)
    if request.method == "POST":
        item.deleted = True
        item.last_updated_by = request.user
        item.save()
        return HttpResponseRedirect(reverse("catalog_list"))

    return render_to_response(
        template, {"item": item}, context_instance=RequestContext(request)
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_view")
def list_catalog(
    request, category="all", template="pbp_store/store_admin/catalog_list.html"
):
    """ Simple list of all the catalogs """

    config = {
        "movie": Movie,
        "book": Book,
        "map": Map,
        "subscription": Subscription,
        "all": Item,
    }

    model = config.get(category, Item)
    # sort by title or price, asc or desc default to title asc
    catalog = model.objects.active()

    return render_to_response(
        template,
        {"catalog": catalog, "category": category},
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_admin_orders")
def list_orders(request, template="pbp_store/store_admin/order_list.html"):
    """ Simple list of all the orders """

    config = {
        "init": Order.INIT,
        "submitted": Order.SUBMITTED,
        "processed": Order.PROCESSED,
        "shipped": Order.SHIPPED,
        "cancelled": Order.CANCELLED,
    }

    status = request.GET.get("status", "processed")
    if status == "all":
        orders = Order.objects.all()
    else:
        status_filter = config.get(status)
        orders = Order.objects.filter(status=status_filter)

    return render_to_response(
        template,
        {"orders": orders, "status": status},
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_admin_orders")
def view_order_detail(
    request, order_number, template="pbp_store/store_admin/order.html"
):
    """ View order details """
    order = get_object_or_404(Order, pk=order_number)

    return render_to_response(
        template, {"order": order}, context_instance=RequestContext(request)
    )


@staff_member_required
@permission_required("pbp_core.store_admin_orders")
def list_subscriptions(
    request, template="pbp_store/store_admin/subscription_list.html"
):
    """ Simple list of all the orders """

    config = {
        "init": Order.INIT,
        "submitted": Order.SUBMITTED,
        "processed": Order.PROCESSED,
        "shipped": Order.SHIPPED,
        "cancelled": Order.CANCELLED,
    }

    status = request.GET.get("status", "processed")
    if status == "all":
        order_items = OrderItem.objects.filter(
            product__subclass_type__iexact=Subscription.__name__.lower()
        )
    else:
        status_filter = config.get(status)
        order_items = OrderItem.objects.filter(
            product__subclass_type__iexact=Subscription.__name__.lower()
        ).filter(order__status=status_filter)

    return render_to_response(
        template,
        {"order_items": order_items, "status": status},
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_admin_orders")
def subscription_detail(
    request,
    order_number,
    order_item=None,
    template="pbp_store/store_admin/subscription_detail.html",
):
    """ Simple list of all the orders """

    order = get_object_or_404(Order, pk=order_number)

    if order_number:
        order_items = get_subscriptions(order=order)

    return render_to_response(
        template,
        {"order_items": order_items, "order": order},
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_view")
def list_postal_codes(request, template="pbp_store/store_admin/postal_code_list.html"):
    """ list the postal codes """

    postal_codes = ZipCode.objects.active()

    return render_to_response(
        template,
        {"postal_codes": postal_codes},
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_postal_code(
    request, postal_code=None, template="pbp_store/store_admin/add_edit.html"
):
    """ Add edit postal_code """
    item = None
    edit_mode = False
    if postal_code:
        item = get_object_or_404(ZipCode, zipcode=postal_code)
        edit_mode = True

    form = PostalCodeForm(request.POST or None, instance=item)
    if form.is_valid():
        item = form.save(commit=False)
        if not edit_mode:
            item.created_by = request.user
        item.last_updated_by = request.user
        item.save()
        return HttpResponseRedirect(reverse("postal_code_list"))

    cancel_url = reverse("postal_code_list")

    return render_to_response(
        template,
        {
            "form": form,
            "edit_mode": edit_mode,
            "item_type": "Postal Code",
            "cancel_url": cancel_url,
        },
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def delete_postal_code(
    request, postal_code, template="pbp_store/store_admin/delete_confirm.html"
):
    """ Add movie """
    item = get_object_or_404(ZipCode, zipcode=postal_code)
    if request.method == "POST":
        item.deleted = True
        item.last_updated_by = request.user
        item.save()
        return HttpResponseRedirect(reverse("postal_code_list"))

    return render_to_response(
        template, {"item": item}, context_instance=RequestContext(request)
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_view")
def list_persons(request, template="pbp_store/store_admin/person_list.html"):
    """ list the postal codes """

    persons = Person.objects.active()

    return render_to_response(
        template, {"persons": persons}, context_instance=RequestContext(request)
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def add_edit_person(
    request, person_slug=None, template="pbp_store/store_admin/add_edit.html"
):
    """ Add edit Author """
    item = None
    edit_mode = False
    if person_slug:
        item = get_object_or_404(Person, slug=person_slug)
        edit_mode = True

    form = PersonForm(request.POST or None, request.FILES or None, instance=item)
    if form.is_valid():
        item = form.save(commit=False)
        if not edit_mode:
            item.created_by = request.user
        item.last_updated_by = request.user
        item.save()
        return HttpResponseRedirect(reverse("person_list"))

    cancel_url = reverse("person_list")

    return render_to_response(
        template,
        {
            "form": form,
            "edit_mode": edit_mode,
            "item_type": "Person",
            "cancel_url": cancel_url,
        },
        context_instance=RequestContext(request),
    )


@staff_member_required
@permission_required("pbp_core.store_catalog_edit")
def delete_person(
    request, person_slug, template="pbp_store/store_admin/delete_confirm.html"
):
    """ Add movie """
    item = get_object_or_404(Person, slug=person_slug)
    if request.method == "POST":
        item.deleted = True
        item.last_updated_by = request.user
        item.save()
        return HttpResponseRedirect(reverse("person_list"))

    return render_to_response(
        template, {"item": item}, context_instance=RequestContext(request)
    )
