import calibre_plugins.ai_custom_tag_extractor.config as cfg
import calibre_plugins.ai_custom_tag_extractor.api.anything_llm_api as AllmAPI
import json

#PROMPT_ENGINEERING = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_PROMPT_ENGINEERING]
#SUMMARY_ENGINEERING = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_SUMMARY_ENGINEERING]

'''
if PROMPT_MODE == "Accuracy":
    try:
        ADVANCED_QUESTIONS = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_ADVANCED_QUESTIONS]
    except Exception as e:
        ADVANCED_QUESTIONS = []
'''

## for debugging
DEBUG_ALLM = False

class AnythingLLM():
    
    def __init__(self, progress_reporter=False):
        
        self.abort = False
        self.AI_PLATFORM = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_AI_PLATFORM]
        self.API_URL = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_PLATFORM_URL] + '/api/v1'
        self.API_KEY = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_PLATFORM_API_KEY]
        self.WORKSPACE = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_PLATFORM_WORKSPACE]
        
        self.PROMPT_ENGINEERING = ''
        self.SUMMARY_ENGINEERING = ''
        self.PROMPT_MODE = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_PROMPT_MODE]
        self.CONTEXT_MODE = cfg.plugin_prefs[cfg.STORE_NAME][cfg.KEY_CONTEXT_MODE]
        
        ## instanciate the API
        self._API = AllmAPI.AnythingLLM_API(self.API_URL, self.API_KEY, self.WORKSPACE, self.CONTEXT_MODE, progress_reporter)
    
    def abort_thread(self, status=True):
        self.abort = status
        self._API.abort_process()
        return
    
    def authenticate(self):
        return self._API.authenticate()

    def ask_ai_single_prompt(self,file_name,prompts):
        ## send the prompt in one go
        PAYLOAD = {}
        prompt_string = ''
        prompt_structure = ''
        for pid in prompts:
            prompt_string = prompt_string + "I require a field '"+ prompts[pid]['label'] +"': " + prompts[pid]['prompt'] + ". "
            prompt_structure = prompt_structure + "\""+ prompts[pid]['label'] +"\": \"\","
        if prompt_structure != '':
            prompt_structure = "{ "+ prompt_structure +" }"
        PAYLOAD['message'] = f"Please analyse the book '{file_name}' for information. {prompt_string}. Provide the structure as a single string field — do not split it into multiple fields or sections. Return only the required field. Return the response in Json Format, only provide the Json as the Response. If you cannot find the information for the field, simply return Not Available. Use this structure: "+ prompt_structure +".".replace("   ","").replace("  ","")
        PAYLOAD['mode'] = "query"
        PAYLOAD['userId'] = 1
        PAYLOAD['reset'] = 'false'
        
        return self._API.send_ai_question(PAYLOAD, file_name, "")

    def ask_ai_multiple_questions(self,file_name,prompts):
        returned_dict = {}
        prompt_string = ''
        ## the mode is accuracy, break the prompt into individual questions and ask them one by one to maximise RAG efficiency
        for pid in prompts:
            prompt_string = "I require a field '"+ prompts[pid]['label'] +"': " + prompts[pid]['prompt']
            PAYLOAD = {}
            PAYLOAD['message'] = "Please analyse the book '"+ file_name + "' for information. "+ prompt_string +". Provide the structure as a single string field — do not split it into multiple fields or sections. Return only the required field. Return the response in Json Format, only provide the Json as the Response. If you cannot find the information for the field, simply return Not Available. Use this structure: {"+ '"' + prompts[pid]['label'] + '": ""' + " }.".replace("   ","").replace("  ","")
            PAYLOAD['mode'] = "query"
            PAYLOAD['userId'] = 1
            PAYLOAD['reset'] = 'false'
            
            returned_payload = self._API.send_ai_question(PAYLOAD, file_name, prompts[pid]['prompt'])
            if returned_payload != None:
                returned_dict = {**returned_dict, **returned_payload}
            if self.abort:
                break
                
        return returned_dict
        
    def ask_ai_questions(self,file_name,prompts):
        
        if self.PROMPT_MODE == "Efficiency":
            return self.ask_ai_single_prompt(file_name,prompts)
        else:
            return self.ask_ai_multiple_questions(file_name,prompts)
    
    def delete_threads(self):
        self._API.delete_threads()
    
    def send_chat_message_to_ai(self,ebook_location,prompts):       
        # check see if the workplace exists
        if self._API.check_workspace_exists() and self.abort == False:
            # upload the document
            if self._API.upload_document_to_workspace(ebook_location) and self.abort == False:
                
                if self.abort == False:
                    ## ask the a.i. bot the questions on the document
                    file_name = self._API.strip_filename_from_path(ebook_location)
                    returned_dict = self.ask_ai_questions(file_name,prompts)
                
                if DEBUG_ALLM != True:
                    ## if we have got the data we now cleanup
                    self._API.cleanup()
            
                return returned_dict
            else:
                return
        else:
            return
#authenticate()
