from tags.models import TaggedItem
from . import models
from django.contrib import admin,messages
# from django.contrib.contenttypes.admin import GenericTabularInline
from django.db.models import Count
from django.utils.html import format_html, urlencode
from django.urls import reverse


# creating custom class for filtering the low inventory items
class InventoryFilter(admin.SimpleListFilter):
    title = 'inventory'
    # this will appear in the query string
    parameter_name = 'inventory'

    # this tells which methods should appear in the filtering panel
    def lookups(self, request, model_admin):

        # first argument is the value, second is the title which will
        #  be displayed
        # you can pass multiple tuples here
        return [
            ('<10', 'Low')
        ]

    def queryset(self, request, queryset):
        # if the user selected this filter then return the filtered
        #  queryset
        if self.value() == '<10':
            return queryset.filter(inventory__lte=10)


# we can also register using this and add another column unit_price.
@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin):


    search_fields=['title']

    # set the collection field to autocomplete field
    # to enable the search functionality in it
    autocomplete_fields = ['collection']

    # slug field is automatically created using the title field 
    # you can add more fields here
    prepopulated_fields = {
        "slug": ["title"]
        }



    # pass the name of the csutom action we created
    actions = ['clear_inventory']

    # for displaying columns of product table you can also add
    # others tables    
    # columns by making custom method like here inventory_status
    #  columns of collection class is also added
    list_display = ['title', 'unit_price',
                    'inventory_status', 'collection_title']

    # for making columns editable
    list_editable = ['unit_price']

    # for making pagination
    list_perpage = 10

    # implementing the filter method for filtering by collection
    # and last_update
    list_filter = ['collection', 'last_update', InventoryFilter]

    # like the select_related() method in query set
    # to preload the collection table to stop extra queries to run
    list_select_related = ['collection']

    # for loading each column of a table indivudually
    def collection_title(self, product):
        return product.collection.title

    # ordering the field of product model
    @admin.display(ordering='inventory')
    # check each invetory row in the product table
    def inventory_status(self, product):
        if product.inventory < 10:
            return 'Low'
        return 'OK'

    # request repsresents the current http request
    # queryset represents the selected products/objects
    @admin.action(description='clear inventory')
    def clear_inventory(self, request, queryset):
        updated_count = queryset.update(inventory=0)

        # every model admin contains this method to show
        # message to user
        self.message_user(request, 
        f'{updated_count} products were succesfully updated',
        messages.ERROR)


class OrderItemInline(admin.TabularInline):

    autocomplete_fields = ['product']    
    # we should always specify 1 order
    min_num=1
    max_num=10
    model = models.OrderItem

    # no extra orders that are by default
    extra=0

@admin.register(models.Order)
class OrderAdmin(admin.ModelAdmin):

    # managing the items of the order 
    inlines=[OrderItemInline]


    list_display = ['id', 'placed_at', 'customer']

    autocomplete_fields = ['customer']


# Register your models here.
@admin.register(models.Collection)
class CollectionAdmin(admin.ModelAdmin):
    # for searching in the forms with collection title
    search_fields=['title']

    list_display = ['title', 'products_count']


    # but products_count field is not in the collection object
    @admin.display(ordering='products_count')
    def products_count(self, collection):

        # 'admin:app_model_page' is the url format
        # the pagename is changelist
        # reverse() create url for the product model and to get
        # the specific
        # collection id of it we are using the collection.id
        url = (
            reverse('admin:store_product_changelist')
            + '?'
            + urlencode({
                'collection__id': str(collection.id)
            }))

        # the collection.products_count output become a link which
        # redirects to url.
        return format_html('<a href="{}">{}</a>', url, collection.products_count)

    # so we need to add the query of products_count manually using
    #  the get_queryset() method
    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            products_count=Count('product')
        )


@admin.register(models.Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = ['first_name', 'last_name', 'membership']
    list_editable = ['membership']
    list_per_page = 10
    ordering = ['first_name', 'last_name']

    # search the first and last name and word is case insensitive
    search_fields = ['first_name__istartswith', 'last_name__istartswith']

from tags.models import TaggedItem
from . import models
from django.contrib import admin,messages
# from django.contrib.contenttypes.admin import GenericTabularInline
from django.db.models import Count
from django.utils.html import format_html, urlencode
from django.urls import reverse


# creating custom class for filtering the low inventory items
class InventoryFilter(admin.SimpleListFilter):
    title = 'inventory'
    # this will appear in the query string
    parameter_name = 'inventory'

    # this tells which methods should appear in the filtering panel
    def lookups(self, request, model_admin):

        # first argument is the value, second is the title which will
        #  be displayed
        # you can pass multiple tuples here
        return [
            ('<10', 'Low')
        ]

    def queryset(self, request, queryset):
        # if the user selected this filter then return the filtered
        #  queryset
        if self.value() == '<10':
            return queryset.filter(inventory__lte=10)


# we can also register using this and add another column unit_price.
@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin):


    search_fields=['title']

    # set the collection field to autocomplete field
    # to enable the search functionality in it
    autocomplete_fields = ['collection']

    # slug field is automatically created using the title field 
    # you can add more fields here
    prepopulated_fields = {
        "slug": ["title"]
        }



    # pass the name of the csutom action we created
    actions = ['clear_inventory']

    # for displaying columns of product table you can also add
    # others tables    
    # columns by making custom method like here inventory_status
    #  columns of collection class is also added
    list_display = ['title', 'unit_price',
                    'inventory_status', 'collection_title']

    # for making columns editable
    list_editable = ['unit_price']

    # for making pagination
    list_perpage = 10

    # implementing the filter method for filtering by collection
    # and last_update
    list_filter = ['collection', 'last_update', InventoryFilter]

    # like the select_related() method in query set
    # to preload the collection table to stop extra queries to run
    list_select_related = ['collection']

    # for loading each column of a table indivudually
    def collection_title(self, product):
        return product.collection.title

    # ordering the field of product model
    @admin.display(ordering='inventory')
    # check each invetory row in the product table
    def inventory_status(self, product):
        if product.inventory < 10:
            return 'Low'
        return 'OK'

    # request repsresents the current http request
    # queryset represents the selected products/objects
    @admin.action(description='clear inventory')
    def clear_inventory(self, request, queryset):
        updated_count = queryset.update(inventory=0)

        # every model admin contains this method to show
        # message to user
        self.message_user(request, 
        f'{updated_count} products were succesfully updated',
        messages.ERROR)


class OrderItemInline(admin.TabularInline):

    autocomplete_fields = ['product']    
    # we should always specify 1 order
    min_num=1
    max_num=10
    model = models.OrderItem

    # no extra orders that are by default
    extra=0

@admin.register(models.Order)
class OrderAdmin(admin.ModelAdmin):

    # managing the items of the order 
    inlines=[OrderItemInline]


    list_display = ['id', 'placed_at', 'customer']

    autocomplete_fields = ['customer']


# Register your models here.
@admin.register(models.Collection)
class CollectionAdmin(admin.ModelAdmin):
    # for searching in the forms with collection title
    search_fields=['title']

    list_display = ['title', 'products_count']


    # but products_count field is not in the collection object
    @admin.display(ordering='products_count')
    def products_count(self, collection):

        # 'admin:app_model_page' is the url format
        # the pagename is changelist
        # reverse() create url for the product model and to get
        # the specific
        # collection id of it we are using the collection.id
        url = (
            reverse('admin:store_product_changelist')
            + '?'
            + urlencode({
                'collection__id': str(collection.id)
            }))

        # the collection.products_count output become a link which
        # redirects to url.
        return format_html('<a href="{}">{}</a>', url, collection.products_count)

    # so we need to add the query of products_count manually using
    #  the get_queryset() method
    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            products_count=Count('product')
        )


@admin.register(models.Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = ['first_name', 'last_name', 'membership']
    list_editable = ['membership']
    list_per_page = 10
    ordering = ['first_name', 'last_name']

    # search the first and last name and word is case insensitive
    search_fields = ['first_name__istartswith', 'last_name__istartswith']

# from django.contrib.contenttypes.admin import GenericTabularInline # creating custom class for filtering the low inventory items # this will appear in the query string # this tells which methods should appear in the filtering panel # first argument is the value, second is the title which will #  be displayed # you can pass multiple tuples here # if the user selected this filter then return the filtered #  queryset # we can also register using this and add another column unit_price. # set the collection field to autocomplete field # to enable the search functionality in it # slug field is automatically created using the title field # you can add more fields here # pass the name of the csutom action we created # for displaying columns of product table you can also add # others tables # columns by making custom method like here inventory_status #  columns of collection class is also added # for making columns editable # for making pagination # implementing the filter method for filtering by collection # and last_update # like the select_related() method in query set # to preload the collection table to stop extra queries to run # for loading each column of a table indivudually # ordering the field of product model # check each invetory row in the product table # request repsresents the current http request # queryset represents the selected products/objects # every model admin contains this method to show # message to user # we should always specify 1 order # no extra orders that are by default # managing the items of the order # Register your models here. # for searching in the forms with collection title # but products_count field is not in the collection object # 'admin:app_model_page' is the url format # the pagename is changelist # reverse() create url for the product model and to get # the specific # collection id of it we are using the collection.id # the collection.products_count output become a link which # redirects to url. # so we need to add the query of products_count manually using #  the get_queryset() method # search the first and last name and word is case insensitive