/* eslint-disable @next/next/no-img-element */
import React, { useState, MouseEvent } from 'react';
import styles from './ContactUs.module.scss';
import Map from '../Map';
import { validateEmail } from '../../utils';
import DashedLine from '../DashedLine';
import WavyLink from '../Link/WavyLink';
import { fetchContactUs } from '../../api/contact';
import FormMessage from '../FormMessage';
import { SubmitMessage } from '../../models/common';
import { useGoogleReCaptcha } from 'react-google-recaptcha-v3';
import useTranslation from 'next-translate/useTranslation';

interface ActionsInput {
  onChange: (value: string) => void;
}

interface Inputs {
  [key: string]: ActionsInput;
}

export type Props = {
  title: string;
};

const ContactUs = (props: Props): JSX.Element => {
  const { title } = props;
  const [enteredName, setEnteredName] = useState('');
  const [enteredEmail, setEnteredEmail] = useState('');
  const [enteredMessage, setEnteredMessage] = useState('');
  const [nameError, setNameError] = useState(false);
  const [emailError, setEmailError] = useState(false);
  const [messageError, setMessageError] = useState(false);
  const [inputId, setCurrentHoverInputId] = useState(-1);
  const [activeSubmit, setActiveSubmit] = useState(true);
  const [submitMessage, setSubmitMessage] = useState<SubmitMessage>();
  const { executeRecaptcha } = useGoogleReCaptcha();
  const { t } = useTranslation();

  const data = [
    {
      id: 'name',
      title: t('common:form.contact-us.name.title'),
      placeholder: t('common:form.contact-us.name.placeholder'),
      value: enteredName,
      error: nameError,
      type: 'input',
    },
    {
      id: 'email',
      title: t('common:form.contact-us.email.title'),
      placeholder: t('common:form.contact-us.email.placeholder'),
      value: enteredEmail,
      error: emailError,
      type: 'input',
    },
    {
      id: 'message',
      title: t('common:form.contact-us.message.title'),
      placeholder: t('common:form.contact-us.message.placeholder'),
      value: enteredMessage,
      error: messageError,
      type: 'textarea',
    },
  ];

  const runOnChange: Inputs = {
    name: {
      onChange: (value: string) => {
        setEnteredName(value);
        setNameError(value ? false : true);
      },
    },
    email: {
      onChange: (value: string) => {
        setEnteredEmail(value);
        if (!value) {
          setEmailError(false);
        } else {
          setEmailError(!validateEmail(value));
        }
      },
    },
    message: {
      onChange: (value: string) => {
        setEnteredMessage(value);
        setMessageError(value ? false : true);
      },
    },
  };

  const clearErrors = () => {
    setNameError(false);
    setEmailError(false);
    setMessageError(false);
  };

  const handleRecaptcha = async () => {
    try {
      const token = executeRecaptcha
        ? await executeRecaptcha('contact_form')
        : null;
      if (!token) throw new Error();
      return token;
    } catch (error) {
      setSubmitMessage({
        type: 'error',
        message: t('common:form.recaptcha.failed'),
      });
    }
  };

  const submitHandler = async (e: MouseEvent<HTMLButtonElement>) => {
    try {
      e.preventDefault();
      const token = await handleRecaptcha();

      if (
        enteredName &&
        !emailError &&
        enteredMessage &&
        enteredEmail &&
        token
      ) {
        setActiveSubmit(false);
        clearErrors();
        const formData = {
          name: enteredName,
          email: enteredEmail,
          message: enteredMessage,
          token,
        };
        const result = await fetchContactUs(formData);
        await new Promise((resolve) => setTimeout(resolve, 3000));
        if (result.status !== 'success') throw new Error(result.status);
        else
          setSubmitMessage({
            type: 'success',
            message: t('common:form.success'),
          });

        clearFields();
      } else {
        setActiveSubmit(true);
        setNameError(enteredName ? false : true);
        setEmailError(!validateEmail(enteredEmail));
        setMessageError(enteredMessage ? false : true);
      }
    } catch (error) {
      setSubmitMessage({
        type: 'error',
        message: t('common:form.failed'),
      });
    } finally {
      setActiveSubmit(true);
    }
  };

  const clearFields = () => {
    setEnteredName('');
    setEnteredEmail('');
    setEnteredMessage('');
  };

  return (
    <div className={styles.contactUsContainer}>
      <div className={styles.container}>
        <div className={styles.formContainer}>
          <div className={`h4_italic ${styles.h4_italic}`}>{title}</div>
          <form>
            {data.map((element, index) => {
              return (
                <div
                  className={`${styles.form_control} ${
                    element.value
                      ? styles.filled
                      : element.error
                      ? styles.error
                      : ''
                  } ${
                    element.id === 'email' && element.error ? styles.error : ''
                  }`}
                  key={index}
                >
                  <label htmlFor={element.id} className={`text_4`}>
                    {element.title}
                  </label>
                  {element.type === 'input' && (
                    <input
                      type="text"
                      id={element.id}
                      className={`text_4 ${element.error ? styles.error : ''}`}
                      placeholder={element.placeholder}
                      value={element.value}
                      onChange={(event) => {
                        runOnChange[element.id].onChange(event.target.value);
                      }}
                      onFocus={() => setCurrentHoverInputId(index + 1)}
                      onBlur={() => setCurrentHoverInputId(-1)}
                      disabled={!activeSubmit}
                    />
                  )}
                  {element.type === 'textarea' && (
                    <textarea
                      id={element.id}
                      className={`text_4 ${element.error ? styles.error : ''}`}
                      placeholder={element.placeholder}
                      onChange={(event) => {
                        runOnChange[element.id].onChange(event.target.value);
                      }}
                      onFocus={() => setCurrentHoverInputId(index + 1)}
                      onBlur={() => setCurrentHoverInputId(-1)}
                      disabled={!activeSubmit}
                      rows={2}
                      value={element.value}
                    />
                  )}
                  <img
                    src={'/imgs/icons/red_cancel_icon.svg'}
                    alt=""
                    className={`${styles.errorImage} ${
                      element.error ? styles.showErrorImage : ''
                    }`}
                  />
                  <div
                    className={`${styles.containerLine} ${
                      element.error ? styles.containerLineError : ''
                    }`}
                  >
                    <DashedLine
                      key={index + 1}
                      animate={
                        inputId === index + 1 || element.error
                          ? 'active'
                          : 'inactive'
                      }
                    />
                  </div>
                </div>
              );
            })}
            {submitMessage ? (
              <FormMessage
                {...submitMessage}
                hideComplete={() => {
                  setSubmitMessage(undefined);
                }}
              />
            ) : null}
            <button
              type="submit"
              onClick={submitHandler}
              disabled={!activeSubmit}
              aria-label=""
            >
              <div className={`h5 ${styles.h5}`}>
                <WavyLink loading={!activeSubmit} isIconFirst={true}>
                  <span>{t('common:form.button.label')}</span>
                </WavyLink>
              </div>
            </button>
          </form>
        </div>
        <div className={styles.mapContainer}>
          <Map />
        </div>
      </div>
    </div>
  );
};

export default ContactUs;
