import { typeboxResolver } from "@hookform/resolvers/typebox";
import { Input, NativeSelect, Select, TextInput } from "@mantine/core";
import { useToggle } from "@mantine/hooks";
import { IconMinus, IconPlus, IconWorld } from "@tabler/icons-react";
import type { Node, NodeProps } from "@xyflow/react";
import type { Static } from "core/utils";
import { Type } from "core/utils";
import { FetchTask } from "flows";
import { useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { Button } from "ui/components/buttons/Button";
import { JsonViewer } from "ui/components/code/JsonViewer";
import { SegmentedControl } from "ui/components/form/SegmentedControl";
import { MantineSelect } from "ui/components/form/hook-form-mantine/MantineSelect";
import { type TFlowNodeData, useFlowSelector } from "../../../hooks/use-flow";
import { KeyValueInput } from "../../form/KeyValueInput";
import { BaseNode } from "../BaseNode";

const schema = Type.Composite([
   FetchTask.schema,
   Type.Object({
      query: Type.Optional(Type.Record(Type.String(), Type.String()))
   })
]);

type TFetchTaskSchema = Static<typeof FetchTask.schema>;
type FetchTaskFormProps = NodeProps<Node<TFlowNodeData>> & {
   params: TFetchTaskSchema;
   onChange: (params: any) => void;
};

export function FetchTaskForm({ onChange, params, ...props }: FetchTaskFormProps) {
   const [advanced, toggle] = useToggle([true, false]);
   const [bodyType, setBodyType] = useState("None");
   const {
      register,
      handleSubmit,
      setValue,
      getValues,
      formState: { isValid, errors },
      watch,
      control
   } = useForm({
      resolver: typeboxResolver(schema),
      defaultValues: params as Static<typeof schema>,
      mode: "onChange"
      //defaultValues: (state.relations?.create?.[0] ?? {}) as Static<typeof schema>
   });

   function onSubmit(data) {
      console.log("submit task", data);
      onChange(data);
   }

   //console.log("FetchTaskForm", watch());
   return (
      <BaseNode
         {...props}
         isInvalid={!isValid}
         className="w-[400px]"
         Icon={IconWorld}
         tabs={TaskNodeTabs({ watch })}
         onChangeName={console.log}
      >
         <form onBlur={handleSubmit(onSubmit)} className="flex flex-col gap-3">
            <div className="flex flex-row gap-2 items-center">
               <MantineSelect
                  className="w-36"
                  label="Method"
                  defaultValue="GET"
                  data={["GET", "POST", "PATCH", "PUT", "DEL"]}
                  name="method"
                  control={control}
               />
               <TextInput
                  className="w-full"
                  label="Mapping Path"
                  placeholder="/path/to-be/mapped"
                  classNames={{ wrapper: "font-mono pt-px" }}
                  {...register("url")}
               />
            </div>

            <Button
               onClick={toggle as any}
               className="justify-center"
               size="small"
               variant="ghost"
               iconSize={14}
               IconLeft={advanced ? IconMinus : IconPlus}
            >
               More options
            </Button>

            {advanced && (
               <>
                  <KeyValueInput
                     label="URL query"
                     onChange={(items: any) => setValue("query", items)}
                     error={errors.query?.message}
                  />
                  <KeyValueInput label="Headers" />
                  <div className="flex flex-row gap-2 items-center mt-2">
                     <Input.Wrapper className="w-full">
                        <div className="flex flex-row gap-2 items-center">
                           <Input.Label>Body</Input.Label>
                           <SegmentedControl
                              data={["None", "Form", "JSON", "Code"]}
                              size="xs"
                              defaultValue={bodyType}
                              onChange={(value) => setBodyType(value)}
                           />
                        </div>
                        {bodyType === "Form" && <KeyValueInput label={undefined} />}
                        {bodyType === "JSON" && <KeyValueInput label={undefined} />}
                     </Input.Wrapper>
                  </div>
               </>
            )}
         </form>
      </BaseNode>
   );
}

const TaskNodeTabs = ({ watch }: any) => [
   {
      id: "json",
      label: "JSON",
      content: () => (
         <div className="scroll-auto">
            <JsonViewer json={watch()} expand={2} className="bg-white break-all" />
         </div>
      )
   },
   {
      id: "test",
      label: "test",
      content: () => <div>test</div>
   }
];
