import React, { useState, useEffect, useRef } from 'react';
import {
  Card,
  CardBody,
  Col,
  Button,
  Row,
  CustomInput,
  Label
} from 'reactstrap';
import Flex from '../common/Flex';
import FalconCardHeader from '../common/FalconCardHeader';
import { useTranslation } from 'react-i18next';
import iconPaymentMethodsGrid from '../../assets/img/icons/icon-payment-methods-grid.png';
import iconPaypalFull from '../../assets/img/icons/icon-paypal-full.png';
import { toast } from 'react-toastify';
import { updatePayment } from '../../helpers/rest';
import { useAuth } from '../../context/UserAuth';
import { getBillingInfo, getUserDetail, getCountries } from '../../helpers/rest';
import { useForm, Controller } from 'react-hook-form';
import Select from 'react-select';
import { useResponsive } from '@farfetch/react-context-responsive';

const JKPaymentMethod = () => {
  const { t } = useTranslation('account');
  const [billingInfo, setBillingInfo] = useState({});
  const [hasStoredCreditCard, setHasStoredCreditCard] = useState(false);
  const [paymentMethod, setPaymentMethod] = useState('credit-card');
  const { currentUser } = useAuth();
  const [countries, setCountries] = useState([]);
  const labelClassName = 'ls text-600 font-weight-semi-bold mb-0';
  const [submitting, setSubmitting] = useState(false);
  const [isCardValid, setIsCardValid] = useState(false);
  const { greaterThan } = useResponsive();

  const elementsRef = useRef(null);
  const formRef = useRef(null);
  const recurlyConfigured = useRef(false);
  const paypal = useRef(null);

  const {
    register,
    control,
    handleSubmit,
    setValue,
    formState: { errors }
  } = useForm({
    defaultValues: {
      first_name: '',
      last_name: '',
      address1: '',
      address2: '',
      city: '',
      state: '',
      zip: '',
      country: 'US',
    }
  });

  useEffect(() => {
    if (currentUser) {
      populateUserData();
    }
  }, [currentUser]);

  const populateUserData = async () => {
    const options = {
      id: currentUser.id
    };
    try {
      const userResp = await getUserDetail(options);
      const userData = await userResp.json();
      if (userData.has_recurly_account) {
        setHasStoredCreditCard(userData['has_stored_credit_card?']);
        await populateBillingAddress();
      }
    } catch (error) {
      console.error('Failed to get user details:', error);
    }
  };

  const populateBillingAddress = async () => {
    try {
      const resp = await getBillingInfo();
      const data = await resp.json();
      const bi = data.billing_info;
      setBillingInfo(bi);
    } catch (error) {
      console.error('Failed to get billing info:', error);
    }
  };

  useEffect(() => {
    if (currentUser) {
      fetchCountries();
    }
  }, [currentUser]);

  const fetchCountries = () => {
    getCountries()
      .then(response => {
        if (response.ok) {
          return response.json();
        }
      })
      .then(data => {
        setCountries(data.countriesx);
      })
      .catch(error => console.log(error));
  };

  useEffect(() => {
    if (billingInfo) {
      setValue('first_name', billingInfo.first_name || '');
      setValue('last_name', billingInfo.last_name || '');
      setValue('address1', billingInfo.address1 || '');
      setValue('address2', billingInfo.address2 || '');
      setValue('city', billingInfo.city || '');
      setValue('state', billingInfo.state || '');
      setValue('zip', billingInfo.zip || '');
      setValue('country', billingInfo.country || 'US');
    }
  }, [billingInfo, setValue]);

  const handleCountryChange = selectedOption => {
    setValue('country', selectedOption.value);
  };

  const recurlyContainerRef = useRef();

  useEffect(() => {
    if (!recurlyContainerRef.current || !window.recurly || recurlyConfigured.current) return;

    window.recurly.configure({ publicKey: process.env.REACT_APP_RECURLY_PUBLIC_API_KEY });
    const elements = window.recurly.Elements();
    const cardElement = elements.CardElement();

    cardElement.attach(recurlyContainerRef.current);

    cardElement.on('change', (event) => {
      setIsCardValid(event.complete && !event.error);
    });

    //then load paypal:
    const paypalInst = window.recurly.PayPal({ braintree: { clientAuthorization: process.env.REACT_APP_BRAINTREE_TOKEN } })
    paypal.current = paypalInst;
    paypal.current.on('error', onPayPalError);
    paypal.current.on('token', onPayPalToken);

    elementsRef.current = elements;
    recurlyConfigured.current = true;

    return () => {
      // Optional cleanup if the component unmounts
      recurlyContainerRef.current.innerHTML = '';
      recurlyConfigured.current = false;
    };
  }, [recurlyContainerRef.current]);

  const onPayPalError = (error) => {
    console.error('PayPal Error:', error);
    toast.error('PayPal Error: ' + (error.message || t('payment_method.alerts.try_again')));
    setSubmitting(false);
  }

  const onPayPalToken = (token) => {
    handleUpdatePayment(token);
  }

  const handleUpdatePayment = (token) => {
    updatePayment({ recurly_token: token.id }).then((response) => {
      setHasStoredCreditCard(true);
      toast.success(t('payment_method.alerts.payment_method_updated'));
    }).catch((error) => {
      console.error('Error updating payment with PayPal token:', error);
      if (error.response && error.response.data && error.response.data.message) {
        toast.error(error.response.data.message);
      } else {
        console.error('Error updating payment with PayPal token:', error);
        toast.error(t('payment_method.alerts.card_update_error'));
      }
    }).finally(() => {
      setSubmitting(false);
    });
  };

  const onSubmit = async (data) => {
    setSubmitting(true);
    if (paymentMethod === 'paypal') { // PayPal payment method
      handoverToPaypal();
      return;
    } else { // Credit Card payment method

      if (!elementsRef.current) {
        console.error('Recurly elementsRef.current is not ready');
        setSubmitting(false);
        return;
      }
      if (!formRef.current) {
        console.error('formRef.current is not ready');
        setSubmitting(false);
        return;
      }

      window.recurly.token(elementsRef.current, formRef.current, (err, token) => {
        if (err) {
          console.error('Recurly token error:', err);
          toast.error(t('payment_method.alerts.card_processing_error'));
          setSubmitting(false);
        } else {
          console.log('Recurly token:', token.id);
          // send token.id to backend
          handleUpdatePayment(token);
        }
      });
    }

  };

  const handoverToPaypal = () => {
    // Handover to Paypal
    setSubmitting(true);
    paypal.current.start()
  };

  return (
    <Card>
      <FalconCardHeader title={t('payment_method.page_title')} titleClass="font-weight-bold" />
      <CardBody className="pt-3" style={{ backgroundColor: '#edf2f9' }}>
        <div className='mb-3'>
          {hasStoredCreditCard ? (
            <span>
              <strong>{t('payment_method.help_text_has_card')}</strong>
            </span>
          ) : (
            <span>
              <strong>{t('payment_method.help_text_no_card')}</strong>
            </span>
          )}
          &nbsp;{t('payment_method.help_text')}
        </div>

        <form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
          <Card style={{ width: greaterThan.sm ? "90%" : '100%' }} className='mx-auto'>
            <FalconCardHeader title={t('payment_method.header')} titleTag="h5" />
            <CardBody>
              <Row>
                <Col className="mb-2" xs={12} md={6}>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="first_name" className={labelClassName}>
                        {t('payment_method.first_name')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('first_name', { required: t('payment_method.validations.first_name.required') })} className="form-control" data-recurly="first_name" />
                      {errors.first_name && (
                        <div className="text-danger">
                          <small>{errors.first_name.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="last_name" className={labelClassName}>
                        {t('payment_method.last_name')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('last_name', { required: t('payment_method.validations.last_name.required') })} className="form-control" data-recurly="last_name" />
                      {errors.last_name && (
                        <div className="text-danger">
                          <small>{errors.last_name.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="address1" className={labelClassName}>
                        {t('payment_method.address1')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('address1', { required: t('payment_method.validations.address1.required') })} className="form-control" data-recurly="address1" />
                      {errors.address1 && (
                        <div className="text-danger">
                          <small>{errors.address1.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="address2" className={labelClassName}>
                        {t('payment_method.address2')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('address2')} className="form-control" data-recurly="address2" />
                      {errors.address2 && (
                        <div className="text-danger">
                          <small>{errors.address2.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="city" className={labelClassName}>
                        {t('payment_method.city')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('city', { required: t('payment_method.validations.city.required') })} className="form-control" data-recurly="city" />
                      {errors.city && (
                        <div className="text-danger">
                          <small>{errors.city.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="state" className={labelClassName}>
                        {t('payment_method.state')}
                      </Label>
                    </Col>
                    <Col>
                      <input {...register('state', { required: t('payment_method.validations.state.required') })} className="form-control" data-recurly="state" />
                      {errors.state && (
                        <div className="text-danger">
                          <small>{errors.state.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="zip" className={labelClassName}>
                        {t('payment_method.zip_code')}
                      </Label>
                    </Col>
                    <Col>
                      <input
                        {...register('zip', { required: t('payment_method.validations.zip_code.required') })}
                        className="form-control" data-recurly="postal_code"
                      />
                      {errors.zip && (
                        <div className="text-danger">
                          <small>{errors.zip.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                  <Row className="mb-2">
                    <Col xs={12} md={5} lg={4} className="text-md-right">
                      <Label for="country" className={labelClassName}>
                        {t('payment_method.country')}
                      </Label>
                    </Col>
                    <Col>
                      <Controller
                        name="country"
                        control={control}
                        rules={{ required: t('payment_method.validations.country.required') }}
                        render={({ field: { onChange, value } }) => {
                          const country = countries.find(country => country.countrycode === value);
                          if (!country) {
                            return (
                              <Select
                                data-testid="countrySelect"
                                data-recurly="country"
                                onChange={handleCountryChange}
                                options={countries.map(c => {
                                  return { value: c.countrycode, label: c.countryname };
                                })}
                              />
                            );
                          }
                          return (
                            <Select
                              data-testid="countrySelect"
                              data-recurly="country"
                              value={{ value: country.countrycode, label: country.countryname }}
                              onChange={handleCountryChange}
                              options={countries.map(c => {
                                return { value: c.countrycode, label: c.countryname };
                              })}
                            />
                          );
                        }}
                      />
                      <input type="hidden" name="country" data-recurly="country" {...register('country')} />
                      {errors.country && (
                        <div className="text-danger">
                          <small>{errors.country.message}</small>
                        </div>
                      )}
                    </Col>
                  </Row>
                </Col>
                <Col xs={12} md={6} className="mb-2 pl-5">
                  <Row>
                    <Col xs={12}>
                      <CustomInput
                        label={
                          <Flex align="center" className="mb-2 fs-1">
                            <span>{t('payment_method.credit_card')}</span>
                          </Flex>
                        }
                        id="credit-card"
                        value="credit-card"
                        checked={paymentMethod === 'credit-card'}
                        onChange={({ target }) => setPaymentMethod(target.value)}
                        type="radio"
                      />
                    </Col>
                  </Row>
                  <Row>
                    <Col sm={8}>
                      <div id="recurly-elements" ref={recurlyContainerRef}></div>
                      {!isCardValid && errors.recurly && (
                        <div className="text-danger">
                          <small>{errors.recurly.message}</small>
                        </div>
                      )}
                      <input type="hidden" name="recurly-token" data-recurly="token" />
                    </Col>
                    <div className="col-4 text-center pt-2 d-none d-sm-block">
                      <div className="rounded p-2 mt-3 bg-100">
                        <div className="text-uppercase fs--2 font-weight-bold">{t('payment_method.we_accept')}</div>
                        <img src={iconPaymentMethodsGrid} alt="" width="120" />
                      </div>
                    </div>
                  </Row>
                  <hr />
                  <Row className="mt-3">
                    <Col xs={12}>
                      <CustomInput
                        label={<img className="pull-right" src={iconPaypalFull} height="20" alt="" />}
                        id="paypal"
                        value="paypal"
                        checked={paymentMethod === 'paypal'}
                        onChange={({ target }) => setPaymentMethod(target.value)}
                        type="radio"
                      />
                    </Col>
                  </Row>
                  <div className="d-flex justify-content-center">
                    <Button
                      color="primary"
                      type="submit"
                      disabled={submitting}
                      className="mt-3"
                    >
                      {submitting ? t('payment_method.submitting') : t('payment_method.save_payment_info')}
                    </Button>

                  </div>
                  <div className="text-center">
                    <p className="fs--1 mt-3 mb-0">
                      {t('payment_method.aggreement.text1')} <strong>{t('payment_method.aggreement.text2')} </strong>{t('payment_method.aggreement.text3')}{' '}
                      <br />
                      <a href="https://www.jamkazam.com/corp/terms" target='_blank'>{t('payment_method.aggreement.terms_of_service')}</a>
                    </p>
                  </div>
                </Col>
              </Row>
            </CardBody>
          </Card>
        </form>

      </CardBody>
    </Card>
  );
};

export default JKPaymentMethod;
