import { useState } from 'react'
import './App.css'
import Dropdown from 'react-dropdown';
import 'react-dropdown/style.css';

function App() {
  const [prompt, setPrompt] = useState('')
  const [isLoading, setIsLoading] = useState(false)
  const [modelType,setModelType] = useState("pre")
  const [chat, setChat] = useState([])

  // Function to parse text and identify code blocks
  const parseTextWithCodeBlocks = (text) => {
    const codeBlockRegex = /```(\w+)?\s*([\s\S]+?)\s*```/g;
    const parts = [];
    let lastIndex = 0;
    let match;

    while ((match = codeBlockRegex.exec(text)) !== null) {
      // Add text before the code block
      if (match.index > lastIndex) {
        parts.push({
          type: 'text',
          content: text.slice(lastIndex, match.index)
        });
      }

      // Add the code block
      parts.push({
        type: 'code',
        language: match[1] || '',
        content: match[2]
      });

      lastIndex = match.index + match[0].length;
    }

    // Add remaining text after last code block
    if (lastIndex < text.length) {
      parts.push({
        type: 'text',
        content: text.slice(lastIndex)
      });
    }

    return parts;
  }

  const handleSubmit = async () => {
    chat.push({ src: "USER", "text": prompt })
    setIsLoading(true)

    let system_prompt = " ### "

    const res = await fetch('http://127.0.0.1:8000/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ prompt:modelType === "fine" ? prompt + system_prompt : prompt }),
    })

    const reader = res.body.getReader()
    const decoder = new TextDecoder('utf-8')

    while (true) {
      const { value, done } = await reader.read()
      if (done) break
      const chunk = decoder.decode(value)
      if (chat[chat.length - 1].src === "AI") {
        chat[chat.length - 1].text += chunk
      } else {
        chat.push({ src: "AI", text: chunk })
        chat[chat.length - 1].text = chunk
      }
      setChat([...chat])
    }
    setIsLoading(false)
    setPrompt("")
  }

  return (
    <div className='w-full flex-col gap-6 h-screen bg-white flex justify-center items-center p-4'>
      <header className='fixed top-0 left-0 p-4 flex justify-between'>
        <div className='flex gap-4'>
          <svg onClick={() => setChat([])} xmlns="http://www.w3.org/2000/svg" width="26" height="26" fill="currentColor" class="bi text-gray-700 bi-pencil-square" viewBox="0 0 16 16">
            <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" />
            <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5z" />
          </svg>
          <select value={modelType} onChange={(e)=>setModelType(e.target.value)} className='font-semibold  focus:outline-none focus:border-0 text-lg text-gray-700'>
            <option value={"pre"} selected>pre trained</option>
            <option value={"fine"} selected>fine tuned</option>
          </select>
        </div>
      </header>
      {chat.length === 0 && <h1 className='text-3xl font-bold'>What can I Help With?</h1>}
      {chat.length !== 0 &&
        <div
          className='w-screen h-[calc(100vh-6rem)] items-center justify-start flex flex-col pt-4 overflow-y-scroll'
        >
          {
            <div className='h-full w-[44rem] flex flex-col gap-3'>
              {
                chat.map((msg, index) => (
                  <div key={index} className={`${msg.src === "USER" ? 'justify-end' : 'justify-start'} flex`}>
                    <div className={`${msg.src === "USER" ? 'bg-gray-200 font-mono rounded-[2rem] w-fit px-4 py-2' : ''} p-4`}>
                      {msg.src === "AI" ? (
                        <div className="whitespace-pre-wrap">
                          {parseTextWithCodeBlocks(msg.text).map((part, i) => (
                            part.type === 'code' ? (
                              <div key={i} className="my-2">
                                <div className="bg-gray-800 text-gray-100 px-2 py-1 text-sm rounded-t-md">
                                  {part.language || 'code'}
                                </div>
                                <pre className="bg-gray-100 p-3 rounded-b-md overflow-x-auto text-sm">
                                  <code>{part.content}</code>
                                </pre>
                              </div>
                            ) : (
                              <span key={i}>{part.content}</span>
                            )
                          ))}
                        </div>
                      ) : (
                        <pre>{msg.text}</pre>
                      )}
                    </div>
                  </div>
                ))
              }
            </div>
          }
        </div>
      }
      <div className='w-[50rem] p-4 h-fit shadow-[-2px_4px_6px_0px_rgba(0,_0,_0,_0.1)] rounded-[2rem] border border-gray-300'>
        <textarea onKeyDown={(e)=>e.key === "Enter" && handleSubmit()}
          placeholder='Ask anything...'
          className='max-h-[12rem] min-h-[2rem] w-full focus:outline-none'
          value={prompt}
          onChange={e => setPrompt(e.target.value)}
        ></textarea>

        <div className='w-full flex justify-end mt-2'>
          {isLoading
            ?
            <div className='cursor-pointer rounded-full w-[34px] h-[34px] flex justify-center items-center p-2 bg-black'>
              <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-square-fill text-white" viewBox="0 0 16 16">
                <path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2z" />
              </svg>
            </div>
            :
            <svg onClick={handleSubmit} xmlns="http://www.w3.org/2000/svg" width="34" height="34" fill="currentColor" className="cursor-pointer bi bi-arrow-up-circle-fill" viewBox="0 0 16 16">
              <path d="M16 8A8 8 0 1 0 0 8a8 8 0 0 0 16 0m-7.5 3.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707z" />
            </svg>}
        </div>
      </div>
    </div>
  )
}

export default App
