from enum import Enum
from typing import Callable

class Task(Enum):
    INSTALL = 0
    REMOVE = 1
    UPDATE = 2
    UNKNOWN = 100

    @classmethod
    def from_str(cls, s: str):
        return cls[s.upper()]

    def to_str(self) -> str:
        return self.name


class Action:
    def __init__(self):
        self.package_id: str = ""
        self.app_name: str = ""
        self.manager_id: str = ""
        self.running: bool = False
        self.task: Task = Task.UNKNOWN
        self._progress: int = 0
        self.progress_trigger: Callable = None
        self.error: str = ""
        self.status: str = ""
        self.background: bool = False
        self.failure_kind: str = ""
        self.can_export_logs: bool = False
        self.tags: list[str] = []

    @property
    def progress(self) -> int:
        return self._progress

    @progress.setter
    def progress(self, value: int):
        self._progress = value
        if self.progress_trigger is not None:
            self.progress_trigger(value)

    def notification_message(self) -> str:
        match self.task:
            case Task.INSTALL:
                return f"Installing {self.app_name}"
            case Task.REMOVE:
                return f"Removing {self.app_name}"
            case Task.UPDATE:
                return f"Updating {self.app_name}"
            case Task.UNKNOWN:
                return f"Unknown task for {self.app_name}"

    def to_dict(self) -> dict:  # NEEDED FOR DBUS
        return {
            "package_id": self.package_id,
            "app_name": self.app_name,
            "manager_id": self.manager_id,
            "task": self.task.to_str(),
            "progress": str(self.progress),
            "error": self.error,
            "background": str(self.background),
            "status": self.status,
            "failure_kind": self.failure_kind,
            "can_export_logs": str(self.can_export_logs),
            "running": str(self.running),
            "tags": self.tags,
        }

    @classmethod
    def from_dict(cls, data: dict):
        action = cls()
        action.package_id = str(data["package_id"])
        action.app_name = str(data["app_name"])
        action.manager_id = str(data["manager_id"])
        action.task = Task.from_str(str(data["task"]))
        action.background = str(data.get("background", "False")).lower() == "true"
        action.progress = int(data.get("progress", "0"))
        action.error = str(data.get("error", ""))
        action.status = str(data.get("status", ""))
        action.failure_kind = str(data.get("failure_kind", ""))
        action.can_export_logs = str(data.get("can_export_logs", "False")).lower() == "true"
        action.running = str(data.get("running", "False")).lower() == "true"
        raw_tags = data.get("tags", [])
        if isinstance(raw_tags, str):
            raw_tags = [tag for tag in raw_tags.split(",") if tag]
        action.tags = [str(tag) for tag in raw_tags]

        return action
