from typing import Optional
from analogai.foundation.common.enums.deontic_modality import DeonticModality
from analogai.foundation.common.utils.time_utils import Tense


class DeonticFormatter:
    
    @staticmethod
    def format_deontic_phrase(
        deontic_modality: Optional[DeonticModality],
        tense: Tense = Tense.PRESENT
    ) -> str:
        if deontic_modality is None:
            return ""
        
        strategy = DeonticPhraseStrategyFactory.create(deontic_modality, tense)
        return strategy.format()
    
    @staticmethod
    def format_deontic_prefix(
        deontic_modality: Optional[DeonticModality],
        tense: Tense = Tense.PRESENT
    ) -> str:
        if deontic_modality is None:
            return ""
        
        strategy = DeonticPrefixStrategyFactory.create(deontic_modality, tense)
        return strategy.format()


class DeonticPhraseStrategy:
    def format(self) -> str:
        raise NotImplementedError


class DeonticPrefixStrategy:
    def format(self) -> str:
        raise NotImplementedError


class ObligatoryPastStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it was obligatory"


class ObligatoryPresentStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it is obligatory"


class ObligatoryFutureStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it will be obligatory"


class PermittedPastStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it was permitted"


class PermittedPresentStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it is permitted"


class PermittedFutureStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it will be permitted"


class ForbiddenPastStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it was not allowed to"


class ForbiddenPresentStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it is not allowed to"


class ForbiddenFutureStrategy(DeonticPhraseStrategy):
    def format(self) -> str:
        return "it will not be allowed to"


class ObligatoryPastPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "had to"


class ObligatoryPresentPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "must"


class ObligatoryFuturePrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "will have to"


class PermittedPastPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "was allowed to"


class PermittedPresentPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "can"


class PermittedFuturePrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "will be allowed to"


class ForbiddenPastPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "was not allowed to"


class ForbiddenPresentPrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "can not"


class ForbiddenFuturePrefixStrategy(DeonticPrefixStrategy):
    def format(self) -> str:
        return "will not be allowed to"


class DeonticPhraseStrategyFactory:
    _strategies = {
        (DeonticModality.OBLIGATORY, Tense.PAST): lambda: ObligatoryPastStrategy(),
        (DeonticModality.OBLIGATORY, Tense.PRESENT): lambda: ObligatoryPresentStrategy(),
        (DeonticModality.OBLIGATORY, Tense.FUTURE): lambda: ObligatoryFutureStrategy(),
        (DeonticModality.PERMITTED, Tense.PAST): lambda: PermittedPastStrategy(),
        (DeonticModality.PERMITTED, Tense.PRESENT): lambda: PermittedPresentStrategy(),
        (DeonticModality.PERMITTED, Tense.FUTURE): lambda: PermittedFutureStrategy(),
        (DeonticModality.FORBIDDEN, Tense.PAST): lambda: ForbiddenPastStrategy(),
        (DeonticModality.FORBIDDEN, Tense.PRESENT): lambda: ForbiddenPresentStrategy(),
        (DeonticModality.FORBIDDEN, Tense.FUTURE): lambda: ForbiddenFutureStrategy(),
    }
    
    @staticmethod
    def create(deontic_modality: DeonticModality, tense: Tense) -> DeonticPhraseStrategy:
        key = (deontic_modality, tense)
        strategy_factory = DeonticPhraseStrategyFactory._strategies.get(key)
        if strategy_factory:
            return strategy_factory()
        return ObligatoryPresentStrategy()


class DeonticPrefixStrategyFactory:
    _strategies = {
        (DeonticModality.OBLIGATORY, Tense.PAST): lambda: ObligatoryPastPrefixStrategy(),
        (DeonticModality.OBLIGATORY, Tense.PRESENT): lambda: ObligatoryPresentPrefixStrategy(),
        (DeonticModality.OBLIGATORY, Tense.FUTURE): lambda: ObligatoryFuturePrefixStrategy(),
        (DeonticModality.PERMITTED, Tense.PAST): lambda: PermittedPastPrefixStrategy(),
        (DeonticModality.PERMITTED, Tense.PRESENT): lambda: PermittedPresentPrefixStrategy(),
        (DeonticModality.PERMITTED, Tense.FUTURE): lambda: PermittedFuturePrefixStrategy(),
        (DeonticModality.FORBIDDEN, Tense.PAST): lambda: ForbiddenPastPrefixStrategy(),
        (DeonticModality.FORBIDDEN, Tense.PRESENT): lambda: ForbiddenPresentPrefixStrategy(),
        (DeonticModality.FORBIDDEN, Tense.FUTURE): lambda: ForbiddenFuturePrefixStrategy(),
    }
    
    @staticmethod
    def create(deontic_modality: DeonticModality, tense: Tense) -> DeonticPrefixStrategy:
        key = (deontic_modality, tense)
        strategy_factory = DeonticPrefixStrategyFactory._strategies.get(key)
        if strategy_factory:
            return strategy_factory()
        return ObligatoryPresentPrefixStrategy()


__all__ = ["DeonticFormatter"]
