"""System Notification plugin — converts system events into chat messages."""

from __future__ import annotations

import logging
from typing import Any

from app.plugins.base import BasePlugin
from app.plugins.manifest import PluginManifest, FrontendSettingsPage

logger = logging.getLogger(__name__)


class SystemNotifPlugin(BasePlugin):
    """System notifications as a participant in the kommunikation plugin."""

    manifest = PluginManifest(
        name="system_notif",
        version="1.0.0",
        display_name="System Benachrichtigungen",
        description=(
            "Wandelt System-Events in Chat-Nachrichten um. "
            "Registriert sich als 'system' Teilnehmer am kommunikation Plugin."
        ),
        dependencies=["kommunikation"],
        routes=[],
        events=[
            "lead.created",
            "contact.created",
            "contact.updated",
            "task.overdue",
            "task.created",
            "mail.received",
            "user.created",
            "workflow.completed",
            "notification.created",
            "backup.completed",
            "backup.failed",
        ],
        migrations=[],
        permissions=["system_notif:read"],
        is_core=False,
        settings_pages=[
            FrontendSettingsPage(path='notifications', label_key='settings.notifications', label='Notifications', component='@/pages/SettingsNotifications', icon='Bell', order=40),
        ],
    )

    def __init__(self) -> None:
        super().__init__()
        self._system_handler = None

    async def on_activate(self, db, service_container, event_bus) -> None:
        """Register as system participant and subscribe to events."""
        await super().on_activate(db, service_container, event_bus)

        from app.plugins.builtins.system_notif.participant_handler import SystemParticipantHandler
        from app.plugins.builtins.kommunikation.participant_registry import get_participant_registry

        self._system_handler = SystemParticipantHandler(service_container)
        registry = get_participant_registry()
        registry.register("system", self._system_handler)

        logger.info("System notification plugin activated — registered as 'system' participant")

    async def on_deactivate(self, db, service_container, event_bus) -> None:
        """Unregister participant."""
        from app.plugins.builtins.kommunikation.participant_registry import get_participant_registry

        get_participant_registry().unregister("system")
        self._system_handler = None
        await super().on_deactivate(db, service_container, event_bus)
        logger.info("System notification plugin deactivated")

    # ─── Event Handlers ───

    async def on_lead_created(self, payload: dict[str, Any]) -> None:
        """Handle lead.created event → system message."""
        await self._create_system_notification(payload, event_type="lead.created")

    async def on_contact_created(self, payload: dict[str, Any]) -> None:
        """Handle contact.created event → system message."""
        await self._create_system_notification(payload, event_type="contact.created")

    async def on_contact_updated(self, payload: dict[str, Any]) -> None:
        """Handle contact.updated event → system message."""
        await self._create_system_notification(payload, event_type="contact.updated")

    async def on_task_overdue(self, payload: dict[str, Any]) -> None:
        """Handle task.overdue event → system message (warning)."""
        await self._create_system_notification(payload, event_type="task.overdue", severity="warning")

    async def on_task_created(self, payload: dict[str, Any]) -> None:
        """Handle task.created event → system message."""
        await self._create_system_notification(payload, event_type="task.created")

    async def on_mail_received(self, payload: dict[str, Any]) -> None:
        """Handle mail.received event → system message."""
        await self._create_system_notification(payload, event_type="mail.received")

    async def on_user_created(self, payload: dict[str, Any]) -> None:
        """Handle user.created event → system message."""
        await self._create_system_notification(payload, event_type="user.created")

    async def on_workflow_completed(self, payload: dict[str, Any]) -> None:
        """Handle workflow.completed event → system message."""
        await self._create_system_notification(payload, event_type="workflow.completed")

    async def on_notification_created(self, payload: dict[str, Any]) -> None:
        """Handle notification.created event → system message.

        This is the bridge from the core notification system to the kommunikation plugin.
        Core code publishes 'notification.created' on the EventBus, this plugin
        converts it into a comm_message in the user's System room.
        """
        await self._create_system_notification(payload, event_type="notification.created")

    async def on_backup_completed(self, payload: dict[str, Any]) -> None:
        """Handle backup.completed event → system message."""
        await self._create_system_notification(payload, event_type="backup.completed")

    async def on_backup_failed(self, payload: dict[str, Any]) -> None:
        """Handle backup.failed event → system message (error)."""
        await self._create_system_notification(payload, event_type="backup.failed", severity="error")

    async def _create_system_notification(
        self,
        payload: dict[str, Any],
        event_type: str,
        severity: str = "info",
    ) -> None:
        """Create a system notification message in the user's System room."""
        import uuid

        from app.core.db import create_db_session
        from app.plugins.builtins.kommunikation.services import create_plugin_room, send_message

        tenant_id_str = payload.get("tenant_id")
        user_id_str = payload.get("user_id")

        if not tenant_id_str or not user_id_str:
            logger.warning("System notification missing tenant_id or user_id in payload: %s", payload)
            return

        try:
            tenant_id = uuid.UUID(tenant_id_str)
            user_id = uuid.UUID(user_id_str)
        except (ValueError, TypeError):
            logger.warning("System notification invalid UUIDs: tenant=%s user=%s", tenant_id_str, user_id_str)
            return

        # Build notification content from payload
        title = payload.get("title", "")
        body = payload.get("body", "")
        action_url = payload.get("action_url", "")

        if not title:
            # Generate title from event type
            event_titles = {
                "lead.created": "Neuer Lead",
                "contact.created": "Neuer Kontakt",
                "contact.updated": "Kontakt aktualisiert",
                "task.overdue": "Aufgabe überfällig",
                "task.created": "Neue Aufgabe",
                "mail.received": "Neue E-Mail",
                "user.created": "Neuer Benutzer",
                "workflow.completed": "Workflow abgeschlossen",
                "notification.created": "Benachrichtigung",
                "backup.completed": "Backup erfolgreich",
                "backup.failed": "Backup fehlgeschlagen",
            }
            title = event_titles.get(event_type, event_type)

        content = f"**{title}**"
        if body:
            content += f"\n{body}"

        # Build action_card block if action_url is present
        blocks = []
        if action_url:
            blocks.append({
                "block_type": "action_card",
                "block_data": {
                    "title": title,
                    "body": body or "",
                    "actions": [
                        {"label": "Öffnen", "action": action_url, "type": "primary"},
                        {"label": "Archivieren", "action": "dismiss", "type": "secondary"},
                    ],
                },
            })

        async with create_db_session(tenant_id) as db:
            # Ensure System room exists for this user
            await create_plugin_room(
                db, tenant_id, user_id,
                plugin_name="system_notif",
                title="System",
                participant_type="system",
                user_role="reader",
            )

            # Find the System room conversation
            from sqlalchemy import select
            from app.plugins.builtins.kommunikation.models import CommConversation, CommParticipant

            result = await db.execute(
                select(CommConversation).where(
                    CommConversation.tenant_id == tenant_id,
                    CommConversation.title == "System",
                    CommConversation.is_locked == True,
                    CommConversation.locked_by == "system_notif",
                    CommConversation.deleted_at.is_(None),
                ).join(CommParticipant, CommParticipant.conversation_id == CommConversation.id).where(
                    CommParticipant.participant_id == user_id,
                    CommParticipant.participant_type == "user",
                    CommParticipant.left_at.is_(None),
                )
            )
            conv = result.scalar_one_or_none()
            if conv is None:
                logger.warning("Could not find System room for user %s", user_id)
                return

            # Send the system message
            await send_message(
                db, tenant_id, conv.id,
                sender_id=None,
                sender_type="system",
                content=content,
                content_format="markdown",
                blocks=blocks if blocks else None,
                metadata={"event_type": event_type, "severity": severity},
            )

            logger.info("System notification created: %s for user %s", event_type, user_id)

    def get_notification_types(self) -> list[dict[str, Any]]:
        return []
