from telegram.ext import (
    CallbackQueryHandler,
    ConversationHandler,
    MessageHandler,
    filters,
)


class HandlerMaker:
    def __init__(self):
        self.handler = None
        self.kwargs = {}
        self.filters = None
        self.callback = None

    def build(self):
        attrs = self.__dict__.copy()
        self.handler = attrs.get('_handler')
        forced_keys = attrs.get('_forced_keys', [])
        replace = attrs.get('_replace', {})
        extra_args = attrs.get('kwargs', {})

        # Clean up internal attributes
        for internal in ['_handler', 'handler', '_forced_keys', '_replace', 'kwargs']:
            attrs.pop(internal, None)

        # Validate required keys
        for key in forced_keys:
            if attrs.get(key) is None:
                raise ValueError(f'Required parameter {key} not set')

        # Process attributes
        for key, value in attrs.items():
            if not key.startswith('_'):
                target_key = replace.get(key, key)
                self.kwargs[target_key] = value

        self.kwargs.update(extra_args)
        # print(self.kwargs)
        return self.handler(**self.kwargs)


class QH(HandlerMaker):
    def __init__(self):
        super().__init__()
        self._exact_match = True
        self._handler = CallbackQueryHandler
        self._replace = {'filters': 'pattern'}
        self._forced_keys = ['callback', 'filters']


class MH(HandlerMaker):
    def __init__(self):
        super().__init__()
        self._handler = MessageHandler
        self._forced_keys = ['callback', 'filters']

from typing import (
    Any,
    Optional,
)


class Conversation:
    @staticmethod
    def make(name: str, entry_points: list | QH | MH | Any,
             states: Optional[list[QH | MH | Any]] = None,
             fallbacks: Optional[list | QH | MH | Any] = None,
             kwargs: dict[str, Any] = {}):
        if type(states) == type(None):
            return entry_points
        else:
            new_states = {}
            if not isinstance(states, list):
                states = [states]
            for i, state in enumerate(states):
                if not isinstance(states, list):
                    state = [state]
                new_states[f"{name}_{i}"] = state

            if type(fallbacks) == type(None):
                fallbacks = []
            if "allow_reentry" not in kwargs:
                kwargs['allow_reentry'] = True
            return [ConversationHandler(
                entry_points=entry_points,
                states = new_states,
                fallbacks=fallbacks,
                **kwargs
            )]
