"""
Integrations admin
"""

from django.contrib import admin
from django.utils.html import format_html, mark_safe

from .models import (
    EventMapping,
    ExternalAPIKey,
    HISEventType,
    HISTestPatient,
    HISTestVisit,
    HISPatientVisit,
    HISVisitEvent,
    InboundEvent,
    IntegrationConfig,
    SurveyTemplateMapping,
)


@admin.register(InboundEvent)
class InboundEventAdmin(admin.ModelAdmin):
    """Inbound event admin"""

    list_display = ["source_system", "event_code", "encounter_id", "status_badge", "processing_attempts", "received_at"]
    list_filter = ["status", "source_system", "received_at"]
    search_fields = ["encounter_id", "patient_identifier", "event_code"]
    ordering = ["-received_at"]
    date_hierarchy = "received_at"

    fieldsets = (
        ("Event Information", {"fields": ("source_system", "event_code", "encounter_id", "patient_identifier")}),
        ("Payload", {"fields": ("payload_json",), "classes": ("collapse",)}),
        ("Processing Status", {"fields": ("status", "processing_attempts", "error")}),
        ("Extracted Context", {"fields": ("physician_license", "department_code"), "classes": ("collapse",)}),
        ("Timestamps", {"fields": ("received_at", "processed_at", "created_at", "updated_at")}),
        ("Metadata", {"fields": ("metadata",), "classes": ("collapse",)}),
    )

    readonly_fields = ["received_at", "processed_at", "created_at", "updated_at"]

    def status_badge(self, obj):
        """Display status with color badge"""
        colors = {
            "pending": "warning",
            "processing": "info",
            "processed": "success",
            "failed": "danger",
            "ignored": "secondary",
        }
        color = colors.get(obj.status, "secondary")
        return format_html('<span class="badge bg-{}">{}</span>', color, obj.get_status_display())

    status_badge.short_description = "Status"

    def has_add_permission(self, request):
        # Events should only be created via API
        return False


class EventMappingInline(admin.TabularInline):
    """Inline admin for event mappings"""

    model = EventMapping
    extra = 1
    fields = ["external_event_code", "internal_event_code", "is_active"]


@admin.register(IntegrationConfig)
class IntegrationConfigAdmin(admin.ModelAdmin):
    """Integration configuration admin"""

    list_display = ["name", "source_system", "is_active", "last_sync_at", "created_at"]
    list_filter = ["source_system", "is_active"]
    search_fields = ["name", "description"]
    ordering = ["name"]
    inlines = [EventMappingInline]

    fieldsets = (
        (None, {"fields": ("name", "source_system", "description")}),
        ("Connection", {"fields": ("api_url", "api_key"), "classes": ("collapse",)}),
        ("Configuration", {"fields": ("is_active", "config_json"), "classes": ("collapse",)}),
        ("Metadata", {"fields": ("last_sync_at", "created_at", "updated_at")}),
    )

    readonly_fields = ["last_sync_at", "created_at", "updated_at"]


@admin.register(SurveyTemplateMapping)
class SurveyTemplateMappingAdmin(admin.ModelAdmin):
    """Survey template mapping admin"""

    list_display = ["hospital", "patient_type", "survey_template", "is_active"]
    list_filter = ["hospital", "patient_type", "is_active"]
    search_fields = ["hospital__name", "survey_template__name"]
    ordering = ["hospital", "patient_type"]

    fieldsets = (
        ("Mapping Configuration", {"fields": ("hospital", "patient_type", "survey_template")}),
        ("Settings", {"fields": ("is_active",)}),
        ("Metadata", {"fields": ("created_at", "updated_at")}),
    )

    readonly_fields = ["created_at", "updated_at"]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.select_related("hospital", "survey_template")


class HISVisitEventInline(admin.TabularInline):
    model = HISVisitEvent
    extra = 0
    fields = ["event_type", "bill_date", "parsed_date", "visit_category"]
    readonly_fields = ["event_type", "bill_date", "parsed_date", "visit_category"]
    show_change_link = False


@admin.register(HISPatientVisit)
class HISPatientVisitAdmin(admin.ModelAdmin):
    """HIS patient visit admin"""

    list_display = [
        "patient",
        "patient_type",
        "admission_id",
        "hospital",
        "is_visit_complete",
        "survey_linked",
        "discharge_date",
        "last_his_fetch_at",
    ]
    list_filter = ["patient_type", "is_visit_complete", "hospital"]
    search_fields = ["admission_id", "reg_code", "patient_id_his", "patient__first_name", "patient__last_name"]
    ordering = ["-last_his_fetch_at"]
    date_hierarchy = "last_his_fetch_at"
    inlines = [HISVisitEventInline]

    fieldsets = (
        (
            "Patient & Hospital",
            {"fields": ("patient", "hospital", "admission_id", "reg_code", "patient_id_his", "patient_type")},
        ),
        ("Visit Dates", {"fields": ("admit_date", "discharge_date", "effective_discharge_date")}),
        ("Status", {"fields": ("is_visit_complete", "survey_instance", "last_his_fetch_at")}),
        ("HIS Data", {"fields": ("visit_data", "visit_timeline"), "classes": ("collapse",)}),
        ("Doctor & Consultant", {"fields": ("primary_doctor", "consultant_id", "primary_doctor_fk", "consultant_fk")}),
        ("Insurance & Billing", {"fields": ("company_name", "grade_name", "insurance_company_name", "bill_type")}),
        ("VIP & Nationality", {"fields": ("is_vip", "nationality")}),
        ("Timestamps", {"fields": ("created_at", "updated_at")}),
    )

    readonly_fields = ["created_at", "updated_at"]

    def survey_linked(self, obj):
        if obj.survey_instance:
            return format_html(
                '<a href="/admin/surveys/surveyinstance/{}/">{}</a>', obj.survey_instance.id, obj.survey_instance.id
            )
        return mark_safe('<span class="badge bg-secondary">None</span>')

    survey_linked.short_description = "Survey"

    def has_add_permission(self, request):
        return False


@admin.register(HISVisitEvent)
class HISVisitEventAdmin(admin.ModelAdmin):
    """HIS visit event admin"""

    list_display = ["visit", "event_type", "bill_date", "parsed_date", "visit_category", "admission_id"]
    list_filter = ["visit_category", "patient_type"]
    search_fields = ["admission_id", "patient_id", "event_type"]
    ordering = ["-parsed_date"]
    date_hierarchy = "parsed_date"

    fieldsets = (
        ("Visit", {"fields": ("visit",)}),
        ("Event Details", {"fields": ("event_type", "bill_date", "parsed_date", "visit_category")}),
        (
            "Patient Info",
            {"fields": ("patient_type", "admission_id", "patient_id", "reg_code", "ssn", "mobile_no")},
        ),
        ("Timestamps", {"fields": ("created_at", "updated_at")}),
    )

    readonly_fields = ["created_at", "updated_at"]

    def has_add_permission(self, request):
        return False


@admin.register(HISEventType)
class HISEventTypeAdmin(admin.ModelAdmin):
    """HIS event type admin - auto-populated from HIS data"""

    list_display = ["event_type", "patient_types_display", "event_count", "last_seen_at"]
    search_fields = ["event_type"]
    ordering = ["event_type"]
    list_filter = ["last_seen_at"]

    readonly_fields = ["event_type", "patient_types", "event_count", "last_seen_at", "created_at", "updated_at"]

    def has_add_permission(self, request):
        return False

    def patient_types_display(self, obj):
        if not obj.patient_types:
            return mark_safe('<span class="badge bg-secondary">None</span>')
        return ", ".join(obj.patient_types)

    patient_types_display.short_description = "Patient Types"


@admin.register(EventMapping)
class EventMappingAdmin(admin.ModelAdmin):
    """Event mapping admin"""

    list_display = ["integration_config", "external_event_code", "internal_event_code", "is_active"]
    list_filter = ["integration_config", "is_active"]
    search_fields = ["external_event_code", "internal_event_code"]
    ordering = ["integration_config", "external_event_code"]

    fieldsets = (
        (None, {"fields": ("integration_config", "external_event_code", "internal_event_code")}),
        ("Field Mappings", {"fields": ("field_mappings",), "classes": ("collapse",)}),
        ("Configuration", {"fields": ("is_active",)}),
        ("Metadata", {"fields": ("created_at", "updated_at")}),
    )

    readonly_fields = ["created_at", "updated_at"]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.select_related("integration_config")


@admin.register(HISTestPatient)
class HISTestPatientAdmin(admin.ModelAdmin):
    list_display = ["admission_id", "patient_name", "patient_type", "hospital_name", "admit_date", "discharge_date"]
    list_filter = ["patient_type", "hospital_name"]
    search_fields = ["admission_id", "patient_id", "ssn", "mobile_no", "patient_name"]
    ordering = ["-admit_date"]
    date_hierarchy = "admit_date"
    readonly_fields = ["created_at", "updated_at"]

    def has_add_permission(self, request):
        return False


@admin.register(HISTestVisit)
class HISTestVisitAdmin(admin.ModelAdmin):
    list_display = ["admission_id", "visit_category", "event_type", "bill_date"]
    list_filter = ["visit_category", "event_type"]
    search_fields = ["admission_id", "patient_id"]
    ordering = ["-bill_date"]
    date_hierarchy = "bill_date"
    readonly_fields = ["created_at", "updated_at"]

    def has_add_permission(self, request):
        return False


@admin.register(ExternalAPIKey)
class ExternalAPIKeyAdmin(admin.ModelAdmin):
    """Admin for External API Keys - shows the plaintext key ONLY on creation."""

    list_display = ["name", "key_prefix", "hospital", "is_active", "allowed_entities_display", "last_used_at", "created_at"]
    list_filter = ["is_active", "hospital"]
    search_fields = ["name", "key_prefix", "description"]
    ordering = ["-created_at"]
    readonly_fields = ["key_hash", "key_prefix", "last_used_at", "created_at", "updated_at"]

    fieldsets = (
        (
            "Identity",
            {"fields": ("name", "description", "key_prefix", "key_hash")},
        ),
        (
            "Scope",
            {"fields": ("hospital", "allowed_entities", "rate_limit")},
        ),
        (
            "Status",
            {"fields": ("is_active", "expires_at", "last_used_at")},
        ),
        (
            "Metadata",
            {"fields": ("created_by", "created_at", "updated_at")},
        ),
    )

    def allowed_entities_display(self, obj):
        if not obj.allowed_entities:
            return mark_safe('<span class="badge bg-success">All Entities</span>')
        return ", ".join(obj.allowed_entities)

    allowed_entities_display.short_description = "Allowed Entities"

    def save_model(self, request, obj, form, change):
        if not change:
            # Creating a new key — generate it
            obj.created_by = request.user
            obj.save()

            # Store the raw key to show in admin message
            # We need to generate the key ourselves since save_model doesn't return it
            import secrets
            import hashlib
            raw_key = secrets.token_hex(32)
            obj.key_prefix = raw_key[:8]
            obj.key_hash = hashlib.sha256(raw_key.encode()).hexdigest()
            obj.save(update_fields=["key_prefix", "key_hash"])

            self._generated_key = raw_key
        else:
            obj.save()

    def response_add(self, request, obj, post_url_continue=None):
        resp = super().response_add(request, obj, post_url_continue)
        if hasattr(self, "_generated_key"):
            from django.contrib import messages
            messages.success(
                request,
                f'API Key created. Copy it now — it will NOT be shown again: {self._generated_key}',
            )
            # Clear it
            del self._generated_key
        return resp
