import React, { useMemo, useState } from 'react';

type ContactValues = {
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  message: string;
};

type ContactErrors = Partial<Record<keyof ContactValues, string>>;

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const phoneRegex = /^[+()\-.\s0-9]{8,20}$/;

const ContactForm: React.FC = () => {
  const [values, setValues] = useState<ContactValues>({
    firstName: '',
    lastName: '',
    email: '',
    phone: '',
    message: ''
  });

  const [touched, setTouched] = useState<Partial<Record<keyof ContactValues, boolean>>>({});
  const [errors, setErrors] = useState<ContactErrors>({});
  const [submitted, setSubmitted] = useState(false);

  const validate = (v: ContactValues): ContactErrors => {
    const e: ContactErrors = {};

    if (!v.firstName.trim()) e.firstName = 'Voornaam is verplicht.';
    if (!v.lastName.trim()) e.lastName = 'Achternaam is verplicht.';

    if (!v.email.trim()) e.email = 'Email is verplicht.';
    else if (!emailRegex.test(v.email.trim())) e.email = 'Vul een geldig e-mailadres in.';

    if (v.phone.trim() && !phoneRegex.test(v.phone.trim())) {
      e.phone = 'Vul een geldig telefoonnummer in.';
    }

    if (!v.message.trim()) e.message = 'Bericht is verplicht.';
    else if (v.message.trim().length < 10) e.message = 'Bericht moet minstens 10 tekens zijn.';

    return e;
  };

  const currentErrors = useMemo(() => validate(values), [values]);

  const setField = <K extends keyof ContactValues>(key: K, val: ContactValues[K]) => {
    setValues((p) => ({ ...p, [key]: val }));
    if (submitted || touched[key]) {
      setErrors(validate({ ...values, [key]: val } as ContactValues));
    }
  };

  const onBlur = (key: keyof ContactValues) => {
    setTouched((p) => ({ ...p, [key]: true }));
    setErrors(validate(values));
  };

  const onSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitted(true);

    const eMap = validate(values);
    setErrors(eMap);

    if (Object.keys(eMap).length > 0) return;

    console.log('Contact form submit:', values);

    setValues({ firstName: '', lastName: '', email: '', phone: '', message: '' });
    setTouched({});
    setErrors({});
    setSubmitted(false);
  };

  const showError = (key: keyof ContactValues) => {
    const shouldShow = submitted || touched[key];
    return shouldShow ? errors[key] : undefined;
  };

  return (
    <div className="content content--background">
      <div className="content__container content__container--small">
        <div className="content__title__row">
          <h2 className="content__title">Contact form</h2>
        </div>

        <div className="contact">
          <form className="contact__form" noValidate onSubmit={onSubmit}>
            <label className="contact__form__group contact__form__group--2">
              <span className="contact__form__label">Voornaam*</span>
              <input
                type="text"
                className="contact__input"
                placeholder="Enter your name"
                aria-label="Enter your name"
                value={values.firstName}
                onChange={(e) => setField('firstName', e.target.value)}
                onBlur={() => onBlur('firstName')}
                aria-invalid={!!showError('firstName')}
                aria-describedby="firstName-error"
              />
              {showError('firstName') && (
                <span className="contact__error" id="firstName-error">
                  {showError('firstName')}
                </span>
              )}
            </label>

            <label className="contact__form__group contact__form__group--2">
              <span className="contact__form__label">Achternaam*</span>
              <input
                type="text"
                className="contact__input"
                placeholder="Enter your last name"
                aria-label="Enter your last name"
                value={values.lastName}
                onChange={(e) => setField('lastName', e.target.value)}
                onBlur={() => onBlur('lastName')}
                aria-invalid={!!showError('lastName')}
                aria-describedby="lastName-error"
              />
              {showError('lastName') && (
                <span className="contact__error" id="lastName-error">
                  {showError('lastName')}
                </span>
              )}
            </label>

            <label className="contact__form__group contact__form__group--2">
              <span className="contact__form__label">Email*</span>
              <input
                type="email"
                className="contact__input"
                placeholder="Enter your email"
                aria-label="Enter your email"
                value={values.email}
                onChange={(e) => setField('email', e.target.value)}
                onBlur={() => onBlur('email')}
                aria-invalid={!!showError('email')}
                aria-describedby="email-error"
              />
              {showError('email') && (
                <span className="contact__error" id="email-error">
                  {showError('email')}
                </span>
              )}
            </label>

            <label className="contact__form__group contact__form__group--2">
              <span className="contact__form__label">Telefoonnummer</span>
              <input
                type="tel"
                className="contact__input"
                placeholder="Enter your phone number"
                aria-label="Enter your phone number"
                value={values.phone}
                onChange={(e) => setField('phone', e.target.value)}
                onBlur={() => onBlur('phone')}
                aria-invalid={!!showError('phone')}
                aria-describedby="phone-error"
              />
              {showError('phone') && (
                <span className="contact__error" id="phone-error">
                  {showError('phone')}
                </span>
              )}
            </label>

            <label className="contact__form__group">
              <span className="contact__form__label">Bericht*</span>
              <textarea
                className="contact__textarea"
                placeholder="Enter your message"
                aria-label="Enter your message"
                value={values.message}
                onChange={(e) => setField('message', e.target.value)}
                onBlur={() => onBlur('message')}
                aria-invalid={!!showError('message')}
                aria-describedby="message-error"
              />
              {showError('message') && (
                <span className="contact__error" id="message-error">
                  {showError('message')}
                </span>
              )}
            </label>

            <div className="contact__form__actions">
              <button type="submit" className="cta cta--primary">
                Send message
              </button>
            </div>
            {/* 
            {submitted && Object.keys(currentErrors).length > 0 && (
              <div className="contact__error-summary" role="alert">
                Controleer de velden in het formulier.
              </div>
            )} */}
          </form>
        </div>
      </div>
    </div>
  );
};

export default ContactForm;
