import React, { useEffect, useState } from "react";
import { H3, TextArea, Button, Pre, Loader } from "../components";
import styled from "styled-components";
import { postVscMessage, withProgress } from "../vscode";
import { useDebugContextValue } from "../redux/hooks";
import CodeMultiselect from "../components/CodeMultiselect";
import { useSelector } from "react-redux";
import { selectDebugContext } from "../redux/selectors/debugContextSelectors";
import { useDispatch } from "react-redux";
import { updateValue } from "../redux/slices/debugContexSlice";
import { setWorkspacePath } from "../redux/slices/configSlice";
import { SerializedDebugContext } from "../../../src/client";
import { useEditCache } from "../util/editCache";
import { useApi } from "../util/api";

const ButtonDiv = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 4px;
  margin: 4px;
  flex-wrap: wrap;

  & button {
    flex-grow: 1;
  }
`;

function MainTab(props: any) {
  const dispatch = useDispatch();

  const [suggestion, setSuggestion] = useState("");
  const [traceback, setTraceback] = useDebugContextValue("traceback", "");
  const [selectedRanges, setSelectedRanges] = useDebugContextValue(
    "rangesInFiles",
    []
  );

  const editCache = useEditCache();
  const { debugApi } = useApi();

  const [responseLoading, setResponseLoading] = useState(false);

  let debugContext = useSelector(selectDebugContext);

  useEffect(() => {
    editCache.preloadEdit(debugContext);
  }, [debugContext]);

  function postVscMessageWithDebugContext(
    type: string,
    overrideDebugContext: SerializedDebugContext | null = null
  ) {
    postVscMessage(type, {
      debugContext: overrideDebugContext || debugContext,
    });
  }

  function launchFindSuspiciousCode(newTraceback: string) {
    // setTraceback's effects don't occur immediately, so we have to add it to the debug context manually
    let updatedDebugContext = {
      ...debugContext,
      traceback: newTraceback,
    };
    postVscMessageWithDebugContext("findSuspiciousCode", updatedDebugContext);
    postVscMessageWithDebugContext("preloadEdit", updatedDebugContext);
  }

  useEffect(() => {
    const eventListener = (event: any) => {
      switch (event.data.type) {
        case "suggestFix":
        case "explainCode":
        case "listTenThings":
          setSuggestion(event.data.value);
          setResponseLoading(false);
          break;
        case "traceback":
          setTraceback(event.data.value);
          launchFindSuspiciousCode(event.data.value);
          break;
        case "workspacePath":
          dispatch(setWorkspacePath(event.data.value));
          break;
      }
    };
    window.addEventListener("message", eventListener);

    return () => window.removeEventListener("message", eventListener);
  }, [debugContext, selectedRanges]);

  return (
    <div className="mx-5">
      <h1>Debug Panel</h1>

      <H3>Code Sections</H3>
      <CodeMultiselect></CodeMultiselect>

      <H3>Bug Description</H3>
      <TextArea
        id="bugDescription"
        name="bugDescription"
        className="bugDescription"
        rows={4}
        cols={50}
        placeholder="Describe your bug..."
      ></TextArea>

      <H3>Stack Trace</H3>
      <TextArea
        id="traceback"
        className="traceback"
        name="traceback"
        rows={4}
        cols={50}
        placeholder="Paste stack trace here"
        onChange={(e) => {
          setTraceback(e.target.value);
          dispatch(updateValue({ key: "traceback", value: e.target.value }));
          // postVscMessageWithDebugContext("findSuspiciousCode");
        }}
        onPaste={(e) => {
          let pasted = e.clipboardData.getData("text");
          console.log("PASTED", pasted);
          setTraceback(pasted);
          launchFindSuspiciousCode(pasted);
        }}
        value={traceback}
      ></TextArea>

      <select
        hidden
        id="relevantVars"
        className="relevantVars"
        name="relevantVars"
      ></select>

      <ButtonDiv>
        <Button
          onClick={() => {
            postVscMessageWithDebugContext("explainCode");
            setResponseLoading(true);
          }}
        >
          Explain Code
        </Button>
        <Button
          onClick={() => {
            postVscMessageWithDebugContext("suggestFix");
            setResponseLoading(true);
          }}
        >
          Generate Ideas
        </Button>
        <Button
          disabled={selectedRanges.length === 0}
          onClick={async () => {
            withProgress("Generating Fix", async () => {
              let edits = await editCache.getEdit(debugContext);
              postVscMessage("makeEdit", { edits });
            });
          }}
        >
          Suggest Fix
        </Button>
        <Button
          disabled={selectedRanges.length === 0}
          onClick={() => {
            postVscMessageWithDebugContext("generateUnitTest");
          }}
        >
          Create Test
        </Button>
      </ButtonDiv>
      <Loader hidden={!responseLoading}></Loader>

      <Pre
        className="fixSuggestion"
        hidden={!(typeof suggestion === "string" && suggestion.length > 0)}
      >
        {suggestion}
      </Pre>

      <br></br>
    </div>
  );
}

export default MainTab;