import React, { FC, useState } from 'react';
import Form from '../../blocks/Form';
import Input from '../../blocks/Input';
import RadioButtons, { RadioItem } from '../../blocks/RadioButtons';
import css from './index.module.css';
import Checkbox from '../../blocks/Checkbox';
import FingerIconSVG from '../../assets/icons/icon_finger.svg';
import creditCardType, { types as CardType } from 'credit-card-type';
import ToolTipModal from '../../blocks/ToolTipModal';

export interface PaymentFormValues {
  creditCardNumber: string;
  creditCardHolder: string;
  expirationDate: string;
  cvc: string;
  paymentOption: string;
  savePaymentInfo: boolean;
  paymentMethod: string;
}

export interface PaymentMethodData {
  id: string;
  type: 'Card';
  details: {
    last4: string;
    holderName: string;
    brand: string;
  };
}

export interface PaymentFormLabels {
  creditCardNumber: string;
  creditCardHolder: string;
  expirationDate: string;
  cvc: string;
  creditCard: string;
  invoice: string;
  savePaymentInfo: string;
  guaranteeTitle: string;
  guaranteeText: string;
  cvcTooltip: string;
  invoiceAddress: string;
  newCreditCard: string;
}

export interface PaymentFormErrors {
  creditCardNumber: string;
  creditCardHolder: string;
  expirationDate: string;
  cvc: string;
  creditCard: string;
  invoice: string;
}

export interface PaymentFormTouched {
  [key: string]: unknown;
}

export interface PaymentFormProps {
  values: PaymentFormValues;
  touched: PaymentFormTouched;
  errors: PaymentFormErrors;
  labels: PaymentFormLabels;
  handleChange: (e) => void;
  handleBlur: (e) => void;
  handleSubmit: (e) => void;
  invoiceAddress: {
    firstName: string;
    lastName: string;
    additional: string;
    street: string;
    streetNr: string;
    zip: string;
    city: string;
    country: string;
    company: string;
  };
  isLoggedIn: boolean;
  paymentMethods: PaymentMethodData[];
  deviceType?: string;
  checkIfKeyBoardOpen?: (e) => void;
  isCreditCardDisabled: boolean;
}

const PaymentForm: FC<PaymentFormProps> = ({
  values,
  touched,
  errors,
  handleChange,
  handleBlur,
  handleSubmit,
  labels,
  invoiceAddress,
  isLoggedIn,
  paymentMethods,
  checkIfKeyBoardOpen,
  isCreditCardDisabled,
}) => {
  const [creditCardIssuer, setCreditCardIssuer] = useState('');

  const ccFormat = (value): string => {
    const v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, '');
    const matches = v.match(/\d{4,16}/g);
    const match = (matches && matches[0]) || '';
    const parts = [];

    for (let i = 0, len = match.length; i < len; i += 4) {
      parts.push(match.substring(i, i + 4));
    }
    if (v.length > 0) {
      const type = creditCardType(v).filter(function (card) {
        switch (card.type) {
          case CardType.MASTERCARD: {
            return card;
          }
          case CardType.VISA: {
            return card;
          }
          default: {
            break;
          }
        }
      });
      setCreditCardIssuer(type.length > 0 ? type[0].type : 'invalid');
    } else {
      setCreditCardIssuer('');
    }

    if (parts.length) {
      return parts.join(' ');
    } else {
      return value;
    }
  };

  let items: RadioItem[];
  if (isCreditCardDisabled) {
    items = [
      {
        label: labels.invoice,
        value: 'Invoice',
        isChecked: values.paymentOption == 'Invoice',
        name: 'paymentOption',
      },
    ];
  } else {
    items = [
      {
        label: labels.creditCard,
        value: 'Card',
        isChecked: values.paymentOption == 'Card',
        name: 'paymentOption',
      },
      {
        label: labels.invoice,
        value: 'Invoice',
        isChecked: values.paymentOption == 'Invoice',
        name: 'paymentOption',
      },
    ];
  }

  return (
    <Form onSubmit={handleSubmit} novalidate>
      <div className={css.formPayment__tooltip}>
        <FingerIconSVG height={42} width={66} />
        <p>{labels.guaranteeTitle}</p>
        <p>{labels.guaranteeText}</p>
      </div>
      <div
        className={`${css.formRegister__input} ${css.formRegister__inputRadioButtons}`}
      >
        <RadioButtons
          onChange={handleChange}
          items={items}
          horizontal={true}
          invert={true}
        />
      </div>
      {items.length > 1 && items[0].isChecked ? (
        <div id={'credit-card-form'}>
          {paymentMethods && paymentMethods.length > 0 && (
            <RadioButtons
              onChange={handleChange}
              horizontal={false}
              items={[
                ...paymentMethods.map((p) => ({
                  isChecked: values.paymentMethod === p.id,
                  label: (
                    <>
                      {labels.creditCard} **** **** **** {p.details.last4} (
                      {p.details.holderName})
                    </>
                  ),
                  name: 'paymentMethod',
                  value: p.id,
                })),
                {
                  isChecked: values.paymentMethod === 'new',
                  label: labels.newCreditCard,
                  name: 'paymentMethod',
                  value: 'new',
                },
              ]}
            />
          )}
          {values.paymentMethod === 'new' && (
            <div>
              <div className={css.formPayment__ccIcons}>
                <i
                  className={`fa fa-cc-mastercard ${
                    creditCardIssuer != 'mastercard' && creditCardIssuer != ''
                      ? css.formPayment__ccIconInactive
                      : ''
                  }`}
                />
                <i
                  className={`fa fa-cc-visa ${
                    creditCardIssuer != 'visa' && creditCardIssuer != ''
                      ? css.formPayment__ccIconInactive
                      : ''
                  }`}
                />
              </div>
              <div className={css.formRegister__input}>
                <Input
                  style={'booking'}
                  type="text"
                  name="creditCardNumber"
                  autocomplete="cc-number"
                  label={labels.creditCardNumber}
                  required
                  onChange={(e): void => {
                    e.target.value = ccFormat(e.target.value);
                    handleChange(e);
                  }}
                  onBlur={handleBlur}
                  value={values.creditCardNumber}
                  error={touched.creditCardNumber && errors.creditCardNumber}
                  isKeyBoardOpen={checkIfKeyBoardOpen}
                />
              </div>
              <div className={css.formRegister__input}>
                <Input
                  style={'booking'}
                  type="text"
                  name="creditCardHolder"
                  autocomplete="cc-holder"
                  label={labels.creditCardHolder}
                  required
                  onChange={handleChange}
                  onBlur={handleBlur}
                  value={values.creditCardHolder}
                  error={touched.creditCardHolder && errors.creditCardHolder}
                  isKeyBoardOpen={checkIfKeyBoardOpen}
                />
              </div>
              <div className={css.formRegister__inputSplit}>
                <div>
                  <div className={css.formRegister__input}>
                    <Input
                      style={'booking'}
                      type="text"
                      name="expirationDate"
                      autocomplete="cc-year"
                      label={labels.expirationDate}
                      required
                      onKeyUp={(e): void => {
                        if (e.key !== 'Backspace') {
                          let input = e.target.value;
                          input = input.length >= 5 ? input.slice(0, 5) : input;
                          if (/^\d{2,}$/.test(input)) {
                            input = input.replace(new RegExp('.{1,2}'), '$&/');
                          }

                          if (e.target.value !== input) {
                            e.target.value = input;
                            handleChange(e);
                          }
                        }
                      }}
                      onChange={(e): void => {
                        handleChange(e);
                      }}
                      onBlur={handleBlur}
                      value={values.expirationDate}
                      error={touched.expirationDate && errors.expirationDate}
                      isKeyBoardOpen={checkIfKeyBoardOpen}
                    />
                  </div>

                  <div className={css.formRegister__input}>
                    <Input
                      style={'booking'}
                      type="text"
                      name="cvc"
                      autocomplete="cc-csc"
                      label={labels.cvc}
                      required
                      onChange={handleChange}
                      onBlur={handleBlur}
                      value={values.cvc}
                      error={touched.cvc && errors.cvc}
                      isKeyBoardOpen={checkIfKeyBoardOpen}
                    />
                  </div>
                </div>
                <ToolTipModal
                  title={labels.cvc}
                  description={labels.cvcTooltip}
                  iconClass={css.formPayment__ccvHelperIcon}
                />
              </div>
              {isLoggedIn && (
                <Checkbox
                  onChange={handleChange}
                  name="savePaymentInfo"
                  label={labels.savePaymentInfo}
                />
              )}
            </div>
          )}
        </div>
      ) : (
        <>
          <div className={css.formPayment__invoice}>
            <div>{labels.invoiceAddress}</div>
            <div>
              {invoiceAddress.firstName + ' ' + invoiceAddress.lastName}
            </div>
            {invoiceAddress.company && <div>{invoiceAddress.company}</div>}
            {invoiceAddress.additional && (
              <div>{invoiceAddress.additional}</div>
            )}
            <div>{invoiceAddress.street + ' ' + invoiceAddress.streetNr}</div>
            <div>{invoiceAddress.zip + ' ' + invoiceAddress.city}</div>
            <div>{invoiceAddress.country}</div>
          </div>
        </>
      )}
    </Form>
  );
};

export default PaymentForm;
