from __future__ import annotations
import os
import traceback


from . import strategy
from .. import stage, entities
import langbot_plugin.api.entities.builtin.platform.message as platform_message
from ...utils import importutil
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
from . import strategies

importutil.import_modules_in_pkg(strategies)


@stage.stage_class('LongTextProcessStage')
class LongTextProcessStage(stage.PipelineStage):
    """Long message processing stage

    Rewrite:
        - resp_message_chain
    """

    strategy_impl: strategy.LongTextStrategy | None

    async def initialize(self, pipeline_config: dict):
        config = pipeline_config['output']['long-text-processing']

        if config['strategy'] == 'none':
            self.strategy_impl = None
            return

        if config['strategy'] == 'image':
            use_font = config['font-path']
            try:
                # 检查是否存在
                if not os.path.exists(use_font):
                    # 若是windows系统，使用微软雅黑
                    if os.name == 'nt':
                        use_font = 'C:/Windows/Fonts/msyh.ttc'
                        if not os.path.exists(use_font):
                            self.ap.logger.warn(
                                'Font file not found, and Windows system font cannot be used, switch to forward message component to send long messages, you can adjust the related settings in the configuration file.'
                            )
                            config['blob_message_strategy'] = 'forward'
                        else:
                            self.ap.logger.info('Using Windows system font: ' + use_font)
                            config['font-path'] = use_font
                    else:
                        self.ap.logger.warn(
                            'Font file not found, and system font cannot be used, switch to forward message component to send long messages, you can adjust the related settings in the configuration file.'
                        )

                        pipeline_config['output']['long-text-processing']['strategy'] = 'forward'
            except Exception:
                traceback.print_exc()
                self.ap.logger.error(
                    'Failed to load font file ({}), switch to forward message component to send long messages, you can adjust the related settings in the configuration file.'.format(
                        use_font
                    )
                )

                pipeline_config['output']['long-text-processing']['strategy'] = 'forward'

        for strategy_cls in strategy.preregistered_strategies:
            if strategy_cls.name == config['strategy']:
                self.strategy_impl = strategy_cls(self.ap)
                break
        else:
            raise ValueError(f'Long message processing strategy not found: {config["strategy"]}')

        await self.strategy_impl.initialize()

    async def process(self, query: pipeline_query.Query, stage_inst_name: str) -> entities.StageProcessResult:
        if self.strategy_impl is None:
            self.ap.logger.debug('Long message processing strategy is not set, skip long message processing.')
            return entities.StageProcessResult(result_type=entities.ResultType.CONTINUE, new_query=query)

        if not query.resp_message_chain:
            self.ap.logger.debug('Response message chain is empty, skip long message processing.')
            return entities.StageProcessResult(result_type=entities.ResultType.CONTINUE, new_query=query)

        # 检查是否包含非 Plain 组件
        contains_non_plain = False

        for msg in query.resp_message_chain[-1]:
            if not isinstance(msg, platform_message.Plain):
                contains_non_plain = True
                break

        if contains_non_plain:
            self.ap.logger.debug('Message contains non-Plain components, skip long message processing.')
        elif (
            len(str(query.resp_message_chain[-1]))
            > query.pipeline_config['output']['long-text-processing']['threshold']
        ):
            query.resp_message_chain[-1] = platform_message.MessageChain(
                await self.strategy_impl.process(str(query.resp_message_chain[-1]), query)
            )

        return entities.StageProcessResult(result_type=entities.ResultType.CONTINUE, new_query=query)
