from django.contrib import admin, messages
from django.utils.translation import gettext_lazy as _

from servala.core.forms import ControlPlaneAdminForm, ServiceDefinitionAdminForm
from servala.core.models import (
    BillingEntity,
    CloudProvider,
    ControlPlane,
    Organization,
    OrganizationMembership,
    OrganizationOrigin,
    Plan,
    Service,
    ServiceCategory,
    ServiceDefinition,
    ServiceOffering,
    ServiceOfferingControlPlane,
    User,
)


@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    list_display = (
        "email",
        "first_name",
        "last_name",
        "company",
        "is_staff",
        "is_superuser",
    )
    list_filter = ("is_staff", "is_superuser")
    search_fields = ("email", "first_name", "last_name", "company")
    ordering = ("email",)
    fieldsets = (
        (None, {"fields": ("email",)}),
        (_("Personal info"), {"fields": ("first_name", "last_name", "company")}),
        (_("Permissions"), {"fields": ("is_staff", "is_superuser")}),
    )
    add_fieldsets = (
        (
            None,
            {
                "classes": ("wide",),
                "fields": ("email", "password1", "password2"),
            },
        ),
    )


class OrganizationMembershipInline(admin.TabularInline):
    model = OrganizationMembership
    extra = 1
    autocomplete_fields = ("user",)


@admin.register(Organization)
class OrganizationAdmin(admin.ModelAdmin):
    list_display = ("name", "billing_entity", "origin")
    list_filter = ("origin",)
    search_fields = ("name",)
    autocomplete_fields = ("billing_entity", "origin")
    inlines = (OrganizationMembershipInline,)


@admin.register(BillingEntity)
class BillingEntityAdmin(admin.ModelAdmin):
    list_display = ("name", "erp_reference")
    search_fields = ("name", "erp_reference")


@admin.register(OrganizationOrigin)
class OrganizationOriginAdmin(admin.ModelAdmin):
    list_display = ("name",)
    search_fields = ("name",)


@admin.register(OrganizationMembership)
class OrganizationMembershipAdmin(admin.ModelAdmin):
    list_display = ("user", "organization", "role", "date_joined")
    list_filter = ("role", "date_joined", "organization")
    search_fields = ("user__email", "organization__name")
    autocomplete_fields = ("user", "organization")
    date_hierarchy = "date_joined"


@admin.register(ServiceCategory)
class ServiceCategoryAdmin(admin.ModelAdmin):
    list_display = ("name", "parent")
    list_filter = ("parent",)
    search_fields = ("name", "description")
    autocomplete_fields = ("parent",)


class PlanInline(admin.TabularInline):
    model = Plan
    extra = 1


@admin.register(Service)
class ServiceAdmin(admin.ModelAdmin):
    list_display = ("name", "category")
    list_filter = ("category",)
    search_fields = ("name", "description")
    autocomplete_fields = ("category",)
    prepopulated_fields = {"slug": ["name"]}


@admin.register(CloudProvider)
class CloudProviderAdmin(admin.ModelAdmin):
    list_display = ("name",)
    search_fields = ("name", "description")


@admin.register(ControlPlane)
class ControlPlaneAdmin(admin.ModelAdmin):
    form = ControlPlaneAdminForm
    list_display = ("name", "cloud_provider")
    list_filter = ("cloud_provider",)
    search_fields = ("name", "description")
    autocomplete_fields = ("cloud_provider",)
    actions = ["test_kubernetes_connection"]

    fieldsets = (
        (
            None,
            {"fields": ("name", "description", "cloud_provider")},
        ),
        (
            _("API Credentials"),
            {
                "fields": ("certificate_authority_data", "server", "token"),
                "description": _(
                    "All three credential fields must be provided together or left empty."
                ),
            },
        ),
    )

    def get_exclude(self, request, obj=None):
        # Exclude the original api_credentials field as we're using our custom fields
        return ["api_credentials"]

    def response_change(self, request, obj):
        result = super().response_change(request, obj)
        if "_save_and_test" in request.POST:
            success, message = obj.test_connection()
            if success:
                messages.success(request, message)
            else:
                messages.warning(request, message)
        return result

    def test_kubernetes_connection(self, request, queryset):
        """Admin action to test Kubernetes connection for selected control planes"""
        for control_plane in queryset:
            success, message = control_plane.test_connection()
            message = f"{control_plane.name}: {message}"

            if success:
                messages.success(request, message)
            else:
                messages.warning(request, message)

    test_kubernetes_connection.short_description = _("Test Kubernetes connection")


@admin.register(Plan)
class PlanAdmin(admin.ModelAdmin):
    list_display = ("name", "service_offering", "term")
    list_filter = ("service_offering", "term")
    search_fields = ("name", "description")
    autocomplete_fields = ("service_offering",)


@admin.register(ServiceDefinition)
class ServiceDefinitionAdmin(admin.ModelAdmin):
    form = ServiceDefinitionAdminForm
    list_display = ("name", "service")
    list_filter = ("service",)
    search_fields = ("name", "description")
    autocomplete_fields = ("service",)

    fieldsets = (
        (
            None,
            {"fields": ("name", "description", "service")},
        ),
        (
            _("API Definition"),
            {
                "fields": ("api_group", "api_version", "api_kind"),
                "description": _("API definition for the Kubernetes Custom Resource"),
            },
        ),
    )

    def get_exclude(self, request, obj=None):
        # Exclude the original api_definition field as we're using our custom fields
        return ["api_definition"]


class ServiceOfferingControlPlaneInline(admin.TabularInline):
    model = ServiceOfferingControlPlane
    extra = 1
    autocomplete_fields = ("control_plane", "service_definition")


@admin.register(ServiceOfferingControlPlane)
class ServiceOfferingControlPlaneAdmin(admin.ModelAdmin):
    list_display = ("service_offering", "control_plane", "service_definition")
    list_filter = ("service_offering", "control_plane", "service_definition")
    search_fields = ("service_offering__service__name", "control_plane__name")
    autocomplete_fields = ("service_offering", "control_plane", "service_definition")


@admin.register(ServiceOffering)
class ServiceOfferingAdmin(admin.ModelAdmin):
    list_display = ("id", "service", "provider")
    list_filter = ("service", "provider")
    search_fields = ("description",)
    autocomplete_fields = ("service", "provider")
    inlines = (
        ServiceOfferingControlPlaneInline,
        PlanInline,
    )
