## chatGPT with Gradio 起手式
## 在你的資料夾新增 .env 檔案,並在裡面寫入 API_KEY=你的API金鑰
import os
import openai
import gradio as gr
from zhdate import ZhDate
from datetime import datetime

'''
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key = os.environ['OPENAI_API_KEY']
print(openai.api_key)
if openai.api_key:
   DESKTOP_KEY = openai.api_key 
print(DESKTOP_KEY)
'''

# 定義地支對應的時間區間
z_mapping = {
        "1": "子",
        "2": "丑",
        "3": "寅",
        "4": "卯",
        "5": "辰",
        "6": "巳",
        "7": "午",
        "8": "未",
        "9": "申",
        "10": "酉",
        "11": "戌",
        "12": "亥",
        "0": "夜子"
    } 

## AI 建議
def get_advice(bmi,temp, API_KEY, model="gpt-3.5-turbo"):
    if API_KEY:
        openai.api_key = API_KEY
    else:
        openai.api_key = DESKTOP_KEY
    print(openai.api_key)
    bmi = '' #未來再說
    gw_main_star = '像一個獨裁霸道的君王,無法聽進別人的意見'
    gw_main_star = '像一個足智多謀的軍師,ㄧ有時候會考慮太多而失去前進的勇氣'

    messages = [{"role": "system", "content": "你是一個心理權威,你會根據用戶的個性,提供至少3個,不超過5個建議。"},
                {"role": "user", "content": f'我的個性是 {gw_main_star}. 針對這樣的個性,妳可否給我一些待人處事的建議?'},]
    response = openai.chat.completions.create(
        model=model,
        max_tokens=1000,
        messages=messages,
        temperature=temp, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message.content

## 健身計畫
def get_gym(bmi,slide, temp, API_KEY, model="gpt-3.5-turbo"):
    if API_KEY:
        openai.api_key = API_KEY
    else:
        openai.api_key = DESKTOP_KEY
    print(openai.api_key)
    messages = [{"role": "system", "content": "You are a great fitness coach and \
                 you will give users great fitness plans."},
                {"role": "user", "content": f'My BMI is {bmi}. I want a {slide}-point weight\
                  loss plan, from 1 to 10. The higher the number, the faster the weight loss.'},]
    response = openai.chat.completions.create(
        model=model,
        max_tokens=200,
        messages=messages,
        temperature=temp, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message.content

def GWAI(year, month, day, btime) -> datetime:
    dt_date1 = datetime(int(year), int(month), int(day))
    date_lunar = ZhDate.from_datetime(dt_date1)
    bstr = str(date_lunar)
    
    hour = int(btime.split(":")[0])
    if hour >= 23:
        z = 0
    else:
        z = int(hour / 2) + 1
    result=z_mapping[str(z)]
    return bstr.replace('农历','農曆') + " " + result + "時"



# 建立 components
year = gr.Textbox(
    label="生年",
    info="輸入你的西元出生年份",
    placeholder="Input your birth year here...")

month = gr.Textbox(
    label="生月",
    info="輸入你的出生月份",
    placeholder="Input your birthday month here...",)

day = gr.Textbox(
    label="生日",
    info="輸入你的出生日子",
    placeholder="Input your birthday day here...",)

btime = gr.Textbox(
    label="生時",
    info="輸入你的出生時間 HH:MM (幾點及約略幾分即可,請用24小時制)",
    placeholder="Input your birth time here...",)

sex = gr.Textbox(
    label="性別",
    info="輸入你是男生或女生",
    placeholder="Input you are male or female here...",)

output_gwai = gr.Textbox(
    value="",
    label="你的農曆生日及出生時辰",
    info="這是從西元換算出的農曆生日及出生時辰",
    placeholder="Date & Time")

advice = gr.Textbox(
    label="AI Advice",
    info="請選擇以下按鈕讓AI 根據你的BMI值給予的建議",
    placeholder="Ouput Text here...",
    lines=5,)

btn = gr.Button(
    value="計算農曆生日及八字時辰",
    variant="primary", scale=1)

btn_advice  = gr.Button(
    value="AI 紫微的人生建議",
    variant="primary", scale=2)

btn_gym = gr.Button(
    value="AI 紫微聊天室",
    variant="primary", scale=1)

key_box = gr.Textbox(
    label="輸入你的 API 金鑰",
    info="You have to provide your own OPENAI_API_KEY for this app to function properly",
    placeholder="Type OpenAI API KEY here...",
    type="password")


slider = gr.Slider(
    minimum=1,
    maximum=10,
    step=1,
    label="減重速度",
    value=5,
    info="請選擇你的減重速度,數字越大,減重越快",
    )

temperature = gr.Slider(
    minimum=0,
    maximum=1.0,
    value=0.3,
    step=0.05,
    label="Temperature",
    info=(
        "Temperature controls the degree of randomness in token selection. Lower "
        "temperatures are good for prompts that expect a true or correct response, "
        "while higher temperatures can lead to more diverse or unexpected results. "
    ),
)

with gr.Blocks() as demo:
    gr.Markdown("""
    # AI 紫微
    起手式 - 轉換西元生日到農曆出生時辰
    """)
    with gr.Column():
        with gr.Row():
            year.render()  # 顯示年
            month.render() # 顯示月
            day.render() # 顯示日
            btime.render() # 顯示時
            sex.render() # 顯示性別
        
        with gr.Row():
            output_gwai.render() # 顯示農曆生日欄

        btn.render() # 顯示農曆生日值結果
        btn.click(fn=GWAI, 
                     inputs=[year, month, day, btime], 
                     outputs=[output_gwai])

        advice.render() # 顯示AI建議結果的文字框
        
        with gr.Row(): 
            key_box.render() # 顯示API金鑰輸入框
            btn_advice.render() # 顯示AI建議按鈕
            btn_advice.click(fn=get_advice, inputs=[output_gwai,temperature,key_box], outputs=advice)
            btn_gym.render() # 顯示AI健身計畫按鈕
            btn_gym.click(fn=get_gym, inputs=[output_gwai,slider,temperature, key_box], outputs=advice)
    
        with gr.Accordion("settings", open=True):
            slider.render()
            temperature.render()

demo.launch()