import { useEffect, useState } from 'react';
import { CONFIG } from '../config';
import { getPromptGeneratePodcastScript } from '../utils/prompts';
import { getSSEStreamAsync } from '../utils/utils';

interface SplitContent {
  thought: string;
  codeBlock: string;
}

const getFromTo = (content: string, from: string, to: string): string => {
  const firstSplit = content.split(from, 2);
  if (firstSplit[1] !== undefined) {
    const secondSplit = firstSplit[1].split(to, 1);
    return secondSplit[0];
  } else {
    return '';
  }
};

const splitContent = (content: string): SplitContent => {
  return {
    thought: getFromTo(content, '<think>', '</think>').trim(),
    codeBlock: getFromTo(content, '```yaml', '```').trim(),
  };
};

export const ScriptMaker = ({
  setScript,
  setBusy,
  busy,
}: {
  setScript: (script: string) => void;
  setBusy: (busy: boolean) => void;
  busy: boolean;
}) => {
  const [input, setInput] = useState<string>('');
  const [note, setNote] = useState<string>('');
  const [thought, setThought] = useState<string>('');
  const [isGenerating, setIsGenerating] = useState<boolean>(false);

  useEffect(() => {
    setBusy(isGenerating);
  }, [isGenerating]);

  const generate = async () => {
    setIsGenerating(true);
    setThought('');
    try {
      let responseContent = '';
      const fetchResponse = await fetch(CONFIG.llmEndpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          messages: [
            {
              role: 'user',
              content: getPromptGeneratePodcastScript(input, note),
            },
          ],
          temperature: 0.3,
          stream: true,
        }),
      });
      if (fetchResponse.status !== 200) {
        const body = await fetchResponse.json();
        throw new Error(body?.error?.message || 'Unknown error');
      }
      const chunks = getSSEStreamAsync(fetchResponse);
      for await (const chunk of chunks) {
        // const stop = chunk.stop;
        if (chunk.error) {
          throw new Error(chunk.error?.message || 'Unknown error');
        }
        const addedContent = chunk.choices[0].delta.content;
        responseContent += addedContent;
        const { thought, codeBlock } = splitContent(responseContent);
        setThought(thought);
        if (codeBlock.length > 0) {
          setScript(codeBlock);
        }
      }
    } catch (error) {
      console.error(error);
      alert('Failed to generate the script. Please try again.');
    }
    setIsGenerating(false);
  };

  return (
    <div className="card bg-base-100 w-full shadow-xl">
      <div className="card-body">
        <h2 className="card-title">Step 1: Input information</h2>
        <textarea
          className="textarea textarea-bordered w-full h-72 p-2"
          placeholder="Type your input information here (an article, a document, etc)..."
          value={input}
          onChange={(e) => setInput(e.target.value)}
          disabled={isGenerating || busy}
        ></textarea>
        <textarea
          className="textarea textarea-bordered w-full h-24 p-2"
          placeholder="Optional note (the theme, tone, etc)..."
          value={note}
          onChange={(e) => setNote(e.target.value)}
          disabled={isGenerating || busy}
        ></textarea>

        {thought.length > 0 && (
          <>
            <p>Thought process:</p>
            <textarea
              className="textarea textarea-bordered w-full h-24 p-2"
              value={thought}
              readOnly
            ></textarea>
          </>
        )}
        <button
          className="btn btn-primary mt-2"
          onClick={generate}
          disabled={isGenerating || busy}
        >
          {isGenerating ? (
            <>
              <span className="loading loading-spinner loading-sm"></span>
              Generating...
            </>
          ) : (
            'Generate script'
          )}
        </button>
      </div>
    </div>
  );
};
