from abc import ABC
from typing import List, Type

from ..enums import ScenarioName, SegmentType
from ..exceptions import UnknownScenario


class BaseScenario(ABC):
    name: ScenarioName
    segments: List[SegmentType]

    @classmethod
    def to_dict(cls):
        return dict(name=cls.name, segments=cls.segments)


class DiscountForLostScenario(BaseScenario):
    name: ScenarioName = ScenarioName.DISCOUNT_FOR_LOST
    segments: List[SegmentType] = [SegmentType.LOST]


class EngageProspectiveScenario(BaseScenario):
    name: ScenarioName = ScenarioName.ENGAGE_PROSPECTIVE
    segments: List[SegmentType] = [SegmentType.NO_ORDERS, SegmentType.PROSPECTIVE]


class ThankTheLoyalScenario(BaseScenario):
    name: ScenarioName = ScenarioName.THANK_THE_LOYAL
    segments: List[SegmentType] = [SegmentType.LOYAL]


class DiscountForDisloyalScenario(BaseScenario):
    name: ScenarioName = ScenarioName.DISCOUNT_FOR_DISLOYAL
    segments: List[SegmentType] = [SegmentType.DISLOYAL]


def find_scenario_by_name(name: ScenarioName) -> Type[BaseScenario]:
    candidates = filter(lambda el: el.name == name, BaseScenario.__subclasses__())

    try:
        return next(candidates)
    except StopIteration:
        raise UnknownScenario(name)
