import React, { useEffect, useState, useRef, useMemo } from 'react';
import classNames from 'classnames/bind';
import styles from './ProfileModal.scss';
import { Link, useLocation } from 'react-router-dom';
import { ReactComponent as IconEthereum } from '@assets/img/svg/logo_ethereum.svg';
import { ReactComponent as IconMetarare } from '@assets/img/svg/logo_metarare.svg';
import { ReactComponent as IconMetafinance } from '@assets/img/svg/logo_metafinance.svg';
import StringUtil from '@src/utils/StringUtil';
import URLInfo from '@src/constants/URLInfo';
import LayerContainer from '@src/containers/common/LayerContainer';
import Layer from '@src/components/common/Layer';
import Input from '@src/components/common/Input';
import InputPrice from '@src/components/common/InputPrice';
import HashBox from '@src/components/common/HashBox';
import { ECurrencyType } from '@src/constants/Enums';
import { useDispatch, useSelector } from 'react-redux';
import useLogin from '@src/hooks/useLogin';
import APIs from '@src/api/APIs';
import { toggleLoadingState } from '@src/store/reducers/NetworkLoadingReducer';
import NumberUtils from '../../utils/NumberUtil';

const cx = classNames.bind(styles);

interface IOwnProps {
  onClose: () => void;
};

function useInterval(callback: () => void, delay: number) {
  const savedCallback = useRef<any>();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    function tick() {
      savedCallback.current();
    }

    if (delay === 0) {
      return;
    }

    const intervalId = setInterval(tick, delay);
    return () => {
      clearInterval(intervalId);
    }
  }, [delay]);
}

const ProfileModal: React.FC<IOwnProps> = ({ onClose }) => {
  const dispatch = useDispatch();
  const location = useLocation();
  const { userInfo } = useSelector(store => store.user);

  const [showWithdrewLayer, setShowWithdrewLayer] = useState<boolean>(false);
  const [showWithdrewCompleteLayer, setShowWithdrewCompleteLayer] = useState<boolean>(false);
  const [address, setAddress] = useState<string>('');
  const [price, setPrice] = useState<string>('');
  const [currencyType, setCurrencyType] = useState<ECurrencyType>(ECurrencyType.ETH);
  const [collectionHash, setCollectionHash] = useState<string>('');
  const [authenticationInput, setAuthenticationInput] = useState(false);
  const [authenticationNumber, setAuthenticationNumber] = useState<string>('');
  const [minutes, setMinutes] = useState<number>(0);
  const [seconds, setSeconds] = useState<number>(0);
  const [timerStatus, setTimerStatus] = useState(false);



  const { handleClickLogout, loginText } = useLogin();

  useEffect(() => {
    onClose();
  }, [location.pathname]);

  useInterval(() => {
    if (seconds > 0) {
      setSeconds(seconds - 1);
    }
    if (seconds === 0) {
      if (minutes === 0) {
        setTimerStatus(false);
        
      } else {
        setMinutes(minutes - 1);
        setSeconds(59);
      }
    }
  }, timerStatus ? 1000 : 0);

  const handleClickCopy = () => {
    navigator.clipboard.writeText(userInfo?.simple_profile.address || '').then(() => {
      alert('복사되었습니다.');
    });
  };

  const handleChangeWalletAddress = (e: React.ChangeEvent<HTMLInputElement>) => {
    setAddress(e.target.value);
  };

  const handleChangeAuthenticationNumber = (e: React.ChangeEvent<HTMLInputElement>) => {
    setAuthenticationNumber(e.target.value);
  }

  const handleClickSendEmail = async () => { //user/cartification/code로 요청 => 응답값 send할때 같이 보냄

    if (address.length === 0) {
      alert('출금 주소를 입력해주세요.');
      return;
    }

    if (price.length === 0 || Number(price) === 0) {
      alert('토큰 개수를 입력해주세요.');
      return;
    }

    setAuthenticationInput(true);
    setMinutes(5);
    setSeconds(0);
    setTimerStatus(true);

    await APIs.sendEmail({ amount: Number(price), currency: currencyType })
      .then((res) => {
        console.log('성공');
      })
      .catch((err) => {
        console.log('에러');
      });
  };

  const handleClickSend = async () => {
    if (!userInfo) {
      return;
    }

    if (address.length === 0) {
      alert('출금 주소를 입력해주세요.');
      return;
    }

    if (price.length === 0) {
      alert('토큰 개수를 입력해주세요.');
      return;
    }
    
    if (authenticationNumber.length !== 6) {

      alert('인증번호는 6자리 입니다');
      return;
    }

    if (!Number(authenticationNumber)) {
      alert('숫자만 입력 가능합니다');
      return;
    }

    setAuthenticationInput(true);
    setTimerStatus(true);

    let isCanTransfer = false;
    const networkFee = Number(userInfo.settings.network_commission);
    const userEth = userInfo.simple_profile.available_eth_balance;
    switch (currencyType) {
      case 'eth':
        if (Number(price) + networkFee <= userEth) {
          isCanTransfer = true;
        }
        break;
      case 'mr':
        if (Number(price) <= userInfo.simple_profile.available_mr_balance && userEth >= networkFee) {
          isCanTransfer = true;
        }
        break;
      case 'mf':
        if (Number(price) <= userInfo.simple_profile.available_mf_balance && userEth >= networkFee) {
          isCanTransfer = true;
        }
        break;
    }
    if (!isCanTransfer) {
      alert('가용 잔고가 부족합니다. 잔고를 확인해주세요');
      return;
    }


    dispatch(toggleLoadingState()); 
    await APIs.transfer({ amount: Number(price), currency: currencyType, to_address: address, code: authenticationNumber })
      .then((res) => {
        setShowWithdrewCompleteLayer(true);
        setCollectionHash(res);
        clearTransferModal()
        dispatch(toggleLoadingState());
      }).catch(() => {
        clearTransferModal()
        dispatch(toggleLoadingState());
        alert('출금을 실패하였습니다.');
      });
  };

  const clearTransferModal = () => {
    setAddress('');
    setPrice('');
    setAuthenticationNumber('');
    setAuthenticationInput(false);
    setTimerStatus(false);
    setCurrencyType(ECurrencyType.ETH);
    setShowWithdrewLayer(false);
  }

  const handleClickConfirmTransaction = () => {
    window.open(URLInfo.getTransactionUrl(collectionHash), '_blank');
    setShowWithdrewCompleteLayer(false);
    onClose();
  };

  const handleClickLogoutBtn = () => {
    handleClickLogout();
    onClose();
  };

  const handleWithdrawButtonClick = () => {
    if (!authenticationInput || (seconds === 0 && minutes === 0)) {
      handleClickSendEmail();
      return;
    }
    handleClickSend();
  };

  const withdrawButtonText = useMemo<string>(() => {
    if (seconds === 0 && minutes === 0) {
      return '재발송';
    }
    if (authenticationInput) {
      return '출금 신청하기';
    }
    return '이메일로 인증번호 발송'
  }, [seconds, minutes, authenticationInput]);

  return (
    <div className={cx('profile_modal_wrap')}>
      <div className={cx('profile_info')}>
        <strong className={cx('name')}>{userInfo?.simple_profile.name}</strong>
        <div className={cx('wallet')}>
          <span className={cx('address')}>
            {StringUtil.summaryWalletAddress(userInfo?.simple_profile.address)}
          </span>
          <button type="button" className={cx('btn_copy')} onClick={handleClickCopy}>복사</button>
        </div>
      </div>
      <div className={cx('account_info')}>
        <div className={cx('btn_area')}>
          <button 
            type="button" 
            className={cx('btn_transaction')} 
            onClick={() => setShowWithdrewLayer(true)}
          >
            출금
          </button>
        </div>
        <ul className={cx('account_list')}>
          <li className={cx('account')}>
            <div className={cx('ico_area')}>
              <IconEthereum className={cx('ico_exchange')} />
            </div>
            <div className={cx('info_area')}>
              <div className={cx('name')}>Ethereum</div>
              <div className={cx('balance')}>
                <strong className={cx('number')}>
                  {NumberUtils.formatBalance(userInfo?.simple_profile.eth_balance)}
                  ({NumberUtils.formatBalance(userInfo?.simple_profile.available_eth_balance)})
                </strong>
                <strong className={cx('unit')}>ETH</strong>
              </div>
            </div>
          </li>
          <li className={cx('account')}>
            <div className={cx('ico_area')}>
              <IconMetarare className={cx('ico_exchange')} />
            </div>
            <div className={cx('info_area')}>
              <div className={cx('name')}>Mtra</div>
              <div className={cx('balance')}>
                <strong className={cx('number')}>
                  {NumberUtils.formatBalance(userInfo?.simple_profile.mr_balance)}
                  ({NumberUtils.formatBalance(userInfo?.simple_profile.available_mr_balance)})
                </strong>
                <strong className={cx('unit')}>MTRA</strong>
              </div>
            </div>
          </li>
          <li className={cx('account')}>
            <div className={cx('ico_area')}>
              <IconMetafinance className={cx('ico_exchange')} />
            </div>
            <div className={cx('info_area')}>
              <div className={cx('name')}>Mf1</div>
              <div className={cx('balance')}>
                <strong className={cx('number')}>
                  {NumberUtils.formatBalance(userInfo?.simple_profile.mf_balance)}
                  ({NumberUtils.formatBalance(userInfo?.simple_profile.available_mf_balance)})
                </strong>
                <strong className={cx('unit')}>MF1</strong>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <ul className={cx('menu_list')}>
        <li className={cx('menu')}>
          <Link 
            to={URLInfo.getProfileUserUrl(userInfo?.simple_profile.name || '')} 
            className={cx('link')}
          >
            내 프로필
          </Link>
        </li> 
        <li className={cx('menu')}>
          <Link to={URLInfo.ACTIVITY} className={cx('link')}>나의 활동</Link>
        </li>
        <li className={cx('menu')}>
          <Link to={URLInfo.USER_EDIT} className={cx('link')}>프로필 편집</Link>
        </li>
        <li className={cx('menu')}>
          <button type="button" className={cx('link')} onClick={handleClickLogoutBtn}>
            {loginText}
          </button>
        </li>
      </ul>
      {showWithdrewLayer && (
        <LayerContainer onClose={() => {
          clearTransferModal();
        }} 
        useDimmedColor={true}
        >
          <Layer 
            title={'출금'}
            buttonText={withdrawButtonText}
            onClickButton={handleWithdrawButtonClick}
          >
            <div className={cx('withdrew_wrap')}>
              <div className={cx('guide')}>
                이더리움 네트워크를 활용하는 지갑주소인지 확인하세요. <br />
                잘못 전송 시 책임지지 않습니다.
              </div>
              <div className={cx('input_group')}>
                <div className={cx('input_box')}>
                  <Input 
                    placeholder={'지갑 주소를 입력해주세요'} 
                    className={'input'} 
                    onChange={handleChangeWalletAddress} 
                    value={address} 
                  />
                </div>
                <div className={cx('input_box')}>
                  <InputPrice 
                    placeholder={'토큰 개수'} 
                    className={'input_blockchain'} 
                    setValue={setPrice} 
                    type={currencyType} 
                    setType={setCurrencyType} 
                    value={price} 
                  />
                </div>
                {
                  authenticationInput && 
                    <div className={cx('input_box')}>
                      <Input 
                        placeholder={'인증번호를 입력해주세요'} 
                        className={'input'} 
                        onChange={handleChangeAuthenticationNumber} 
                        value={authenticationNumber} 
                      />
                      <div className={cx('timer')}>
                        {minutes}:{seconds < 10 ? `0${seconds}` : seconds}
                      </div>
                    </div>
                }
              </div>
            </div>
          </Layer>
        </LayerContainer>
      )}
      {showWithdrewCompleteLayer && (
        <LayerContainer onClose={() => setShowWithdrewCompleteLayer(false)} useDimmedColor={true}>
          <Layer 
            title={'출금 완료'} 
            buttonText={'트렌젝션 확인하기'} 
            onClickButton={handleClickConfirmTransaction}
          >
            <HashBox address={StringUtil.summaryWalletAddress(collectionHash)} />
          </Layer>
        </LayerContainer>
      )}
    </div>
  );
};

export default ProfileModal;
