from django.contrib import admin
from django.db.models import Sum
from unfold.admin import ModelAdmin, TabularInline
from unfold.decorators import display

from core.admin_ui import PortalAdminMixin
from core.status_palette import ASSET_STATUS_LABELS, BACKUP_STATUS_LABELS, SERVER_STATUS_LABELS
from .models import BackupRecord, DatabaseAsset, Server, TechnicalAsset


class DatabaseInline(TabularInline):
    model = DatabaseAsset
    extra = 0
    tab = True


class BackupInline(TabularInline):
    model = BackupRecord
    extra = 0
    fields = ("backup_type", "backup_date", "status", "verified_at")
    tab = True


@admin.register(Server)
class ServerAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "dns"
    portal_kicker = "INFRAESTRUTURA"
    portal_description = "Inventário de servidores, localizações, painéis de controlo e referências seguras de acesso."
    portal_tone = "navy"
    portal_stats = (
        {"label": "Servidores", "icon": "dns", "tone": "primary", "caption": "Infraestrutura total"},
        {"label": "Ativos", "icon": "dns", "tone": "success", "filters": {"status": Server.Status.ACTIVE}, "caption": "Em produção"},
        {"label": "Em manutenção", "icon": "build", "tone": "warning", "filters": {"status": Server.Status.MAINTENANCE}, "caption": "Intervenção planeada"},
        {"label": "Desativados", "icon": "power_settings_new", "tone": "neutral", "filters": {"status": Server.Status.RETIRED}, "caption": "Fora de serviço"},
    )
    portal_related_links = (
        {"label": "Ativos técnicos", "icon": "developer_board", "url_name": "admin:technical_technicalasset_changelist"},
        {"label": "Alojamentos", "icon": "cloud", "url_name": "admin:hosting_hostingaccount_changelist"},
        {"label": "Backups", "icon": "backup", "url_name": "admin:technical_backuprecord_changelist"},
    )

    list_display = ("name", "provider", "hostname", "ip_address", "control_panel", "show_status")
    list_filter = ("status", "provider", "control_panel")
    search_fields = ("name", "hostname", "ip_address", "location")
    autocomplete_fields = ("provider",)
    list_fullwidth = True
    readonly_fields = ("public_id", "created_at", "updated_at")
    fieldsets = (
        ("Servidor", {"fields": ("name", "provider", "status", "location"), "description": "Identificação, fornecedor e estado operacional."}),
        ("Rede e painel", {"fields": ("hostname", "ip_address", "control_panel", "panel_url"), "description": "Dados técnicos de ligação ao servidor."}),
        ("Acesso seguro", {"fields": ("account_reference",), "description": "Indique apenas a referência do cofre; nunca guarde passwords."}),
        ("Notas", {"fields": ("notes",)}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Estado", label=SERVER_STATUS_LABELS, ordering="status")
    def show_status(self, obj):
        return obj.get_status_display()


@admin.register(TechnicalAsset)
class TechnicalAssetAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "developer_board"
    portal_kicker = "INFRAESTRUTURA"
    portal_description = "Ficha técnica dos websites, contas, certificados, pastas, CMS e verificações de cada serviço."
    portal_tone = "cyan"
    portal_stats = (
        {"label": "Ativos técnicos", "icon": "developer_board", "tone": "primary", "caption": "Inventário total"},
        {"label": "Ativos", "icon": "check_circle", "tone": "success", "filters": {"status": TechnicalAsset.Status.ACTIVE}, "caption": "Sem alertas"},
        {"label": "Requerem atenção", "icon": "warning", "tone": "danger", "filters": {"status": TechnicalAsset.Status.ATTENTION}, "caption": "Intervenção necessária"},
        {"label": "Sem SSL", "icon": "lock_open", "tone": "warning", "filters": {"ssl_active": False}, "caption": "Rever segurança"},
    )
    portal_related_links = (
        {"label": "Servidores", "icon": "dns", "url_name": "admin:technical_server_changelist"},
        {"label": "Bases de dados", "icon": "database", "url_name": "admin:technical_databaseasset_changelist"},
        {"label": "Backups", "icon": "backup", "url_name": "admin:technical_backuprecord_changelist"},
    )

    list_display = ("label", "service", "asset_type", "server", "domain_name", "ssl_active", "show_status", "last_checked_at")
    list_filter = ("asset_type", "status", "server", "ssl_active", "cms")
    search_fields = ("label", "service__name", "service__client__name", "domain_name", "document_root", "subdomain", "cms")
    autocomplete_fields = ("service", "server")
    readonly_fields = ("public_id", "created_at", "updated_at")
    inlines = (DatabaseInline, BackupInline)
    list_fullwidth = True
    fieldsets = (
        ("Ativo", {"fields": ("service", "server", "asset_type", "label", "status"), "description": "Identificação e relação com o serviço e servidor."}),
        ("Website e localização", {"fields": ("domain_name", "document_root", "subdomain"), "description": "Endereços e caminhos usados na infraestrutura."}),
        ("Tecnologia", {"fields": ("php_version", "cms", "cms_version", "ssl_active"), "description": "Versões, CMS e estado do certificado SSL."}),
        ("Verificação", {"fields": ("last_checked_at", "notes"), "description": "Última revisão e notas técnicas relevantes."}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Estado", label=ASSET_STATUS_LABELS, ordering="status")
    def show_status(self, obj):
        return obj.get_status_display()


@admin.register(DatabaseAsset)
class DatabaseAssetAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "database"
    portal_kicker = "INFRAESTRUTURA"
    portal_description = "Bases de dados associadas aos ativos técnicos, respetivos motores, tamanhos e referências seguras."
    portal_tone = "violet"
    portal_stats = (
        {"label": "Bases de dados", "icon": "database", "tone": "primary", "caption": "Total registado"},
        {"label": "MySQL / MariaDB", "icon": "storage", "tone": "primary", "filters": {"engine": DatabaseAsset.Engine.MYSQL}, "caption": "Motor mais comum"},
        {"label": "PostgreSQL", "icon": "storage", "tone": "violet", "filters": {"engine": DatabaseAsset.Engine.POSTGRES}, "caption": "Bases PostgreSQL"},
        {"label": "Espaço registado", "icon": "data_usage", "tone": "success", "method": "sum_size", "caption": "Tamanho conhecido"},
    )
    portal_related_links = (
        {"label": "Ativos técnicos", "icon": "developer_board", "url_name": "admin:technical_technicalasset_changelist"},
    )

    list_display = ("name", "technical_asset", "engine", "size_mb")
    list_filter = ("engine",)
    search_fields = ("name", "technical_asset__label", "technical_asset__service__client__name")
    autocomplete_fields = ("technical_asset",)
    list_fullwidth = True
    readonly_fields = ("public_id", "created_at", "updated_at")
    fieldsets = (
        ("Base de dados", {"fields": ("technical_asset", "name", "engine", "size_mb")}),
        ("Referência e notas", {"fields": ("username_reference", "notes"), "description": "Não guardar passwords; apenas a referência do cofre."}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    def sum_size(self, request, queryset):
        total = queryset.aggregate(total=Sum("size_mb"))["total"] or 0
        return f"{total:.2f} MB"


@admin.register(BackupRecord)
class BackupRecordAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "backup"
    portal_kicker = "INFRAESTRUTURA"
    portal_description = "Registe a criação, localização, dimensão, verificação e eventuais falhas dos backups."
    portal_tone = "green"
    portal_stats = (
        {"label": "Backups", "icon": "backup", "tone": "primary", "caption": "Histórico total"},
        {"label": "Verificados", "icon": "verified", "tone": "success", "filters": {"status": BackupRecord.Status.VERIFIED}, "caption": "Restauro confirmado"},
        {"label": "Por verificar", "icon": "manage_search", "tone": "warning", "filters": {"status": BackupRecord.Status.CREATED}, "caption": "A validar"},
        {"label": "Falharam", "icon": "backup_table", "tone": "danger", "filters": {"status": BackupRecord.Status.FAILED}, "caption": "Requer intervenção"},
    )
    portal_related_links = (
        {"label": "Ativos técnicos", "icon": "developer_board", "url_name": "admin:technical_technicalasset_changelist"},
        {"label": "Tarefas", "icon": "task_alt", "url_name": "admin:operations_internaltask_changelist"},
    )

    list_display = ("technical_asset", "backup_type", "backup_date", "size_mb", "show_status", "verified_at")
    list_filter = ("backup_type", "status", "backup_date")
    search_fields = ("technical_asset__label", "technical_asset__service__client__name", "location_reference")
    autocomplete_fields = ("technical_asset",)
    list_fullwidth = True
    readonly_fields = ("public_id", "created_at", "updated_at")
    fieldsets = (
        ("Backup", {"fields": ("technical_asset", "backup_type", "backup_date", "status")}),
        ("Ficheiro e validação", {"fields": ("location_reference", "size_mb", "verified_at"), "description": "Localização segura e confirmação de que o backup é utilizável."}),
        ("Notas", {"fields": ("notes",)}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Estado", label=BACKUP_STATUS_LABELS, ordering="status")
    def show_status(self, obj):
        return obj.get_status_display()


from django.utils import timezone
from core.status_palette import (
    SSL_STATUS_LABELS,
    WORDPRESS_HEALTH_LABELS,
    WORDPRESS_PLUGIN_STATUS_LABELS,
    WORDPRESS_SECURITY_LABELS,
)
from .models import SSLCertificate, WordPressPlugin, WordPressSite, WordPressTheme


class WordPressPluginInline(TabularInline):
    model = WordPressPlugin
    extra = 0
    fields = ("name", "installed_version", "available_version", "activation_status", "security_status", "automatic_updates")
    tab = True
    show_change_link = True


class WordPressThemeInline(TabularInline):
    model = WordPressTheme
    extra = 0
    fields = ("name", "installed_version", "available_version", "is_active", "is_child_theme", "automatic_updates")
    tab = True
    show_change_link = True


@admin.register(WordPressSite)
class WordPressSiteAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "web"
    portal_kicker = "WORDPRESS"
    portal_description = "Versões, estado de saúde, atualizações, configurações e referências seguras dos sites WordPress."
    portal_tone = "navy"
    portal_stats = (
        {"label": "Sites WordPress", "icon": "web", "tone": "primary", "caption": "Instalações registadas"},
        {"label": "Saudáveis", "icon": "health_and_safety", "tone": "success", "filters": {"health_status": WordPressSite.HealthStatus.HEALTHY}, "caption": "Sem alertas"},
        {"label": "Requerem atenção", "icon": "warning", "tone": "warning", "filters": {"health_status": WordPressSite.HealthStatus.ATTENTION}, "caption": "Rever configuração"},
        {"label": "Críticos", "icon": "gpp_bad", "tone": "danger", "filters": {"health_status": WordPressSite.HealthStatus.CRITICAL}, "caption": "Intervenção urgente"},
    )
    portal_related_links = (
        {"label": "Plugins", "icon": "extension", "url_name": "admin:technical_wordpressplugin_changelist"},
        {"label": "Temas", "icon": "palette", "url_name": "admin:technical_wordpresstheme_changelist"},
        {"label": "Certificados SSL", "icon": "lock", "url_name": "admin:technical_sslcertificate_changelist"},
        {"label": "Ativos técnicos", "icon": "developer_board", "url_name": "admin:technical_technicalasset_changelist"},
    )
    list_display = ("technical_asset", "installed_version", "available_version", "php_version", "show_health", "show_update", "last_scan_at")
    list_filter = ("health_status", "multisite", "automatic_core_updates", "maintenance_mode", "php_version")
    search_fields = ("technical_asset__label", "technical_asset__domain_name", "technical_asset__service__client__name", "installed_version")
    autocomplete_fields = ("technical_asset",)
    readonly_fields = ("public_id", "created_at", "updated_at")
    inlines = (WordPressPluginInline, WordPressThemeInline)
    list_fullwidth = True
    fieldsets = (
        ("Instalação", {"fields": ("technical_asset", "public_url", "admin_url", "health_status"), "description": "Ativo técnico, endereços e estado geral."}),
        ("Versões", {"fields": ("installed_version", "available_version", "php_version"), "description": "Versões registadas manualmente ou por futuras sincronizações."}),
        ("Configuração", {"fields": ("multisite", "wp_cron_enabled", "automatic_core_updates", "debug_mode", "maintenance_mode")}),
        ("Segurança", {"fields": ("credentials_reference",), "description": "Guarde apenas uma referência do cofre de credenciais."}),
        ("Verificação", {"fields": ("last_updated_at", "last_scan_at", "notes")}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Saúde", label=WORDPRESS_HEALTH_LABELS, ordering="health_status")
    def show_health(self, obj):
        return obj.get_health_status_display()

    @display(description="Atualização", label=True)
    def show_update(self, obj):
        return ("Atualização disponível", "warning") if obj.update_required else ("Atualizado", "success")


@admin.register(WordPressPlugin)
class WordPressPluginAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "extension"
    portal_kicker = "WORDPRESS"
    portal_description = "Inventário de plugins, versões, atualizações automáticas, licenças e alertas de segurança."
    portal_tone = "violet"
    portal_stats = (
        {"label": "Plugins", "icon": "extension", "tone": "primary", "caption": "Inventário total"},
        {"label": "Ativos", "icon": "toggle_on", "tone": "success", "filters": {"activation_status": WordPressPlugin.ActivationStatus.ACTIVE}, "caption": "Em utilização"},
        {"label": "Vulneráveis", "icon": "bug_report", "tone": "danger", "filters": {"security_status": WordPressPlugin.SecurityStatus.VULNERABLE}, "caption": "Atualização urgente"},
        {"label": "Licenças", "icon": "license", "tone": "warning", "filters": {"premium": True}, "caption": "Plugins premium"},
    )
    portal_related_links = (
        {"label": "Sites WordPress", "icon": "web", "url_name": "admin:technical_wordpresssite_changelist"},
        {"label": "Temas", "icon": "palette", "url_name": "admin:technical_wordpresstheme_changelist"},
    )
    list_display = ("name", "wordpress_site", "installed_version", "available_version", "show_activation", "show_security", "show_update", "license_expires_on")
    list_filter = ("activation_status", "security_status", "automatic_updates", "premium", "license_expires_on")
    search_fields = ("name", "slug", "wordpress_site__technical_asset__domain_name", "wordpress_site__technical_asset__service__client__name", "provider")
    autocomplete_fields = ("wordpress_site",)
    readonly_fields = ("public_id", "created_at", "updated_at")
    list_fullwidth = True
    fieldsets = (
        ("Plugin", {"fields": ("wordpress_site", "name", "slug", "activation_status")}),
        ("Versões e atualização", {"fields": ("installed_version", "available_version", "automatic_updates", "security_status", "last_checked_at")}),
        ("Licença", {"fields": ("premium", "provider", "license_reference", "license_expires_on"), "description": "Não guarde chaves de licença em texto simples; utilize uma referência do cofre."}),
        ("Notas", {"fields": ("notes",)}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Estado", label=WORDPRESS_PLUGIN_STATUS_LABELS, ordering="activation_status")
    def show_activation(self, obj):
        return obj.get_activation_status_display()

    @display(description="Segurança", label=WORDPRESS_SECURITY_LABELS, ordering="security_status")
    def show_security(self, obj):
        return obj.get_security_status_display()

    @display(description="Atualização", label=True)
    def show_update(self, obj):
        return ("Disponível", "warning") if obj.update_required else ("Atualizado", "success")


@admin.register(WordPressTheme)
class WordPressThemeAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "palette"
    portal_kicker = "WORDPRESS"
    portal_description = "Temas ativos, temas filho, versões, atualizações e licenças por instalação WordPress."
    portal_tone = "cyan"
    portal_stats = (
        {"label": "Temas", "icon": "palette", "tone": "primary", "caption": "Inventário total"},
        {"label": "Ativos", "icon": "check_circle", "tone": "success", "filters": {"is_active": True}, "caption": "Tema em utilização"},
        {"label": "Temas filho", "icon": "account_tree", "tone": "primary", "filters": {"is_child_theme": True}, "caption": "Personalizações seguras"},
        {"label": "Premium", "icon": "workspace_premium", "tone": "warning", "filters": {"premium": True}, "caption": "Licenças a controlar"},
    )
    portal_related_links = (
        {"label": "Sites WordPress", "icon": "web", "url_name": "admin:technical_wordpresssite_changelist"},
        {"label": "Plugins", "icon": "extension", "url_name": "admin:technical_wordpressplugin_changelist"},
    )
    list_display = ("name", "wordpress_site", "installed_version", "available_version", "is_active", "is_child_theme", "show_update", "license_expires_on")
    list_filter = ("is_active", "is_child_theme", "automatic_updates", "premium", "license_expires_on")
    search_fields = ("name", "slug", "parent_theme", "wordpress_site__technical_asset__domain_name", "provider")
    autocomplete_fields = ("wordpress_site",)
    readonly_fields = ("public_id", "created_at", "updated_at")
    list_fullwidth = True
    fieldsets = (
        ("Tema", {"fields": ("wordpress_site", "name", "slug", "is_active", "is_child_theme", "parent_theme")}),
        ("Versões", {"fields": ("installed_version", "available_version", "automatic_updates", "last_checked_at")}),
        ("Licença", {"fields": ("premium", "provider", "license_reference", "license_expires_on")}),
        ("Notas", {"fields": ("notes",)}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Atualização", label=True)
    def show_update(self, obj):
        return ("Disponível", "warning") if obj.update_required else ("Atualizado", "success")


@admin.register(SSLCertificate)
class SSLCertificateAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "lock"
    portal_kicker = "SEGURANÇA TÉCNICA"
    portal_description = "Validade, emissor, domínios abrangidos, renovação automática e erros dos certificados SSL."
    portal_tone = "green"
    portal_stats = (
        {"label": "Certificados", "icon": "lock", "tone": "primary", "caption": "Total registado"},
        {"label": "Válidos", "icon": "verified_user", "tone": "success", "filters": {"status": SSLCertificate.Status.VALID}, "caption": "Sem alertas"},
        {"label": "A expirar", "icon": "schedule", "tone": "warning", "filters": {"status": SSLCertificate.Status.EXPIRING}, "caption": "Renovar em breve"},
        {"label": "Inválidos", "icon": "gpp_bad", "tone": "danger", "filters": {"status__in": [SSLCertificate.Status.EXPIRED, SSLCertificate.Status.INVALID, SSLCertificate.Status.REVOKED]}, "caption": "Intervenção urgente"},
    )
    portal_related_links = (
        {"label": "Ativos técnicos", "icon": "developer_board", "url_name": "admin:technical_technicalasset_changelist"},
        {"label": "Sites WordPress", "icon": "web", "url_name": "admin:technical_wordpresssite_changelist"},
    )
    list_display = ("primary_domain", "technical_asset", "issuer", "certificate_type", "expires_at", "show_days", "show_status", "automatic_renewal")
    list_filter = ("status", "certificate_type", "automatic_renewal", "validation_method", "expires_at")
    search_fields = ("primary_domain", "covered_domains", "issuer", "technical_asset__service__client__name")
    autocomplete_fields = ("technical_asset",)
    readonly_fields = ("public_id", "created_at", "updated_at")
    list_fullwidth = True
    fieldsets = (
        ("Certificado", {"fields": ("technical_asset", "primary_domain", "covered_domains", "status")}),
        ("Emissão e validade", {"fields": ("issuer", "certificate_type", "issued_at", "expires_at", "automatic_renewal", "validation_method")}),
        ("Verificação", {"fields": ("last_checked_at", "error_message", "notes")}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    @display(description="Estado", label=SSL_STATUS_LABELS, ordering="status")
    def show_status(self, obj):
        return obj.get_status_display()

    @display(description="Dias", label=True)
    def show_days(self, obj):
        days = obj.days_remaining
        if days is None:
            return "Por confirmar", "info"
        if days < 0:
            return "Expirado", "danger"
        if days <= 30:
            return f"{days} dias", "warning"
        return f"{days} dias", "success"
