"""
批量操作 Mixin
"""
import asyncio
from typing import Optional, Callable, Any, TYPE_CHECKING
from contextlib import asynccontextmanager

from loguru import logger

if TYPE_CHECKING:
    from ..tab import Tab


class BatchMixin:
    """批量操作功能"""

    # 这些属性由其他 mixin 或 core 定义
    _tabs: dict[str, "Tab"]
    _current_tab: Optional[str]

    async def parallel_action(
        self,
        action: Callable[["Tab"], Any],
        tab_ids: Optional[list[str]] = None,
    ) -> dict[str, Any]:
        """
        在多个标签页并行执行操作

        Args:
            action: 操作函数
            tab_ids: 标签页ID列表，默认所有标签页

        Returns:
            dict: {tab_id: result}
        """
        tab_ids = tab_ids or list(self._tabs.keys())

        logger.info(f"并行执行操作: tabs={tab_ids}")

        async def run_action(tab_id: str):
            tab = self._tabs[tab_id]
            try:
                if asyncio.iscoroutinefunction(action):
                    return tab_id, await action(tab)
                else:
                    return tab_id, action(tab)
            except Exception as e:
                logger.error(f"并行操作失败: tab={tab_id}, error={e}")
                return tab_id, e

        results = await asyncio.gather(*[run_action(tid) for tid in tab_ids])
        return dict(results)

    async def sequential_action(
        self,
        action: Callable[["Tab"], Any],
        tab_ids: Optional[list[str]] = None,
    ) -> dict[str, Any]:
        """
        在多个标签页顺序执行操作

        Args:
            action: 操作函数
            tab_ids: 标签页ID列表

        Returns:
            dict: {tab_id: result}
        """
        tab_ids = tab_ids or list(self._tabs.keys())
        results = {}

        logger.info(f"顺序执行操作: tabs={tab_ids}")

        for tab_id in tab_ids:
            tab = self._tabs[tab_id]
            try:
                if asyncio.iscoroutinefunction(action):
                    results[tab_id] = await action(tab)
                else:
                    results[tab_id] = action(tab)
            except Exception as e:
                logger.error(f"顺序操作失败: tab={tab_id}, error={e}")
                results[tab_id] = e

        return results

    @asynccontextmanager
    async def tab_context(self, name: Optional[str] = None):
        """
        标签页上下文管理器

        Args:
            name: 标签页名称

        Yields:
            Tab: 新标签页
        """
        tab = await self.new_tab(name)
        old_tab = self._current_tab
        self._current_tab = tab.id

        try:
            yield tab
        finally:
            self._current_tab = old_tab
            await self.close_tab(tab.id)
