import json
import logging

from langchain_core.language_models import BaseChatModel

from ceo.action.action import Action
from ceo.prompt.prompt import Prompt

log = logging.getLogger('ceo.prompt')


class AnalyserPrompt(Prompt):
    def __init__(self, query: str, prev_results: list, action: Action, ext_context: str = ''):
        self.action = action
        prev_results_str = str()
        prompt = str()
        if len(prev_results) > 0:
            prev_results_str += '\n'
        for result in prev_results:
            prev_results_str += f'{result};\n'
        parameters_str = '{'
        for key, clazz in action.parameters.items():
            parameters_str += f'"{key}"(paramName):"{clazz}"(paramDataType),'
        parameters_str += '}'
        prompt += ('Precondition: Below is the tool you can use (you can only use this tool). '
                   f'Now there is a user query: "{query}"\n'
                   'Task: What you need to do is to generate values of parameters of the function\n'
                   'Output format: {param1_name:param1_value, param2_name:param2_value, ...} '
                   '(Parameters are given below at [!!!Parameters provided!!!], values are gonna be generated by you, '
                   'strictly abide by the parameter name and type)\n'
                   "(You must not generate any nonexistent parameter, "
                   "look carefully at parameters which are provided below at [!!!Parameters provided!!!]!)\n"
                   'Example output: {"param1": "value1", "param2": "value2"} '
                   '(With not any redundant information, only a json)\n'
                   f'Tool: {action}\n'
                   f'!!!Parameters provided!!!: {parameters_str}\n')
        if len(prev_results_str) != 0:
            prompt += (f'Generate response according to previous actions performed by you.\n'
                       f'Previous actions: {prev_results_str}\n'
                       f'What [previous actions] has shown is what you have done until now. '
                       f'What you need to do now is to think seriously what you have not done yet '
                       f'according to the [user query].\n')
        else:
            prompt += 'This is your first step, no previous actions have been performed.\n'
        super().__init__(prompt, ext_context)
        log.debug(f'AnalyserPrompt: {self.prompt}')

    def invoke(self, model: BaseChatModel) -> tuple[Action, dict]:
        result = model.invoke(self.prompt).content
        param = json.loads(result)
        return self.action, param
