import asyncio
from typing import Optional, Callable
from datetime import datetime, timedelta

from .config import Config


class MessageService:
    def __init__(self, config: Config):
        self.config = config
        self.pending_recalls: dict[str, list[asyncio.Task]] = {}

    async def send_with_recall(
        self,
        scope: str,
        message_type: str,
        send_func: Callable,
        *args,
        **kwargs,
    ) -> Optional[str]:
        """Send message and schedule recall if configured."""
        try:
            message_id = await send_func(*args, **kwargs)
            if not message_id:
                return None

            recall_time = self.config.MESSAGE_RECALL.get(message_type, 0)
            if recall_time > 0:
                task = asyncio.create_task(
                    self._schedule_recall(scope, message_id, recall_time, send_func)
                )
                if scope not in self.pending_recalls:
                    self.pending_recalls[scope] = []
                self.pending_recalls[scope].append(task)

            return message_id
        except Exception as e:
            return None

    async def _schedule_recall(
        self,
        scope: str,
        message_id: str,
        delay: int,
        recall_func: Callable,
    ):
        """Schedule message recall."""
        try:
            await asyncio.sleep(delay)
            await recall_func(message_id)
        except Exception:
            pass

    def clear_pending_recalls(self, scope: str):
        """Cancel all pending recall tasks for a scope."""
        if scope in self.pending_recalls:
            for task in self.pending_recalls[scope]:
                if not task.done():
                    task.cancel()
            del self.pending_recalls[scope]

    def clear_all_recalls(self):
        """Cancel all pending recall tasks."""
        for scope in list(self.pending_recalls.keys()):
            self.clear_pending_recalls(scope)
