import { useForm, SubmitHandler } from 'react-hook-form';
import { ContactsProps } from '../../pages/Chat.tsx';
import { axiosClient } from '../../App.tsx';
import { AxiosResponse } from 'axios';
import { useEffect, useState } from 'react';
import LoadingWheel from './LoadingWheel.tsx';

type Input = {
  contact: string;
};

type ContactFormProps = {
  InitializeContact: (contact: ContactsProps) => void;
  setContactsList: React.Dispatch<React.SetStateAction<ContactsProps[]>>;
};

function ContactForm({ InitializeContact, setContactsList }: ContactFormProps) {
  const { register, handleSubmit, reset, watch } = useForm<Input>();
  const contactInput = watch('contact');
  const [suggestions, setSuggestions] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [notFound, setNotFound] = useState<boolean>(false);
  const [selectedIndex, setSelectedIndex] = useState<number>(0);

  useEffect(() => {
    const fetchSuggestions = async () => {
      if (contactInput?.length >= 3) {
        try {
          setIsLoading(true);
          const response: AxiosResponse<string[]> = await axiosClient.get(
            `/api/chat/contacts/suggestions/${contactInput}`,
          );
          setSuggestions(response.data);
          setSelectedIndex(0); // Reset selection to first item when suggestions update
          if (response.data.length < 1) {
            setIsLoading(false);
            setNotFound(true);
          } else {
            setIsLoading(false);
            setNotFound(false);
          }
        } catch (error) {
          setIsLoading(false);
          console.error('Error fetching suggestions:', error);
        }
      } else {
        setNotFound(false);
        setIsLoading(false);
        setSuggestions([]);
      }
    };

    const delay = setTimeout(() => {
      fetchSuggestions();
    }, 300);

    return () => clearTimeout(delay);
  }, [contactInput]);

  const submitContact: SubmitHandler<Input> = async (data) => {
    const contactToSubmit =
      suggestions.length > 0 ? suggestions[selectedIndex] : data.contact.trim();

    try {
      setContactsList((prevContacts) => {
        if (prevContacts.some((c) => c.username === contactToSubmit)) {
          return prevContacts;
        }
        return prevContacts;
      });

      console.log('Submit contact: ', contactToSubmit);
      const response: AxiosResponse<ContactsProps> = await axiosClient.post(
        `/api/chat/contact/${contactToSubmit}`,
      );

      console.log('contact post response: ', response.data);
      InitializeContact(response.data);

      setContactsList((prevContacts) => {
        if (!prevContacts.some((c) => c.username === contactToSubmit)) {
          return [...prevContacts, response.data];
        }
        return prevContacts;
      });

      reset({ contact: '' });
      setSuggestions([]);
    } catch (error) {
      console.error('Error adding contact:', error);
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (suggestions.length > 0) {
      switch (e.key) {
        case 'ArrowDown':
          e.preventDefault();
          setSelectedIndex((prev) => (prev + 1) % suggestions.length);
          break;
        case 'ArrowUp':
          e.preventDefault();
          setSelectedIndex(
            (prev) => (prev - 1 + suggestions.length) % suggestions.length,
          );
          break;
        case 'Enter':
          if (suggestions.length > 0) {
            e.preventDefault();
            reset({ contact: suggestions[selectedIndex] });
            handleSubmit(submitContact)();
          }
          break;
      }
    }
  };

  return (
    <>
      <div className="text-center">
        <form onSubmit={handleSubmit(submitContact)}>
          <input
            className="text-white bg-gray-800 pl-2 shadow-lg rounded-xl h-8 mb-2 mt-2 placeholder:text-gray-400 outline-none border-gray-600 focus:outline-none focus:ring-0"
            type="text"
            placeholder="Search for user"
            onKeyDown={handleKeyDown}
            {...register('contact', {
              minLength: 4,
              maxLength: 20,
            })}
          />
        </form>
        <div className="m-1">
          {suggestions?.length > 0 ? (
            <ul className="text-left p-2 bg-gray-900 shadow-md rounded-md w-full border">
              {suggestions.map((suggestion, index) => (
                <li
                  key={suggestion}
                  className={`p-1 cursor-pointer rounded-md mt-1 mb-1 ${
                    index === selectedIndex
                      ? 'bg-gray-500'
                      : 'hover:bg-gray-500'
                  }`}
                  onClick={() => {
                    reset({ contact: suggestion });
                    handleSubmit(() =>
                      submitContact({ contact: suggestion }),
                    )();
                    setSuggestions([]);
                  }}
                >
                  {suggestion}
                </li>
              ))}
            </ul>
          ) : isLoading ? (
            <LoadingWheel />
          ) : null}
          {notFound ? (
            <p className="p-1 bg-gray-800 shadow-md rounded-md w-full border text-gray-400">
              user not found
            </p>
          ) : null}
        </div>
      </div>
    </>
  );
}

export default ContactForm;
