from django.contrib import admin, messages
from .models import *
from unfold.admin import TabularInline, StackedInline
from unfold.contrib.inlines.admin import NonrelatedTabularInline
from django.db.models import Q
from import_export.admin import ImportExportModelAdmin
from unfold.contrib.import_export.forms import ExportForm, ImportForm, SelectableFieldsExportForm
from unfold.contrib.forms.widgets import ArrayWidget, WysiwygWidget
from django.contrib.postgres.fields import ArrayField
from utils.admin import ModelAdmin
from django.utils.html import format_html, format_html_join
from azbankgateways.models.banks import Bank
from unfold.decorators import action
from django.shortcuts import redirect
from .permissons import ShopOrderAdminPermission
from django.urls import reverse
from django.utils.safestring import mark_safe

class OrderItemModelInline(StackedInline):
    model = OrderItemModel
    extra = 0
    max_num = 0
    def has_delete_permission(self, request, obj=None):
        return False
    def get_readonly_fields(self, request, obj=None):
        return [field.name for field in self.model._meta.fields]



@admin.register(OrderItemModel)
class OrderItemAdmin(ModelAdmin):
    def has_view_permission(self, request, obj=None):
        if request.user.is_superuser or obj == None:
            return True
        
        if not hasattr(request.user, 'shop'):
            return False
        print(obj.product.product.shop)
        print(request.user.shop)
        return request.user.shop == obj.product.product.shop


@admin.register(DiscountCode)
class DiscountCodeAdmin(ModelAdmin, ImportExportModelAdmin):
    import_form_class = ImportForm
    export_form_class = ExportForm
    list_display = ['code', 'expiration_date', 'percent', 'quantity']


class BankRecordInline(StackedInline):
    model = Bank
    extra = 0
    max_num = 0
    tab = True
    def has_delete_permission(self, request, obj=None):
        return False
    def get_readonly_fields(self, request, obj=None):
        return [field.name for field in self.model._meta.fields]


class CartItemInline(StackedInline):
    model = CartItem
    extra = 0
    max_num = 0

    def has_delete_permission(self, request, obj=None):
        return False
    
    def has_add_permission(self, request, obj=None):
        return False

@admin.register(Cart)
class CartAdmin(ModelAdmin):
    inlines = [CartItemInline]


class ShopOrderInline(StackedInline):
    model = ShopOrderModel
    extra = 0
    max_num = 0
    tab = True

    def has_view_permission(self, request, obj=None):
        if request.user.is_superuser or obj == None:
            return True
        
        if not hasattr(request.user, 'shop'):
            return False
        
        return request.user.shop == obj.shop


class ShopOrderItemInline(NonrelatedTabularInline):  # NonrelatedStackedInline is available as well
    model = ShopOrderItem
    tab = True
    extra = 0
    show_change_link = True

    def get_form_queryset(self, obj):
        """
        Gets all nonrelated objects needed for inlines. Method must be implemented.
        """
        shop_orders = obj.shop_orders.all()

        return ShopOrderItem.objects.filter(shop_order__in=shop_orders)

    def save_new_instance(self, parent, instance):
        """
        Extra save method which can for example update inline instances based on current
        main model object. Method must be implemented.
        """
        pass

    def has_view_permission(self, request, obj=None):
        if request.user.is_superuser or obj == None:
            return True
        
        if not hasattr(request.user, 'shop'):
            return False
        
        return request.user.shop == obj.shop



from .models import ShopDailyReport, ShopOrderModel
@admin.register(ShopDailyReport)
class ShopDailyReportAdmin(ModelAdmin):
    list_display = ['shop', 'date', 'is_settled',]
    inlines = [ShopOrderInline, ShopOrderItemInline]
    def get_queryset(self, request):

        if request.user.is_superuser:
            return self.model.objects.all()
        
        if not hasattr(request.user, 'shop'):
            return self.model.objects.none()
        
        queryset = self.model.objects.filter(shop=request.user.shop)
        return queryset
    
    def has_view_permission(self, request, obj=None):
        if request.user.is_superuser or obj == None:
            return True
        
        if not hasattr(request.user, 'shop'):
            return False
        
        return request.user.shop == obj.shop


class ShopOrderItemInline(StackedInline):
    model = ShopOrderItem
    extra = 0
    max_num = 0
    tab = True


    def has_view_permission(self, request, obj=None):
        if request.user.is_superuser or obj == None:
            return True
        
        if not hasattr(request.user, 'shop'):
            return False
        
        return request.user.shop == obj.shop


@admin.register(ShopOrderModel)
class ShopOrderModelAdmin(ShopOrderAdminPermission, ModelAdmin):
    inlines = [ShopOrderItemInline]
    list_display = ['id', 'shop', 'order', 'customer_name', 'status', 'is_paid', 'is_settled', 'created_at', 'download_invoice_button']
    readonly_fields = ['download_invoice_link']

    def download_invoice_button(self, obj):
        if obj.pk:
            url = reverse('download-shop-order-invoice', args=[obj.pk])
            return mark_safe(f'<a class="button" href="{url}" target="_blank" style="background-color: #28a745; color: white; border-color: #28a745;">دانلود فاکتور</a>')
        return '-'
    download_invoice_button.short_description = 'فاکتور'
    
    def download_invoice_link(self, obj):
        if obj.pk:
            url = reverse('download-shop-order-invoice', args=[obj.pk])
            return mark_safe(f'<a href="{url}" target="_blank" style="background-color: #28a745; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;">دانلود فاکتور PDF</a>')
        return '-'
    download_invoice_link.short_description = 'دانلود فاکتور'


    def get_queryset(self, request):

        if request.user.is_superuser:
            return ShopOrderModel.objects.all()
        
        if not hasattr(request.user, 'shop'):
            return ShopOrderModel.objects.none()
        
        queryset = ShopOrderModel.objects.filter(shop=request.user.shop)
        return queryset
    

@admin.register(OrderModel)
class OrderAdmin(ModelAdmin, ImportExportModelAdmin):
    import_form_class = ImportForm
    export_form_class = ExportForm
    search_fields = ['user__phone', 'user__first_name', 'user__last_name', 'user__email']
    list_filter = ['is_paid', 'status']
    actions_list = ['redirect_to_learn', 'udpate_bank_status']
    list_display = ['order_id', 'user', 'is_paid', 'status', 'discount_code', 'address', 'download_invoice_button']
    readonly_fields = ('created_at', 'tax', 'final_price', 'cart_total', 'discount_amount', 'discount_code', 'user', 'address', 'is_paid', 'special_discount_code','download_invoice_link')
    compressed_fields = True
    warn_unsaved_form = True
    # exclude = ('bank_records',)
    formfield_overrides = {
        ArrayField: {
            "widget": ArrayWidget,
        }
    }
    inlines = [OrderItemModelInline, BankRecordInline]

    def order_id(self, obj):
        return f"سفارش {obj.pk}"
    order_id.short_description = "شماره سفارش"
    
    def download_invoice_button(self, obj):
        if obj.pk:
            url = reverse('download-order-invoice', args=[obj.pk])
            return mark_safe(f'<a class="button" href="{url}" target="_blank" style="background-color: #28a745; color: white; border-color: #28a745;">دانلود فاکتور</a>')
        return '-'
    download_invoice_button.short_description = 'فاکتور'
    
    def download_invoice_link(self, obj):
        if obj.pk:
            url = reverse('download-order-invoice', args=[obj.pk])
            return mark_safe(f'<a href="{url}" target="_blank" style="background-color: #28a745; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;">دانلود فاکتور PDF</a>')
        return '-'
    download_invoice_link.short_description = 'دانلود فاکتور'



    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super().get_search_results(request, queryset, search_term)
        

        if search_term.isdigit():
            order_id_search = int(search_term) - 1000  
            queryset |= self.model.objects.filter(Q(pk=order_id_search))
        
        return queryset, use_distinct

    @action(description='اپدیت وضعیت رکورد های بانکی')
    def udpate_bank_status(self, request):
        import logging
        from azbankgateways import (
            bankfactories,
            models as bank_models,
            default_settings as settings,
        )
        factory = bankfactories.BankFactory()

        bank_models.Bank.objects.update_expire_records()

        for item in bank_models.Bank.objects.filter_return_from_bank():
            bank = factory.create(
                bank_type=item.bank_type, identifier=item.bank_choose_identifier
            )
            bank.verify(item.tracking_code)
            bank_record = bank_models.Bank.objects.get(tracking_code=item.tracking_code)
            if bank_record.is_success:
                logging.debug("This record is verify now.", extra={"pk": bank_record.pk})
        messages.success(request, f"با موفقیت اپدیت شد")
        return redirect("admin:order_ordermodel_changelist")
    


