"use client";
import { useState } from "react";
import { Options } from "redaxios";

import { Toggle } from "@/components/input/toggle";
import { TextInput } from "@/components/input/input";
import { usePersistentState } from "@/utils/usePersistentState";
import { ApiRoute, Body } from "@/utils/type";
import { useUpdateEffect } from "react-use";
import { Snippet } from "./snippet";
import { Tabs } from "./tabs";
import Link from "next/link";

export const Request = ({
  parameters,
  formattedBody,
  formattedEndpoint,
  onBodyChange,
  endpoint,
  children,
  onParamsChange,
}: {
  parameters: Record<string, any>;
  children: React.ReactElement;
  formattedBody: Options | undefined;
  endpoint: ApiRoute;
  formattedEndpoint: string;
  onBodyChange: (o: Options) => void;
  onParamsChange: (key: string, value: string | boolean) => void;
}) => {
  const [tab, setTab] = useState<"headers" | "parameters" | "body" | "snippet">(
    endpoint?.parameters ? "parameters" : endpoint?.body ? "body" : "headers"
  );

  const [headers, setHeaders] = usePersistentState("headers", {
    Authorization: "",
  });

  const [bodyForm, setBodyForm] = useState<Options>({});

  useUpdateEffect(() => onBodyChange(bodyForm), [bodyForm]);

  return (
    <div className="h-full bg-white dark:bg-slate-900 pb-5 overflow-auto">
      <div className="top-0 sticky w-full backdrop-blur">
        {children}
        <Tabs active={tab} setActive={setTab} endpoint={endpoint} />
      </div>
      <div className="px-4 xl:px-6">
        {tab === "parameters" && parameters && (
          <div className="mt-6 grid grid-cols-2 gap-6 w-full">
            <p className="text-slate-500 dark:text-slate-200 uppercase text-xs dark:font-semibold col-span-2">
              Optional parameters
            </p>
            {parameters &&
              Object.entries(parameters).map(([key, value]) => (
                <div
                  key={key}
                  className="flex items-center justify-between gap-2"
                >
                  {typeof value === "boolean" ? (
                    <div>
                      <Toggle
                        checked={value}
                        label={key}
                        tooltip={endpoint?.tooltips?.[key]}
                        onChange={(e) => onParamsChange(key, e)}
                      />
                    </div>
                  ) : (
                    <TextInput
                      value={value as string}
                      label={key}
                      tooltip={endpoint?.tooltips?.[key]}
                      placeholder="value"
                      onChange={(e) => onParamsChange(key, e)}
                    />
                  )}
                </div>
              ))}
          </div>
        )}
        {tab === "body" && endpoint?.body?.length && (
          <div className="mt-6 grid grid-cols-2 gap-6 w-full">
            <p className="text-slate-500 dark:text-slate-200 uppercase text-xs dark:font-semibold col-span-2">
              Body
            </p>
            {endpoint?.body?.length &&
              endpoint?.body.map((b, key) => (
                <div
                  key={key}
                  className="flex items-center justify-between gap-2"
                >
                  {typeof b.defaultValue === "boolean" ? (
                    <div>
                      <Toggle
                        checked={b.defaultValue}
                        label={b.key}
                        onChange={(e) =>
                          setBodyForm({ ...bodyForm, [b.key]: e })
                        }
                      />
                    </div>
                  ) : (
                    <TextInput
                      value={
                        (formattedBody?.[
                          b.key as keyof typeof formattedBody
                        ] as string) ?? (b.defaultValue as string)
                      }
                      label={b.key}
                      placeholder="value"
                      onChange={(e) => setBodyForm({ ...bodyForm, [b.key]: e })}
                    />
                  )}
                </div>
              ))}
          </div>
        )}
        {tab === "headers" && (
          <div className="mt-8 grid grid-cols-1 gap-6 w-full">
            <p className="text-slate-500 dark:text-slate-200 uppercase text-xs dark:font-semibold col-span-2">
              Headers
            </p>
            <div className="w-full">
              <TextInput
                value={headers?.Authorization}
                label="Authorization"
                placeholder="hf_token"
                onlyAlphaNumeric={false}
                onChange={(Authorization) =>
                  setHeaders({ ...headers, Authorization })
                }
              />
              <Link
                href="https://huggingface.co/settings/tokens"
                target="_blank"
                className="text-blue-500 hover:text-blue-600 text-xs mt-3 block"
              >
                Get my Hugging Face token
              </Link>
            </div>
          </div>
        )}
        {tab === "snippet" && (
          <Snippet
            endpoint={{ ...endpoint, path: formattedEndpoint }}
            parameters={parameters}
            headers={headers}
            body={formattedBody}
          />
        )}
      </div>
    </div>
  );
};
