import { Button, Form, FormField, Icon, Input, SpaceBetween } from "@cloudscape-design/components";
import { useEffect, useState } from "react";

import { AuthRequest, AuthRequestSchema } from "../../../doorman-schema/src";
import { fetchUrlEncoded } from "../helpers/FetchHelper";
import { useForm } from "react-hook-form";

import { zodResolver } from "@hookform/resolvers/zod";
import CInput from "react-hook-form-cloudscape/components/input";

// COPIED FROM SERVER
export enum IAuthMode {
  FIXED_PIN = "Fixed Pin",
  RANDOM_ROTATING_KEY = "Random Rotating Key",
}

export interface IAuthComponentProps {
  door: string,
  authMode: IAuthMode,
  secret: string | null;
  onUnlock: () => void;
  onError?: (res: any) => void;
  runCheck?: number;
}

export const AuthComponent = ({ door, secret, authMode, onError, onUnlock, runCheck }: IAuthComponentProps) => {
  const { control, setError, formState, handleSubmit, setValue, getValues } = useForm<AuthRequest>({
    resolver: zodResolver(AuthRequestSchema),
    defaultValues: {
      key: secret || "",
      door,
    }
  });

  const [isLoading, setLoading] = useState(false);

  const onSubmit = async (body: AuthRequest) => {
    setLoading(true);
    await fetchUrlEncoded('/api/door/auth', body)
      .then(async res => {
        if (res.status !== 200) {
          setError("key", { type: "validate", message: "Incorrect PIN"});
          onError && onError(await res.json());
          return;
        }
        onUnlock();
    });
    setLoading(false);
  };

  useEffect(() => {
    // don't allow us to submit while we are submitting
    if (runCheck && !isLoading) {
      handleSubmit(onSubmit)();
    }
  }, [runCheck]);


  // try and submit on load if the pin is passed in by query params
  useEffect(() => {
    setLoading(true);
    fetch('https://api.ipify.org?format=json')
      .then(response => response.json())
      .then(data => {
          return data.ip;
      })
      .catch(error => {
          console.log('Error:', error);
          return "null";
      })
      .then(async ip => {
        setValue("ip", ip);

        // if the key is there, then try submitting right away
        if (secret !== null) {
          await handleSubmit(onSubmit)();
        }

        setLoading(false);
      });
  }, [secret]);

  return (
    <>
      <SpaceBetween size='l'>
        <FormField errorText={formState.errors.key?.message} label={"PIN"} constraintText={"Enter the PIN to unlock the door"}>
          <CInput type="password" name="key" readOnly={secret !== null} control={control} />
        </FormField>
      </SpaceBetween>
    </>
  );
}