from domain.injector.value_object import TaskModelActionValue, TaskStatusValue
from apollo.settings import CDN_PLATFORM_ID_LIST


class TaskQueryStrategy:

    def get_query_type(self):
        raise NotImplementedError("子类必须实现 apply 方法")

    def apply(self, query_dict, value):
        raise NotImplementedError("子类必须实现 apply 方法")

    @classmethod
    def run_all_plugins(cls):
        child_classes = cls.__subclasses__()
        sorted_classes = sorted(child_classes, key=lambda c: c.priority)
        strategy_map = {}
        for subclass in sorted_classes:
            instance = subclass()
            strategy_map[instance.get_query_type()] = instance
        return strategy_map


class PartnerIdStrategy(TaskQueryStrategy):
    """合作方id查询策略"""
    priority = 2

    def get_query_type(self):
        return "partner_id"

    def apply(self, query_dict, value):
        if value:
            query_dict['partner_id'] = value
        return query_dict


class MediaNameStrategy(TaskQueryStrategy):
    """存储id查询策略"""
    priority = 3

    def get_query_type(self):
        return "storage_name"

    def apply(self, query_dict, value):
        if value:
            query_dict["media__name__icontains"] = value
        return query_dict


class TaskStatusStrategy(TaskQueryStrategy):
    priority = 1

    def get_query_type(self):
        return "task_status"

    def apply(self, query_dict, value):
        if value:
            query_dict["status"] = value
            if int(value) == 94:
                # 表示查的是remark 完成状态 分发失败
                query_dict["status"] = 23
                query_dict["remark__icontains"] = "分发失败"
                query_dict["partner_id__in"] = CDN_PLATFORM_ID_LIST
            elif int(value) == 93:
                # 表示未分发
                query_dict["status"] = 23
                query_dict["remark__icontains"] = "SUCCESS"
                query_dict["partner_id__in"] = CDN_PLATFORM_ID_LIST
        return query_dict


class LSPIdStrategy(TaskQueryStrategy):
    """LSP id查询策略"""
    priority = 4

    def get_query_type(self):
        return "lsp_ids"

    def apply(self, query_dict, value):
        if value:
            query_dict["partner_id__in"] = value
        return query_dict


class StorageNumStrategy(TaskQueryStrategy):
    """存储编号查询策略"""
    priority = 6

    def get_query_type(self):
        return "nums"

    def apply(self, query_dict, value):
        if value:
            query_dict["episode__serial_num__in"] = value.split(",")
        return query_dict


class QueryActionStrategy(TaskQueryStrategy):
    """存储编号查询策略"""
    priority = 7

    def get_query_type(self):
        return "action"

    def apply(self, query_dict, value):
        if value:
            value = TaskModelActionValue.REGISTER if value == "register" else TaskModelActionValue.DELETE
            query_dict["action"] = value
        return query_dict


class QueryGoalStrategy(TaskQueryStrategy):
    """存储编号查询策略"""
    priority = 8

    def get_query_type(self):
        return "goal"

    def apply(self, query_dict, value):
        if value and "status" not in query_dict:
            if value == "success":
                query_dict["status"] = TaskStatusValue.INFO_COMPLETED
            elif value == "fail":
                query_dict["status__in"] = TaskStatusValue.failed()
            elif value == "injecting":
                query_dict["status__in"] = (TaskStatusValue.TRANS_CODE_PENDING, TaskStatusValue.TRANS_CODE_COMPLETED,
                                            TaskStatusValue.TRANS_CODE_TRANSFERING, TaskStatusValue.FILE_PENDING,
                                            TaskStatusValue.FILE_TRANSFERING, TaskStatusValue.INFO_PENDING,
                                            TaskStatusValue.INFO_TRANSFERING)
        return query_dict


# TaskSearch_Strategy_Map = {
#     "partner_id": PartnerIdStrategy(),
#     "storage_name": MediaNameStrategy(),
#     "task_status": TaskStatusStrategy(),
#     "lsp_ids": LSPIdStrategy(),
#     "nums": StorageNumStrategy(),
#     "action": QueryActionStrategy(),
#     "goal": QueryGoalStrategy(),
# }


class TaskQueryStrategyFactory:
    """任务查询策略工厂"""

    TaskSearch_Strategy_Map = TaskQueryStrategy.run_all_plugins()

    @classmethod
    def register_strategy(cls, param_name, strategy):
        cls.TaskSearch_Strategy_Map[param_name] = strategy

    @classmethod
    def build(cls, params: dict):
        query_dict = {}
        for key, value in params.items():
            if value is None or value == '':
                continue
            strategy = cls.TaskSearch_Strategy_Map[key]
            strategy.apply(query_dict, value)

        return query_dict
