"""Search provider for unified_search integration."""

from __future__ import annotations

import logging
import uuid
from typing import Any

from sqlalchemy import select, func, or_
from sqlalchemy.ext.asyncio import AsyncSession

from app.plugins.builtins.kommunikation.models import (
    CommConversation,
    CommMessage,
    CommParticipant,
)

logger = logging.getLogger(__name__)


class CommSearchProvider:
    """Provider for unified_search — searches conversations and messages."""

    async def search(
        self,
        db: AsyncSession,
        tenant_id: uuid.UUID,
        user_id: uuid.UUID,
        query: str,
        limit: int = 20,
    ) -> list[dict[str, Any]]:
        """Search in messages and conversations the user has access to."""
        results: list[dict[str, Any]] = []

        # Get user's conversation IDs
        conv_result = await db.execute(
            select(CommParticipant.conversation_id).where(
                CommParticipant.participant_id == user_id,
                CommParticipant.participant_type == "user",
                CommParticipant.left_at.is_(None),
                CommParticipant.tenant_id == tenant_id,
            )
        )
        conv_ids = [row[0] for row in conv_result.fetchall()]

        if not conv_ids:
            return results

        # Search in messages
        msg_result = await db.execute(
            select(CommMessage, CommConversation.title)
            .join(CommConversation, CommConversation.id == CommMessage.conversation_id)
            .where(
                CommMessage.conversation_id.in_(conv_ids),
                CommMessage.tenant_id == tenant_id,
                CommMessage.deleted_at.is_(None),
                CommMessage.content.ilike(f"%{query}%"),
            )
            .order_by(CommMessage.created_at.desc())
            .limit(limit)
        )

        for msg, conv_title in msg_result.fetchall():
            # Build snippet around match
            content = msg.content or ""
            idx = content.lower().find(query.lower())
            if idx >= 0:
                start = max(0, idx - 30)
                end = min(len(content), idx + len(query) + 30)
                snippet = ("..." if start > 0 else "") + content[start:end] + ("..." if end < len(content) else "")
            else:
                snippet = content[:100]

            results.append({
                "type": "message",
                "id": str(msg.id),
                "conversation_id": str(msg.conversation_id),
                "conversation_title": conv_title,
                "content": msg.content,
                "sender_type": msg.sender_type,
                "created_at": msg.created_at.isoformat() if msg.created_at else None,
                "snippet": snippet,
            })

        # Search in conversation titles
        conv_title_result = await db.execute(
            select(CommConversation).where(
                CommConversation.id.in_(conv_ids),
                CommConversation.tenant_id == tenant_id,
                CommConversation.deleted_at.is_(None),
                CommConversation.title.ilike(f"%{query}%"),
            )
            .limit(limit)
        )

        for conv in conv_title_result.scalars().all():
            results.append({
                "type": "conversation",
                "id": str(conv.id),
                "title": conv.title,
                "last_msg_at": conv.last_msg_at.isoformat() if conv.last_msg_at else None,
            })

        return results

    async def index_message(self, message: dict[str, Any]) -> None:
        """Index a message for search (placeholder for future full-text indexing)."""
        pass

    async def reindex_all(self, db: AsyncSession, tenant_id: uuid.UUID) -> None:
        """Full reindex (placeholder for future full-text indexing)."""
        pass
