from django.contrib import admin, messages
from django.utils import timezone
from django.utils.html import format_html

from core.models import (
    Category, CategoryField, Profile, Listing, ListingPhoto, Favorite,
    SavedSearch, Conversation, Message, InquiryRequest, Review,
    Notification, Report, PotentialDuplicate,
    EventCategory, Event, EventPhoto, EventTicketType, EventTicketOrder, EventFavorite,
)


# =========================================================================
# Categories
# =========================================================================

class CategoryFieldInline(admin.TabularInline):
    model = CategoryField
    extra = 1
    fields = ["name", "label", "field_type", "choices", "unit", "required", "order"]


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ["name", "category_type", "parent", "is_active", "order", "field_count", "listing_count"]
    list_filter = ["category_type", "is_active"]
    search_fields = ["name"]
    prepopulated_fields = {"slug": ("name",)}
    inlines = [CategoryFieldInline]

    def field_count(self, obj):
        return obj.fields.count()
    field_count.short_description = "Dynamic Fields"

    def listing_count(self, obj):
        return obj.listings.count()
    listing_count.short_description = "Listings"


@admin.register(CategoryField)
class CategoryFieldAdmin(admin.ModelAdmin):
    list_display = ["category", "label", "name", "field_type", "required", "order"]
    list_filter = ["field_type", "category"]
    search_fields = ["name", "label"]


# =========================================================================
# Profiles / KYC moderation
# =========================================================================

@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
    list_display = [
        "user", "account_type", "verification_badge_display", "verification_status",
        "is_lister", "is_discoverer", "created_at",
    ]
    list_filter = ["verification_status", "account_type", "is_lister", "is_discoverer"]
    search_fields = ["user__username", "user__email", "business_name", "id_number"]
    readonly_fields = ["created_at", "updated_at", "verified_at"]
    actions = ["approve_kyc", "reject_kyc"]
    fieldsets = (
        ("User", {"fields": ("user", "phone", "whatsapp", "avatar", "bio")}),
        ("Roles", {"fields": ("is_lister", "is_discoverer", "preferred_intent", "preferred_language", "preferred_currency")}),
        ("Individual KYC", {"fields": ("account_type", "id_number", "id_photo")}),
        ("Business KYC", {"fields": ("business_name", "business_registration_number", "business_address",
                                      "representative_id_photo", "proof_of_ownership")}),
        ("Verification", {"fields": ("verification_status", "verification_notes", "verified_at")}),
        ("Timestamps", {"fields": ("created_at", "updated_at")}),
    )

    def verification_badge_display(self, obj):
        badge = obj.verification_badge
        if badge:
            return format_html('<span style="color: green; font-weight:bold;">✔ {}</span>', badge)
        return "—"
    verification_badge_display.short_description = "Badge"

    @admin.action(description="Approve selected KYC submissions")
    def approve_kyc(self, request, queryset):
        updated = queryset.update(verification_status=Profile.VERIFIED, verified_at=timezone.now())
        self.message_user(request, f"{updated} profile(s) approved & verified.", messages.SUCCESS)

    @admin.action(description="Reject selected KYC submissions")
    def reject_kyc(self, request, queryset):
        updated = queryset.update(verification_status=Profile.REJECTED)
        self.message_user(request, f"{updated} profile(s) rejected.", messages.WARNING)


# =========================================================================
# Listings
# =========================================================================

class ListingPhotoInline(admin.TabularInline):
    model = ListingPhoto
    extra = 0
    fields = ["image", "caption", "is_cover", "order"]


@admin.register(Listing)
class ListingAdmin(admin.ModelAdmin):
    list_display = [
        "title", "category", "lister", "status", "price_display",
        "is_verified_listing", "is_featured", "views_count", "created_at",
    ]
    list_filter = ["status", "category", "is_verified_listing", "is_featured", "purpose", "currency"]
    search_fields = ["title", "description", "address", "lister__username"]
    readonly_fields = ["views_count", "contact_clicks_count", "created_at", "updated_at", "location_fingerprint"]
    inlines = [ListingPhotoInline]
    actions = ["approve_listings", "reject_listings", "feature_listings", "unfeature_listings"]
    date_hierarchy = "created_at"

    def price_display(self, obj):
        if obj.price is None:
            return "—"
        return f"{obj.currency} {obj.price:,.0f}"
    price_display.short_description = "Price"

    @admin.action(description="Approve & activate selected listings")
    def approve_listings(self, request, queryset):
        updated = queryset.update(status=Listing.STATUS_ACTIVE)
        self.message_user(request, f"{updated} listing(s) activated.", messages.SUCCESS)

    @admin.action(description="Reject selected listings")
    def reject_listings(self, request, queryset):
        updated = queryset.update(status=Listing.STATUS_REJECTED)
        self.message_user(request, f"{updated} listing(s) rejected.", messages.WARNING)

    @admin.action(description="Feature selected listings")
    def feature_listings(self, request, queryset):
        updated = queryset.update(is_featured=True)
        self.message_user(request, f"{updated} listing(s) featured.", messages.SUCCESS)

    @admin.action(description="Un-feature selected listings")
    def unfeature_listings(self, request, queryset):
        updated = queryset.update(is_featured=False)
        self.message_user(request, f"{updated} listing(s) un-featured.", messages.INFO)


@admin.register(ListingPhoto)
class ListingPhotoAdmin(admin.ModelAdmin):
    list_display = ["listing", "is_cover", "order", "uploaded_at"]
    list_filter = ["is_cover"]


# =========================================================================
# Discoverer tools
# =========================================================================

@admin.register(Favorite)
class FavoriteAdmin(admin.ModelAdmin):
    list_display = ["user", "listing", "created_at"]
    search_fields = ["user__username", "listing__title"]


@admin.register(SavedSearch)
class SavedSearchAdmin(admin.ModelAdmin):
    list_display = ["user", "label", "category", "keyword", "is_active", "last_notified_at"]
    list_filter = ["is_active", "category"]


# =========================================================================
# Messaging
# =========================================================================

class MessageInline(admin.TabularInline):
    model = Message
    extra = 0
    readonly_fields = ["sender", "body", "created_at", "is_read"]


@admin.register(Conversation)
class ConversationAdmin(admin.ModelAdmin):
    list_display = ["id", "listing", "created_at", "updated_at"]
    inlines = [MessageInline]
    filter_horizontal = ["participants"]


@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
    list_display = ["conversation", "sender", "short_body", "is_read", "created_at"]
    list_filter = ["is_read"]

    def short_body(self, obj):
        return obj.body[:60]
    short_body.short_description = "Message"


# =========================================================================
# Inquiries & reviews
# =========================================================================

@admin.register(InquiryRequest)
class InquiryRequestAdmin(admin.ModelAdmin):
    list_display = ["listing", "requester", "status", "move_in_date", "budget", "created_at"]
    list_filter = ["status"]
    actions = ["mark_responded", "mark_closed"]

    @admin.action(description="Mark as responded")
    def mark_responded(self, request, queryset):
        queryset.update(status=InquiryRequest.STATUS_RESPONDED)

    @admin.action(description="Mark as closed")
    def mark_closed(self, request, queryset):
        queryset.update(status=InquiryRequest.STATUS_CLOSED)


@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
    list_display = ["listing", "reviewer", "rating", "is_approved", "is_flagged", "created_at"]
    list_filter = ["is_approved", "is_flagged", "rating"]
    actions = ["approve_reviews", "unapprove_reviews"]

    @admin.action(description="Approve selected reviews")
    def approve_reviews(self, request, queryset):
        queryset.update(is_approved=True, is_flagged=False)

    @admin.action(description="Unapprove / hide selected reviews")
    def unapprove_reviews(self, request, queryset):
        queryset.update(is_approved=False)


# =========================================================================
# Notifications
# =========================================================================

@admin.register(Notification)
class NotificationAdmin(admin.ModelAdmin):
    list_display = ["user", "notification_type", "title", "is_read", "created_at"]
    list_filter = ["notification_type", "is_read"]


# =========================================================================
# Trust & safety
# =========================================================================

@admin.register(Report)
class ReportAdmin(admin.ModelAdmin):
    list_display = ["id", "reporter", "listing", "reported_user", "reason", "status", "created_at"]
    list_filter = ["reason", "status"]
    actions = ["mark_reviewed", "mark_action_taken", "mark_dismissed"]

    @admin.action(description="Mark as reviewed")
    def mark_reviewed(self, request, queryset):
        queryset.update(status=Report.STATUS_REVIEWED)

    @admin.action(description="Mark action taken (and deactivate listing)")
    def mark_action_taken(self, request, queryset):
        for report in queryset:
            if report.listing:
                report.listing.status = Listing.STATUS_CLOSED
                report.listing.save()
        queryset.update(status=Report.STATUS_ACTION_TAKEN)

    @admin.action(description="Dismiss selected reports")
    def mark_dismissed(self, request, queryset):
        queryset.update(status=Report.STATUS_DISMISSED)


@admin.register(PotentialDuplicate)
class PotentialDuplicateAdmin(admin.ModelAdmin):
    list_display = ["listing_a", "listing_b", "similarity_reason", "is_resolved", "created_at"]
    list_filter = ["is_resolved"]
    actions = ["mark_resolved"]

    @admin.action(description="Mark resolved")
    def mark_resolved(self, request, queryset):
        queryset.update(is_resolved=True)


# =========================================================================
# Events — dedicated content type
# =========================================================================

class EventTicketTypeInline(admin.TabularInline):
    model = EventTicketType
    extra = 1
    fields = ["name", "price", "quantity_available", "quantity_sold", "sales_end", "order"]
    readonly_fields = ["quantity_sold"]


class EventPhotoInline(admin.TabularInline):
    model = EventPhoto
    extra = 0
    fields = ["image", "caption", "is_cover", "order"]


@admin.register(EventCategory)
class EventCategoryAdmin(admin.ModelAdmin):
    list_display = ["name", "is_active", "order", "event_count"]
    list_filter = ["is_active"]
    search_fields = ["name"]
    prepopulated_fields = {"slug": ("name",)}

    def event_count(self, obj):
        return obj.events.count()
    event_count.short_description = "Events"


@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    list_display = [
        "title", "event_type", "organizer", "status", "start_datetime", "end_datetime",
        "price_display", "is_verified_event", "is_featured", "views_count",
    ]
    list_filter = ["status", "event_type", "is_verified_event", "is_featured", "is_online", "currency"]
    search_fields = ["title", "description", "address", "venue_name", "organizer__username"]
    readonly_fields = [
        "views_count", "created_at", "updated_at",
        "is_verified_event", "min_ticket_price", "max_ticket_price", "is_free",
    ]
    inlines = [EventTicketTypeInline, EventPhotoInline]
    actions = ["publish_events", "reject_events", "cancel_events", "feature_events", "unfeature_events"]
    date_hierarchy = "start_datetime"

    def price_display(self, obj):
        if obj.is_free:
            return "Free"
        if obj.min_ticket_price is None:
            return "—"
        if obj.min_ticket_price == obj.max_ticket_price:
            return f"{obj.currency} {obj.min_ticket_price:,.0f}"
        return f"{obj.currency} {obj.min_ticket_price:,.0f} – {obj.max_ticket_price:,.0f}"
    price_display.short_description = "Price"

    @admin.action(description="Publish selected events")
    def publish_events(self, request, queryset):
        updated = queryset.update(status=Event.STATUS_PUBLISHED)
        self.message_user(request, f"{updated} event(s) published.", messages.SUCCESS)

    @admin.action(description="Reject selected events")
    def reject_events(self, request, queryset):
        updated = queryset.update(status=Event.STATUS_REJECTED)
        self.message_user(request, f"{updated} event(s) rejected.", messages.WARNING)

    @admin.action(description="Cancel selected events")
    def cancel_events(self, request, queryset):
        updated = queryset.update(status=Event.STATUS_CANCELLED)
        self.message_user(request, f"{updated} event(s) cancelled.", messages.WARNING)

    @admin.action(description="Feature selected events")
    def feature_events(self, request, queryset):
        updated = queryset.update(is_featured=True)
        self.message_user(request, f"{updated} event(s) featured.", messages.SUCCESS)

    @admin.action(description="Un-feature selected events")
    def unfeature_events(self, request, queryset):
        updated = queryset.update(is_featured=False)
        self.message_user(request, f"{updated} event(s) un-featured.", messages.INFO)

    def save_formset(self, request, form, formset, change):
        super().save_formset(request, form, formset, change)
        if formset.model is EventTicketType:
            form.instance.refresh_price_summary()


@admin.register(EventTicketOrder)
class EventTicketOrderAdmin(admin.ModelAdmin):
    list_display = ["reference_code", "event", "ticket_type", "buyer", "quantity", "total_price", "status", "created_at"]
    list_filter = ["status", "event"]
    search_fields = ["reference_code", "buyer__username", "event__title"]
    actions = ["mark_confirmed", "mark_cancelled"]

    @admin.action(description="Mark as confirmed")
    def mark_confirmed(self, request, queryset):
        queryset.update(status=EventTicketOrder.STATUS_CONFIRMED)

    @admin.action(description="Mark as cancelled")
    def mark_cancelled(self, request, queryset):
        queryset.update(status=EventTicketOrder.STATUS_CANCELLED)


@admin.register(EventFavorite)
class EventFavoriteAdmin(admin.ModelAdmin):
    list_display = ["user", "event", "created_at"]
    search_fields = ["user__username", "event__title"]


admin.site.site_header = "Acco Administration"
admin.site.site_title = "Acco Admin"
admin.site.index_title = "Platform Management"