import React from "react";
import {
  ActionIcon,
  TextInput,
  Text,
  Loader,
  Tooltip,
  HoverCard,
  Flex,
  Badge,
} from "@mantine/core";
import { getHotkeyHandler } from "@mantine/hooks";
import styled from "styled-components";
import { FunctionsHttpError } from "@supabase/supabase-js";
import toast from "react-hot-toast";
import { GoDependabot } from "react-icons/go";
import { VscClose, VscQuestion } from "react-icons/vsc";
import useJsonQuery from "src/hooks/useJsonQuery";
import { supabase } from "src/lib/api/supabase";
import useConfig from "src/store/useConfig";
import useUser from "src/store/useUser";

const StyledPromptInput = styled(TextInput)`
  .mantine-TextInput-wrapper {
    margin-bottom: 0;
  }
  .mantine-TextInput-input {
    font-weight: 500;
    background: ${({ theme }) => theme.PROMPT_BG};
    color: ${({ theme }) => theme.PROMPT_TEXT_COLOR};
    border: none;
    border-bottom: 1px solid
      ${({ theme, error }) => (error ? theme.DANGER : theme.PROMPT_BORDER_COLOR)};

    :focus-within {
      border-color: #15593a;
    }
  }

  .mantine-TextInput-error {
    padding: 4px;
    border-bottom: 1px solid ${({ theme }) => theme.DANGER};
    background: #280000;
  }

  svg {
    color: ${({ theme }) => theme.PROMPT_TEXT_COLOR};
  }

  ::placeholder {
    color: ${({ theme }) => theme.PROMPT_PLACEHOLDER_COLOR};
  }
`;

export const PromptInput = () => {
  const { updateJson, getJsonType } = useJsonQuery();
  const premium = useUser(state => state.premium);
  const [completing, setCompleting] = React.useState(false);
  const [prompt, setPrompt] = React.useState("");
  const promptVisible = useConfig(state => state.aiEnabled);
  const [promptError, setPromptError] = React.useState<string | null>(null);

  const onSubmit = async () => {
    try {
      setPromptError(null);
      setCompleting(true);
      const jsonModel = await getJsonType();

      const { data, error } = await supabase.functions.invoke("jq", {
        body: { query: prompt, jsonModel },
      });

      if (error instanceof FunctionsHttpError) {
        const errorMessage = await error.context.json();
        throw Error(errorMessage.error);
      }

      // extract jq command
      const jqOutput = data.command;
      const regex = /'([^']*)'/;
      const match = jqOutput.match(regex);

      if (match && match[1]) {
        const extractedString = match[1];
        updateJson(extractedString);
        toast.success(`${data.credits} credits left for today.`);
      } else {
        throw Error("An error occured while parsing result.");
      }
    } catch (error: any) {
      console.error(error);
      if (error instanceof Error) setPromptError(error.message);
    } finally {
      setCompleting(false);
    }
  };

  if (!promptVisible) return null;

  return (
    <Tooltip
      disabled={premium}
      w={400}
      multiline
      position="right"
      label={
        <Text fz="xs">
          <Badge size="xs" radius={2}>
            Alpha
          </Badge>{" "}
          JSON Crack AI is currently only available to premium users to test out. You may close this
          from the settings.
        </Text>
      }
      fz="xs"
      withinPortal
      withArrow
    >
      <div>
        <StyledPromptInput
          placeholder="Ask JSON Crack AI to transform the data"
          value={prompt}
          onChange={e => setPrompt(e.currentTarget.value)}
          maxLength={200}
          disabled={!premium || completing}
          onKeyDown={getHotkeyHandler([["Enter", onSubmit]])}
          onSubmit={onSubmit}
          error={
            promptError && (
              <Flex align="center" justify="space-between">
                {promptError}
                <ActionIcon
                  size="xs"
                  variant="transparent"
                  title="Close Error"
                  onClick={() => setPromptError(null)}
                >
                  <VscClose color="red" />
                </ActionIcon>
              </Flex>
            )
          }
          rightSection={
            <>
              <HoverCard withArrow withinPortal>
                <HoverCard.Target>
                  <ActionIcon variant="transparent">
                    <VscQuestion />
                  </ActionIcon>
                </HoverCard.Target>
                <HoverCard.Dropdown maw={300} fz="xs">
                  This feature is in the{" "}
                  <Badge size="xs" radius={2} variant="light">
                    alpha
                  </Badge>{" "}
                  phase, and its results may not always be accurate. Be cautious, as invalid actions
                  still consume a credit. We only process the schema of your data and DO NOT process
                  values.
                  <br />
                  <br />
                  You receive <b>10 credits</b> daily, and you have the option to deactivate this
                  feature in the settings located at the upper right corner of the editor.
                  <br />
                  <br />
                  Examples:
                  <li>
                    <code>Retrieve members whose names begin with &quot;M&quot;</code>
                  </li>
                  <li>
                    <code>Retrieve members with age older than 30</code>
                  </li>
                </HoverCard.Dropdown>
              </HoverCard>
            </>
          }
          leftSection={completing ? <Loader size="xs" /> : <GoDependabot strokeWidth={1} />}
          radius={0}
        />
      </div>
    </Tooltip>
  );
};
