import React, { ChangeEvent, FC, FormEvent, useState } from 'react';
import { Button, TextBox, ErrorMessage, FormDropdown } from '@nova-hf/ui';
import format from 'date-fns/format';
import isValid from 'date-fns/isValid';
import addYears from 'date-fns/addYears';

import { useTranslation } from 'utils/i18n';
import { useAddWalletCardsUserMutation, useWalletCardsRegisteredQuery } from 'typings/graphql';
import LoadingPlaceholder from 'components/loading-placeholder/LoadingPlaceholder';

import s from './AddUser.module.scss';
import classNames from 'classnames/bind';

const cn = classNames.bind(s);

interface IAddUserProps {
  onComplete(): void;
}

const dateFormat = 'yyyy-MM-dd';

export const AddUser: FC<IAddUserProps> = ({ onComplete }) => {
  const { t } = useTranslation('cards');
  const [form, setForm] = useState({
    cardId: '',
    name: '',
    ssn: '',
    phone: '',
    expiryDate: format(addYears(new Date(), 1), dateFormat),
  });
  const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined);
  const { data, loading: registeredLoading } = useWalletCardsRegisteredQuery();
  const [addUser, { loading }] = useAddWalletCardsUserMutation();

  const handleChange = (id: string, value: string) => {
    if (errorMessage) {
      setErrorMessage(undefined);
    }

    setForm((prev) => ({
      ...prev,
      [id]: value,
    }));
  };

  const handleChangeDate = (value: string) => {
    if (errorMessage) {
      setErrorMessage(undefined);
    }

    setForm((prev) => ({
      ...prev,
      expiryDate: isValid(value) ? format(new Date(value), dateFormat) : value,
    }));
  };

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();

    try {
      const res = await addUser({
        variables: {
          input: {
            cardId: form.cardId,
            user: {
              name: form.name,
              ssn: form.ssn,
              phone: form.phone,
              expiryDate: form.expiryDate,
            },
          },
        },
      });

      if (res.data?.addWalletCardsUser.addUser?.success) {
        onComplete();
      }
    } catch (error) {
      if (error instanceof Error) {
        setErrorMessage(error.message);
      }
    }
  };

  return (
    <div className={s.addUser}>
      {registeredLoading ? (
        <div className={s.addUser__loading}>
          <LoadingPlaceholder size={32} width={200} />
          <LoadingPlaceholder width={150} />
          <LoadingPlaceholder width={250} />
        </div>
      ) : (
        <form onSubmit={handleSubmit}>
          <h2 className={s.addUser__heading}>{t('subNavigation.addUser')}</h2>
          {Boolean(errorMessage) && <ErrorMessage>{errorMessage}</ErrorMessage>}

          <FormDropdown
            onSelect={(value: string) => handleChange('cardId', value)}
            label={t('shared.selectCard')}
          >
            {(data?.walletCardsRegistered.registered ?? []).map(({ cardId, name }) => (
              <option key={cardId} value={cardId}>
                {name}
              </option>
            ))}
          </FormDropdown>

          <TextBox
            type="text"
            label={t('shared.name')}
            value={form.name}
            placeholder="John Doe"
            onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange('name', e.target.value)}
          />

          <TextBox
            type="text"
            label={t('shared.phone')}
            value={form.phone}
            placeholder="774000"
            onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange('phone', e.target.value)}
          />

          <TextBox
            type="text"
            label={t('shared.ssn')}
            value={form.ssn}
            placeholder="0101012222"
            onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange('ssn', e.target.value)}
          />

          <TextBox
            type="date"
            label={t('shared.expiryDate')}
            value={form.expiryDate}
            max="9999-12-31"
            onChange={(e: ChangeEvent<HTMLInputElement>) => handleChangeDate(e.target.value)}
          />

          <Button big loading={loading} type="submit" fill arrowRight>
            {t('shared.submit')}
          </Button>
        </form>
      )}
    </div>
  );
};
