"""Delete protection — prevents deletion of entities that are in use.

Each check function returns a list of consumer descriptions. If non-empty,
the entity cannot be deleted.
"""

from fastapi import HTTPException, status
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession

from ..database.models import (
    CommandConfig,
    CommandTracker,
    CommandTrackerListener,
    NotificationTarget,
    NotificationTracker,
    NotificationTrackerTarget,
)


def raise_if_used(consumers: list[str], entity_name: str) -> None:
    """Raise 409 Conflict if the entity has consumers.

    Produces a human-readable summary string (kept as the primary ``detail``)
    plus a structured ``blocked_by`` list so the frontend can render a
    clickable warning modal.
    """
    if consumers:
        summary = f"Cannot delete {entity_name}: used by {len(consumers)} consumer(s)."
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail={
                "message": summary,
                "entity": entity_name,
                "blocked_by": consumers,
            },
        )


async def check_service_provider(session: AsyncSession, provider_id: int) -> list[str]:
    """Check if a ServiceProvider is used by any trackers."""
    consumers = []
    result = await session.exec(
        select(NotificationTracker).where(NotificationTracker.provider_id == provider_id)
    )
    for t in result.all():
        consumers.append(f"Notification Tracker: {t.name}")
    result = await session.exec(
        select(CommandTracker).where(CommandTracker.provider_id == provider_id)
    )
    for t in result.all():
        consumers.append(f"Command Tracker: {t.name}")
    return consumers


async def check_telegram_bot(session: AsyncSession, bot_id: int) -> list[str]:
    """Check if a TelegramBot is used by any targets or command listeners."""
    consumers = []
    # Check notification targets with this bot in config
    result = await session.exec(
        select(NotificationTarget).where(NotificationTarget.type == "telegram")
    )
    for t in result.all():
        if t.config.get("bot_id") == bot_id:
            consumers.append(f"Target: {t.name}")
    # Check command tracker listeners
    result = await session.exec(
        select(CommandTrackerListener).where(
            CommandTrackerListener.listener_type == "telegram_bot",
            CommandTrackerListener.listener_id == bot_id,
        )
    )
    for listener in result.all():
        tracker = await session.get(CommandTracker, listener.command_tracker_id)
        name = tracker.name if tracker else f"#{listener.command_tracker_id}"
        consumers.append(f"Command Tracker Listener: {name}")
    return consumers


async def check_email_bot(session: AsyncSession, bot_id: int) -> list[str]:
    """Check if an EmailBot is used by any targets."""
    consumers = []
    result = await session.exec(
        select(NotificationTarget).where(NotificationTarget.type == "email")
    )
    for t in result.all():
        if t.config.get("email_bot_id") == bot_id:
            consumers.append(f"Target: {t.name}")
    return consumers


async def check_matrix_bot(session: AsyncSession, bot_id: int) -> list[str]:
    """Check if a MatrixBot is used by any targets."""
    consumers = []
    result = await session.exec(
        select(NotificationTarget).where(NotificationTarget.type == "matrix")
    )
    for t in result.all():
        if t.config.get("matrix_bot_id") == bot_id:
            consumers.append(f"Target: {t.name}")
    return consumers


async def check_tracking_config(session: AsyncSession, config_id: int) -> list[str]:
    """Check if a TrackingConfig is used by any tracker-target links."""
    consumers = []
    result = await session.exec(
        select(NotificationTrackerTarget).where(
            NotificationTrackerTarget.tracking_config_id == config_id
        )
    )
    for tt in result.all():
        tracker = await session.get(NotificationTracker, tt.tracker_id)
        target = await session.get(NotificationTarget, tt.target_id)
        tracker_name = tracker.name if tracker else f"#{tt.tracker_id}"
        target_name = target.name if target else f"#{tt.target_id}"
        consumers.append(f"Tracker Link: {tracker_name} → {target_name}")
    return consumers


async def check_template_config(session: AsyncSession, config_id: int) -> list[str]:
    """Check if a TemplateConfig is used by any tracker-target links."""
    consumers = []
    result = await session.exec(
        select(NotificationTrackerTarget).where(
            NotificationTrackerTarget.template_config_id == config_id
        )
    )
    for tt in result.all():
        tracker = await session.get(NotificationTracker, tt.tracker_id)
        target = await session.get(NotificationTarget, tt.target_id)
        tracker_name = tracker.name if tracker else f"#{tt.tracker_id}"
        target_name = target.name if target else f"#{tt.target_id}"
        consumers.append(f"Tracker Link: {tracker_name} → {target_name}")
    return consumers


async def check_command_template_config(session: AsyncSession, config_id: int) -> list[str]:
    """Check if a CommandTemplateConfig is used by any command configs."""
    consumers = []
    result = await session.exec(
        select(CommandConfig).where(
            CommandConfig.command_template_config_id == config_id
        )
    )
    for c in result.all():
        consumers.append(f"Command Config: {c.name}")
    return consumers


async def check_command_config(session: AsyncSession, config_id: int) -> list[str]:
    """Check if a CommandConfig is used by any command trackers."""
    consumers = []
    result = await session.exec(
        select(CommandTracker).where(CommandTracker.command_config_id == config_id)
    )
    for t in result.all():
        consumers.append(f"Command Tracker: {t.name}")
    return consumers


async def check_notification_target(session: AsyncSession, target_id: int) -> list[str]:
    """Check if a NotificationTarget is used by any tracker-target links."""
    consumers = []
    result = await session.exec(
        select(NotificationTrackerTarget).where(
            NotificationTrackerTarget.target_id == target_id
        )
    )
    for tt in result.all():
        tracker = await session.get(NotificationTracker, tt.tracker_id)
        name = tracker.name if tracker else f"#{tt.tracker_id}"
        consumers.append(f"Notification Tracker: {name}")
    return consumers


