from __future__ import annotations
from typing import Any

from PySide6.QtCore import QObject, QTimer, QSize, QPropertyAnimation, QEasingCurve
from PySide6.QtWidgets import QTreeWidgetItem, QGraphicsOpacityEffect
from src.utils.tool_card.tool_widgets import ToolCard
from src.controller.docker_controller import DockerController, refresh_mgr


class ToolListManager(QObject):
    """
    It controls how the Docker tool list is displayed in the UI.
    """
    def __init__(self, ui: Any, tools: list[dict[str, str]]) -> None:
        super().__init__()
        self.anim = None
        self.ui = ui
        self.tools = tools
        self.setup_tool_list()

    def setup_tool_list(self) -> None:
        refresh_mgr.cache_updated.connect(self._update_all_tool_statuses)

        for tool in self.tools:
            tool_name = tool["name"]
            tool_item = QTreeWidgetItem([tool_name])
            self.ui.tools_list.addTopLevelItem(tool_item)

            card = ToolCard(tool, tool_item, self)

            DockerController.check_container_status(
                tool, tool_item, card.run_button
            )

            self.ui.tool_cards.append(card)
            self.ui.tool_details.addWidget(card)

        self.ui.tools_list.setColumnCount(1)
        self.ui.tools_list.setHeaderLabels(["Tool"])
        self.ui.tools_list.setFixedWidth(220)
        self.ui.tools_list.setIconSize(QSize(24, 24))
        self.ui.tools_list.setIndentation(10)
        self.ui.tools_list.currentItemChanged.connect(self.on_tool_selection_changed)

        # Kick off initial async refresh — non-blocking
        DockerController.refresh_cache(force=True)

        self._setup_global_timer()

    def _setup_global_timer(self) -> None:
        """
        Set up a single global timer to update all tool cards.
        """
        self._global_timer = QTimer(self)
        self._global_timer.timeout.connect(self._update_all_tool_statuses)
        self._global_timer.start(30000)

    def _update_all_tool_statuses(self) -> None:
        """
        Update the status for all tools using cached Docker data.
        """
        DockerController.refresh_cache()
        for card in self.ui.tool_cards:
            card.update_download_status()

    def on_tool_selection_changed(self, current: QTreeWidgetItem | None) -> None:
        """
        It handles the change of element selection in the tools tree
        and updates the display widget accordingly.
        """
        if current is not None:
             index = self.ui.tools_list.indexOfTopLevelItem(current)
             if index != -1:
                self.ui.tool_details.setCurrentIndex(index)
                
                # Fade-in animation for the new widget
                current_widget = self.ui.tool_details.currentWidget()
                if current_widget:
                    effect = QGraphicsOpacityEffect(current_widget)
                    current_widget.setGraphicsEffect(effect)
                    
                    self.anim = QPropertyAnimation(effect, b"opacity")
                    self.anim.setDuration(1200) # 1200ms fade-in
                    self.anim.setStartValue(0)
                    self.anim.setEndValue(1)
                    self.anim.setEasingCurve(QEasingCurve.Type.OutCubic)
                    self.anim.start()
