from ismcore.model.processor_state import StateConfigVisual
from ismcore.processor.base_processor import BaseProcessor
from ismcore.utils.general_utils import build_template_text_v2
from ismcore.utils.ism_logger import ism_logger

logging = ism_logger(__name__)

class BaseProcessorVisual(BaseProcessor):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    @property
    def config(self) -> StateConfigVisual:
        return self.output_state.config

    @property
    def template(self):
        if self.config.template_id:
            template = self.storage.fetch_template(self.config.template_id)
            return template

        return None

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        # ensure that the configuration passed is of StateConfigLM
        if not isinstance(self.output_state.config, StateConfigVisual):
            raise ValueError(f'invalid state config, '
                             f'got {type(self.output_state.config)}, '
                             f'expected {StateConfigVisual}')

    def execute_visual(self, template: str, values: dict):
        raise NotImplementedError(f'You must implement the execute_visual(..) method')

    async def process_input_data_entry(self, input_query_state: dict, force: bool = False):
        if not input_query_state:
            return

        # build final user and system prompts using the query state entry as the input data
        template = build_template_text_v2(self.template, input_query_state)

        # begin the processing of the prompts
        try:

            # execute the underlying model function
            response, response_type, response_raw = (
                self.execute_visual(
                    template=template,
                    values=input_query_state
                )
            )

            # we build a new output state to be appended to the output states
            additional_query_state = {
                'template': template,
            }

            return await self.finalize_result(
                result=response,
                input_data=input_query_state,
                raw_output=response_raw,
                additional_query_state=additional_query_state
            )

        except Exception as exception:
            await self.fail_execute_processor_state(
                route_id=self.output_processor_state.id,
                exception=exception,
                data=input_query_state
            )
