"""
Admin classes for pricing models including compute plans, storage plans, and VSHN AppCat pricing
"""

from django.contrib import admin
from django.utils.html import format_html
from adminsortable2.admin import SortableAdminMixin
from import_export.admin import ImportExportModelAdmin
from import_export import resources
from import_export.fields import Field
from import_export.widgets import ForeignKeyWidget

from ..models import (
    ComputePlan,
    ComputePlanGroup,
    ComputePlanPrice,
    CloudProvider,
    StoragePlan,
    StoragePlanPrice,
    VSHNAppCatBaseFee,
    VSHNAppCatPrice,
    VSHNAppCatUnitRate,
    ProgressiveDiscountModel,
    DiscountTier,
)


class ComputePlanPriceInline(admin.TabularInline):
    """Inline admin for ComputePlanPrice model"""

    model = ComputePlanPrice
    extra = 1
    fields = ("currency", "amount")


class ComputePlanItemInline(admin.TabularInline):
    """Inline admin for ComputePlan model"""

    model = ComputePlan
    extra = 1
    fields = ("name", "vcpus", "ram", "active", "valid_from", "valid_to")


@admin.register(ComputePlanGroup)
class ComputePlanGroupAdmin(SortableAdminMixin, admin.ModelAdmin):
    """Admin configuration for ComputePlanGroup model"""

    list_display = ("name", "node_label", "compute_plans_count")
    search_fields = ("name", "description", "node_label")
    ordering = ("order",)

    def compute_plans_count(self, obj):
        """Display count of compute plans in this group"""
        return obj.compute_plans.count()

    compute_plans_count.short_description = "Compute Plans"


class ComputePlanResource(resources.ModelResource):
    """Import/Export resource for ComputePlan model"""

    cloud_provider = Field(
        column_name="cloud_provider",
        attribute="cloud_provider",
        widget=ForeignKeyWidget(CloudProvider, "name"),
    )
    group = Field(
        column_name="group",
        attribute="group",
        widget=ForeignKeyWidget(ComputePlanGroup, "name"),
    )
    prices = Field(column_name="prices", attribute=None)

    class Meta:
        model = ComputePlan
        skip_unchanged = True
        report_skipped = False
        import_id_fields = ["name"]
        fields = (
            "name",
            "vcpus",
            "ram",
            "cpu_mem_ratio",
            "cloud_provider",
            "group",
            "active",
            "term",
            "valid_from",
            "valid_to",
            "prices",
        )

    def dehydrate_prices(self, compute_plan):
        """Export prices in a custom format"""
        prices = compute_plan.prices.all()
        if not prices:
            return ""
        return "|".join([f"{p.currency} {p.amount}" for p in prices])

    def save_m2m(self, instance, row, *args, **kwargs):
        """Handle many-to-many relationships during import"""
        super().save_m2m(instance, row, *args, **kwargs)

        # Handle prices
        if "prices" in row and row["prices"]:
            # Clear existing prices first
            instance.prices.all().delete()

            # Create new prices
            price_entries = row["prices"].split("|")
            for entry in price_entries:
                if " " in entry:
                    currency, amount = entry.split(" ")
                    ComputePlanPrice.objects.create(
                        compute_plan=instance, currency=currency, amount=amount
                    )


@admin.register(ComputePlan)
class ComputePlansAdmin(ImportExportModelAdmin):
    """Admin configuration for ComputePlan model with import/export functionality"""

    resource_class = ComputePlanResource
    list_display = (
        "name",
        "cloud_provider",
        "group",
        "vcpus",
        "ram",
        "term",
        "display_prices",
        "active",
    )
    search_fields = ("name", "cloud_provider__name", "group__name")
    list_filter = ("active", "cloud_provider", "group")
    ordering = ("name",)
    inlines = [ComputePlanPriceInline]

    def display_prices(self, obj):
        """Display formatted prices for the list view"""
        prices = obj.prices.all()
        if not prices:
            return "No prices set"
        return format_html("<br>".join([f"{p.amount} {p.currency}" for p in prices]))

    display_prices.short_description = "Prices (Amount Currency)"


class VSHNAppCatBaseFeeInline(admin.TabularInline):
    """Inline admin for VSHNAppCatBaseFee model"""

    model = VSHNAppCatBaseFee
    extra = 1
    fields = ("currency", "amount")


class VSHNAppCatUnitRateInline(admin.TabularInline):
    """Inline admin for VSHNAppCatUnitRate model"""

    model = VSHNAppCatUnitRate
    extra = 1
    fields = ("currency", "service_level", "amount")


class DiscountTierInline(admin.TabularInline):
    """Inline admin for DiscountTier model"""

    model = DiscountTier
    extra = 1
    fields = ("min_units", "max_units", "discount_percent")
    ordering = ("min_units",)


@admin.register(ProgressiveDiscountModel)
class ProgressiveDiscountModelAdmin(admin.ModelAdmin):
    """Admin configuration for ProgressiveDiscountModel"""

    list_display = ("name", "description", "active")
    search_fields = ("name", "description")
    inlines = [DiscountTierInline]


@admin.register(VSHNAppCatPrice)
class VSHNAppCatPriceAdmin(admin.ModelAdmin):
    """Admin configuration for VSHNAppCatPrice model"""

    list_display = (
        "service",
        "variable_unit",
        "term",
        "discount_model",
        "admin_display_base_fees",
        "admin_display_unit_rates",
    )
    list_filter = ("variable_unit", "service", "discount_model")
    search_fields = ("service__name",)
    inlines = [VSHNAppCatBaseFeeInline, VSHNAppCatUnitRateInline]

    def admin_display_base_fees(self, obj):
        """Display base fees in admin list view"""
        fees = obj.base_fees.all()
        if not fees:
            return "No base fees"
        return format_html(
            "<br>".join([f"{fee.amount} {fee.currency}" for fee in fees])
        )

    admin_display_base_fees.short_description = "Base Fees"

    def admin_display_unit_rates(self, obj):
        """Display unit rates in admin list view"""
        rates = obj.unit_rates.all()
        if not rates:
            return "No unit rates"
        return format_html(
            "<br>".join(
                [
                    f"{rate.amount} {rate.currency} ({rate.get_service_level_display()})"
                    for rate in rates
                ]
            )
        )

    admin_display_unit_rates.short_description = "Unit Rates"


class StoragePlanPriceInline(admin.TabularInline):
    """Inline admin for StoragePlanPrice model"""

    model = StoragePlanPrice
    extra = 1
    fields = ("currency", "amount")


class StoragePlanResource(resources.ModelResource):
    """Import/Export resource for StoragePlan model"""

    cloud_provider = Field(
        column_name="cloud_provider",
        attribute="cloud_provider",
        widget=ForeignKeyWidget(CloudProvider, "name"),
    )
    prices = Field(column_name="prices", attribute=None)

    class Meta:
        model = StoragePlan
        skip_unchanged = True
        report_skipped = False
        import_id_fields = ["name"]
        fields = (
            "name",
            "cloud_provider",
            "term",
            "unit",
            "valid_from",
            "valid_to",
            "prices",
        )

    def dehydrate_prices(self, storage_plan):
        """Export prices in a custom format"""
        prices = storage_plan.prices.all()
        if not prices:
            return ""
        return "|".join([f"{p.currency} {p.amount}" for p in prices])

    def save_m2m(self, instance, row, *args, **kwargs):
        """Handle many-to-many relationships during import"""
        super().save_m2m(instance, row, *args, **kwargs)

        # Handle prices
        if "prices" in row and row["prices"]:
            # Clear existing prices first
            instance.prices.all().delete()

            # Create new prices
            price_entries = row["prices"].split("|")
            for entry in price_entries:
                if " " in entry:
                    currency, amount = entry.split(" ")
                    StoragePlanPrice.objects.create(
                        storage_plan=instance, currency=currency, amount=amount
                    )


@admin.register(StoragePlan)
class StoragePlanAdmin(ImportExportModelAdmin):
    """Admin configuration for StoragePlan model with import/export functionality"""

    resource_class = StoragePlanResource
    list_display = (
        "name",
        "cloud_provider",
        "term",
        "unit",
        "display_prices",
    )
    search_fields = ("name", "cloud_provider__name")
    list_filter = ("cloud_provider",)
    ordering = ("name",)
    inlines = [StoragePlanPriceInline]

    def display_prices(self, obj):
        """Display formatted prices for the list view"""
        prices = obj.prices.all()
        if not prices:
            return "No prices set"
        return format_html("<br>".join([f"{p.amount} {p.currency}" for p in prices]))

    display_prices.short_description = "Prices (Amount Currency)"
