from django.contrib import admin, messages
from django.db.models.aggregates import Count
from django.db.models.query import QuerySet
from django.utils.html import format_html, urlencode
from django.urls import reverse
from . import models
from humanresource.models import Currency


@admin.register(models.Currency)
class CurrencyAdmin(admin.ModelAdmin):
    list_display = ['name', 'code', 'symbol']


class InventoryFilter(admin.SimpleListFilter):
    title = 'inventory'
    parameter_name = 'inventory'

    def lookups(self, request, model_admin):
        return [
            ('<10', 'Low')
        ]

    def queryset(self, request, queryset: QuerySet):
        if self.value() == '<10':
            return queryset.filter(inventory__lt=10)


class ProductImageInline(admin.TabularInline):
    model = models.ProductImage
    readonly_fields = ['thumbnail']

    def thumbnail(self, instance):
        if instance.image.name != '':
            return format_html(f'<img src="{instance.image.url}" class="thumbnail" />')
        return ''


@admin.register(models.PackingStyle)
class PackingStyleAdmin(admin.ModelAdmin):
    list_display = ['title']


@admin.register(models.MeasurementUnit)
class MeasurementUnitAdmin(admin.ModelAdmin):
    list_display = ['title']


@admin.register(models.Supplier)
class SupplierAdmin(admin.ModelAdmin):
    list_display = ['name', 'country', 'owner', 'phone_number',
                    'bank_account_number', 'contacted_person']


@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin):
    autocomplete_fields = ['collection']
    prepopulated_fields = {
        'slug': ['title']
    }
    actions = ['clear_inventory']
    inlines = [ProductImageInline]
    list_display = ['title', 'unit_price', 'inventory',
                    'inventory_status', 'collection_title']
    list_filter = ['collection', 'last_update', InventoryFilter]
    list_per_page = 10
    list_select_related = ['collection']
    search_fields = ['title']

    def collection_title(self, product):
        return product.collection.title

    @admin.display(ordering='inventory')
    def inventory_status(self, product):
        if product.inventory < 10:
            return 'Low'
        return 'OK'

    @admin.action(description='Clear inventory')
    def clear_inventory(self, request, queryset):
        updated_count = queryset.update(inventory=0)
        self.message_user(
            request,
            f'{updated_count} products were successfully updated.',
            messages.ERROR
        )

    class Media:
        css = {
            'all': ['store/styles.css']
        }


@admin.register(models.ProductBatches)
class ProductBatchesAdmin(admin.ModelAdmin):
    list_display = ('product', 'batch_number',
                    'expiry_date', 'quantity', 'remarks')
    list_filter = ('product', 'expiry_date')
    search_fields = ('product__title', 'batch')
    list_per_page = 20
    autocomplete_fields = ['product']

    def get_queryset(self, request):
        # Get the default queryset
        queryset = super().get_queryset(request)

        # Filter the queryset to include only SaleOrderItems with quantity greater than 0
        queryset = queryset.filter(quantity__gt=0)

        return queryset


@admin.register(models.Collection)
class CollectionAdmin(admin.ModelAdmin):
    autocomplete_fields = ['featured_product']
    list_display = ['title', 'products_count']
    search_fields = ['title']

    @admin.display(ordering='products_count')
    def products_count(self, collection):
        url = (
            reverse('admin:inventory_product_changelist')
            + '?'
            + urlencode({
                'collection__id': str(collection.id)
            }))
        return format_html('<a href="{}">{} Products</a>', url, collection.products_count)

    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            products_count=Count('products')
        )


@admin.register(models.Consumer)
class ConsumerAdmin(admin.ModelAdmin):
    list_display = ('name', 'id', 'business_nature', 'in_charge',
                    'phone_number', 'view_balance')
    search_fields = ('name', 'in_charge', 'phone_number', 'email')
    list_filter = ('business_nature',)

    def view_balance(self, obj):
        url = reverse('inventory:print_consumer_balance',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}"> Print </a>', url)

    view_balance.short_description = 'Details'


@admin.register(models.ConsumerAccount)
class ConsumerAccountAdmin(admin.ModelAdmin):
    list_display = ('id', 'tx_date',  'consumer', 'tx_number', 'details', 'previous_balance',
                    'debit', 'credit', 'current_balance')
    readonly_fields = ('consumer', 'details', 'updated_by', 'created_by',)
    search_fields = ('consumer__name', 'consumer__id', 'tx_number')
    list_per_page = 15

    def has_add_permission(self, request):
        return False


@admin.register(models.Payment_From_Consumer)
class Payment_From_ConsumerAdmin(admin.ModelAdmin):
    list_display = ('id', 'consumer', 'received_by', 'received_in', 'remarks',
                    'amount_paid', 'remain_amount', 'print_payment_bill')
    # Add supplier field for autocomplete
    autocomplete_fields = ('consumer', 'received_by')
    fields = ['consumer', 'received_by',
              'received_in', 'amount_paid', 'remarks']
    list_per_page = 10
    list_filter = ('consumer',)

    def print_payment_bill(self, obj):
        url = reverse('inventory:print_consumer_payment_voucher',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}">Print</a>', url)

    print_payment_bill.short_description = 'voucher'

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            obj.created_by = request.user
        else:
            obj.updated_by = request.user
        super().save_model(request, obj, form, change)


@admin.register(models.SupplierAccount)
class SupplierAccountAdmin(admin.ModelAdmin):
    list_display = ('id', 'tx_date', 'supplier', 'tx_number',
                    'details', 'previous_balance', 'debit', 'credit',
                    'current_balance')
    readonly_fields = ('supplier', 'details', 'updated_by', 'created_by')
    search_fields = ('supplier__name', 'supplier__id', 'tx_number')
    list_per_page = 15

    def has_add_permission(self, request):
        return False


@admin.register(models.Payment_To_Supplier)
class Payment_To_SupplierAdmin(admin.ModelAdmin):
    list_display = ('id', 'supplier', 'paid_by', 'paid_from',
                    'amount_paid', 'remain_amount', 'receipt_no')
    fields = ['supplier', 'paid_by', 'paid_from',
              'amount_paid', 'receipt_no', 'remarks']
    list_filter = ('supplier',)
    list_per_page = 10

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            obj.created_by = request.user
        else:
            obj.updated_by = request.user
        super().save_model(request, obj, form, change)

@admin.register(models.ShareHolders)
class ShareHoldersAdmin(admin.ModelAdmin):
    list_display = ['name', 'contact', 'view_balance']
    search_fields = ['name', 'contact']

    def view_balance(self, obj):
        url = reverse('inventory:share_holder_details',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}"> Print </a>', url)

    view_balance.short_description = 'Balance'


@admin.register(models.Doctor)
class DoctorAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'contact', 'view_balance']
    search_fields = ['name', 'contact']

    def view_balance(self, obj):
        url = reverse('inventory:print_doctor_balance',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}"> Print </a>', url)

    view_balance.short_description = 'Balance'


@admin.register(models.DoctorCommission)
class DoctorCommissionAdmin(admin.ModelAdmin):
    list_display = ['doctor', 'placed_at', 'details',
                    'previous_balance', 'credit', 'debit', 'current_balance']
    readonly_fields = ['current_balance',
                       'debit', 'credit', 'previous_balance']
    autocomplete_fields = ['doctor']


@admin.register(models.DoctorProductCommission)
class DoctorProductCommissionAdmin(admin.ModelAdmin):
    list_display = ['doctor', 'product', 'commission']
    autocomplete_fields = ['doctor', 'product']


@admin.register(models.ConsumerProductDiscount)
class ConsumerProductDiscountAdmin(admin.ModelAdmin):
    list_display = ['consumer', 'product', 'discount', 'unit_price']
    autocomplete_fields = ['consumer', 'product']


class OrderItemInline(admin.TabularInline):
    autocomplete_fields = ['product']
    min_num = 0
    max_num = 100
    model = models.OrderItem
    extra = 0


@admin.register(models.Order)
class OrderAdmin(admin.ModelAdmin):
    inlines = [OrderItemInline]
    search_fields = ['id']
    list_display = ['id', 'order_by', 'order_to', 'placed_at',
                    'order_status', 'created_by', 'view_details']
    fields = ['order_status', 'order_by', 'order_to',
              'holder', 'due_date', 'cargo', 'currency', 'exchange_rate', 'amount_paid', 'remarks']

    def view_details(self, obj):
        url = reverse('inventory:order_print',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}">Print</a>', url)

    view_details.short_description = 'Order Details'

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            obj.created_by = request.user
        else:
            obj.updated_by = request.user
        super().save_model(request, obj, form, change)


class ReceivedOrderItemInline(admin.TabularInline):
    autocomplete_fields = ['product']
    min_num = 0
    max_num = 100
    model = models.ReceivedOrderItem
    extra = 0
    readonly_fields = ['ordered_quantity']


@admin.register(models.ReceiveOrder)
class ReceiveOrderAdmin(admin.ModelAdmin):
    inlines = [ReceivedOrderItemInline]
    autocomplete_fields = ['order']
    list_display = ['order', 'placed_at',
                    'remarks', 'created_by', 'view_details']
    fields = ['order', 'remarks']

    def view_details(self, obj):
        url = reverse('inventory:received_order_details',
                      kwargs={'pk': obj.id})
        return format_html('<a href="{}">Print</a>', url)

    view_details.short_description = 'Received Order Details'

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            obj.created_by = request.user
        else:
            obj.updated_by = request.user
        super().save_model(request, obj, form, change)


class SaleOrderItemsInline(admin.TabularInline):
    autocomplete_fields = ['product']
    model = models.SaleOrderItems
    extra = 0
    readonly_fields = ['price', 'net_price']


@admin.register(models.SaleOrder)
class SaleOrderAdmin(admin.ModelAdmin):
    inlines = [SaleOrderItemsInline]
    list_display = ['id', 'consumer', 'visited_by',
                    'created_at', 'payment_status', 'remarks', 'created_by', 'print_sale_bill']
    search_fields = ['consumer__name']
    fields = ['consumer', 'visited_by', 'payment_status', 'remarks']
    autocomplete_fields = ['consumer']
    readonly_fields = ['created_by', 'updated_by', 'created_at', 'updated_at']

    def print_sale_bill(self, obj):
        url = reverse('inventory:print_sale_bill', kwargs={'pk': obj.id})
        return format_html('<a href="{}">Print</a>', url)

    print_sale_bill.short_description = 'Bill'

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            obj.created_by = request.user
        else:
            obj.updated_by = request.user
        super().save_model(request, obj, form, change)
