import streamlit as st
from dotenv import load_dotenv
import pickle
from PyPDF2 import PdfReader
from streamlit_extras.add_vertical_space import add_vertical_space
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain
from langchain.callbacks import get_openai_callback
import os

# Sidebar contents
with st.sidebar:
    st.title(':orange[BinDoc GmbH]')
    st.markdown(
        "Experience the future of document interaction with the revolutionary"
    )

    st.markdown("**BinDocs Chat App**.")

        
    st.markdown("Harnessing the power of a Large Language Model and AI technology,")
       


    st.markdown("this innovative platform redefines PDF engagement,")

    st.markdown("enabling dynamic conversations that bridge the gap between")
    st.markdown("human and machine intelligence.")

    
    
    add_vertical_space(3)  # Add more vertical space between text blocks
    st.write('Made with ❤️ by Anne')

load_dotenv()

def load_pdf(file_path):
    pdf_reader = PdfReader(file_path)
    text = ""
    for page in pdf_reader.pages:
        text += page.extract_text()

    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )
    chunks = text_splitter.split_text(text=text)

    store_name = file_path.name[:-4]

    if os.path.exists(f"{store_name}.pkl"):
        with open(f"{store_name}.pkl", "rb") as f:
            VectorStore = pickle.load(f)
    else:
        embeddings = OpenAIEmbeddings()
        VectorStore = FAISS.from_texts(chunks, embedding=embeddings)
        with open(f"{store_name}.pkl", "wb") as f:
            pickle.dump(VectorStore, f)

    return VectorStore

def load_chatbot():
    return load_qa_chain(llm=OpenAI(), chain_type="stuff")

def main():
    st.title("BinDocs Chat App")

    pdf = st.file_uploader("Upload your PDF", type="pdf")

    if "chat_history" not in st.session_state:
        st.session_state['chat_history'] = []

    if "current_input" not in st.session_state:
        st.session_state['current_input'] = ""

    if "processing_input" not in st.session_state:
        st.session_state['processing_input'] = ""

    display_chat_history(st.session_state['chat_history'])

    st.write("<!-- Start Spacer -->", unsafe_allow_html=True)
    st.write("<div style='flex: 1;'></div>", unsafe_allow_html=True)
    st.write("<!-- End Spacer -->", unsafe_allow_html=True)

    if pdf is not None:
        query = st.text_input("Ask questions about your PDF file (in any preferred language):", value=st.session_state['current_input'])

        if query != st.session_state['current_input']:
            st.session_state['current_input'] = query

        if st.button("Ask"):
            st.session_state['processing_input'] = st.session_state['current_input']
            st.session_state['chat_history'].append(("User", st.session_state['processing_input'], "new"))

            loading_message = st.empty()
            loading_message.text('Bot is thinking...')

            VectorStore = load_pdf(pdf)
            chain = load_chatbot()
            docs = VectorStore.similarity_search(query=st.session_state['processing_input'], k=3)
            with get_openai_callback() as cb:
                response = chain.run(input_documents=docs, question=st.session_state['processing_input'])

            # Display the bot's response immediately using JavaScript
            st.write(f"<div id='response' style='background-color: #caf; padding: 10px; border-radius: 10px; margin: 10px;'>Bot: {response}</div>", unsafe_allow_html=True)
            st.write("<script>document.getElementById('response').scrollIntoView();</script>", unsafe_allow_html=True)

            loading_message.empty()

        # Mark all messages as old after displaying
        st.session_state['chat_history'] = [(sender, msg, "old") for sender, msg, _ in st.session_state['chat_history']]


def display_chat_history(chat_history):
    for chat in chat_history:
        background_color = "#FFA07A" if chat[2] == "new" else "#acf" if chat[0] == "User" else "#caf"
        st.markdown(f"<div style='background-color: {background_color}; padding: 10px; border-radius: 10px; margin: 10px;'>{chat[0]}: {chat[1]}</div>", unsafe_allow_html=True)

if __name__ == "__main__":
    main()