from typing import List

from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.llms import OpenAI

from load_model import call_palm
from calling_apis import google_api_key, openai_api_key

def article_generator(idea : str, outline : str, section : str, tone_of_voice : str, language='En', model_name='Google Palm 2', creativity='Original') -> str:
    
    '''
    Description

        This function generates paragraphs for an article based on provided parameters such as the main idea, outline, section, language model, and tone of voice. It utilizes a PromptTemplate and an LLMChain for content creation.

    Parameters:

        idea -> Required: (str) Represents the main idea or topic of the article.
        outline -> Required: (str) Indicates the existing outline content (if any) for the article.
        section -> Required: (str) Specifies the main point or section that requires content generation.
        tone_of_voice -> Required: (str) Defines the desired tone for the article (e.g., formal, informal, technical).
        language (str): Opitonal Parameter -> The language of the model.
        creativity (str): Optional Parameter -> Controling the randomness of the model. Default value is Original
        model_name (str): Optional Parameter -> select the LLM model. Default Value is Google Palm 2
        

    Return:
    - `article`: (str) The generated article paragraph based on the provided parameters and content prompts.
    '''
    
    temp = 0

    if creativity == 'Original':
        temp = 0
    elif creativity == 'Balanced':
        temp = 0.25
    elif creativity == 'Creative':
        temp = 0.5
    elif creativity == 'Spirited':
        temp = 0.75
    elif creativity == 'Visionary':
        temp = 1


    if model_name == 'Google Palm 2':
        llm = call_palm(google_api_key, temperature=temp)

    elif model_name == 'GPT-3.5':
        llm = OpenAI(model_name='gpt-3.5-turbo', openai_api_key=openai_api_key, temperature=temp)

    elif model_name == 'GPT-4':
        llm = OpenAI(model_name='gpt-4', openai_api_key=openai_api_key, temperature=temp)


    if language == 'En':
        
        if len(outline) == 0:
            article_prompt = f"Generate Catchy Introduction paragraph for my article on {idea} using the following main point: {section}\nThe tone should be {tone_of_voice}."
        else:
            article_prompt = f"Generate well-organized paragraph for my article on {idea}. I have already covered: {outline} in the outline. I need help with the following main point: {section}. Please ensure the paragraphs are connected logically and provide a smooth transition between main topics. The tone should be {tone_of_voice}."

        article_promptTemp = PromptTemplate(
        input_variables=["text_input"],
        template="You are a Professional content creator and article Writer:\n\n{text_input}\n\nParagraph:")
    
    elif language == 'Ar':
        
        if len(outline) == 0:
            article_prompt = f"أنشئ فقرة مثيرة للاهتمام لمقالي عن {idea} باستخدام النقطة الرئيسية التالية: {section}\nيجب أن يكون اللهجة {tone_of_voice}."
        else:
            article_prompt = f"انشئ فقرة منظمة تماماً لمقالي حول {idea}. لقد غطيت بالفعل: {outline} في الخطة العريضة. أحتاج مساعدة في النقطة الرئيسية التالية: {section}. يرجى التأكد من أن الفقرات متصلة منطقياً وتوفير انتقال سلس بين المواضيع الرئيسية. يجب أن يكون اللهجة {tone_of_voice}."

        article_promptTemp = PromptTemplate(
        input_variables=["text_input"],
        template="أنت مبدع محترف للمحتوى وكاتب مقالات:\n\n{text_input}\n\nالفقرة:")

    article_extraction_chain = LLMChain(llm=llm, prompt=article_promptTemp)
    article = article_extraction_chain.run(article_prompt)
    
    return article


def full_article(idea : str, outline_list : List[str], tone_of_voice : str, language='En', model_name='Google Palm 2', creativity='Original') -> List[str]:
    
    '''
    Description:
        This function generates a full article by iteratively creating paragraphs for each section in an outline list using the `article_generator` function. It accumulates the generated paragraphs into a list representing the complete article.

    Parameters:
        - `idea` -> Required: (str) Represents the main idea or topic of the article.
        - `outline_list` -> Required: (list) Contains sections or main points forming the outline structure of the article.
        - `tone_of_voice` -> Required: (str) Defines the desired tone for the article (e.g., formal, informal, technical).
        - `llm` -> Required: (object) Represents the language model used for generating the article content.
        language (str): Opitonal Parameter -> The language of the model.
        creativity (str): Optional Parameter -> Controling the randomness of the model. Default value is Original
        model_name (str): Optional Parameter -> select the LLM model. Default Value is Google Palm 2
        

    Return:
        - `article`: (list) A list containing paragraphs generated for each section in the `outline_list`.
    '''
    
    article = []
    outline = []
    
    try:
        
        for section in outline_list:

            para = article_generator(idea, ' '.join(outline), section, tone_of_voice, language=language, model_name=model_name, creativity=creativity)
            outline.append(section)
            article.append(para)
            
    except:
        pass
    
    return article