import React, { useEffect, useState } from 'react';
import classNames from 'classnames/bind';
import styles from './SaleButtonContainer.scss';
import { EItemType, ECurrencyType, ESaleType, ESaleStatus } from '@src/constants/Enums';
import APIs from '@src/api/APIs';
import URLInfo from '@src/constants/URLInfo';
import LayerContainer from '@src/containers/common/LayerContainer';
import Layer from '../Layer';
import InputPrice from '@src/components/common/InputPrice';
import HashBox from '@src/components/common/HashBox';
import { useDispatch, useSelector } from 'react-redux';
import StringUtil from '@src/utils/StringUtil';
import useLogin from '@src/hooks/useLogin';
import { useHistory } from 'react-router-dom';
import { fetchUserInfo } from '@src/store/reducers/UserReducer';
import { toggleLoadingState } from '@src/store/reducers/NetworkLoadingReducer';
import NumberUtil from '@src/utils/NumberUtil';

const cx = classNames.bind(styles);

interface IButtonProps {
  text: string;
  onClick?: () => void;
  useColor?: boolean;
  isDisabled?: boolean;
};

const Button: React.FC<IButtonProps> = ({ text, onClick, useColor, isDisabled }) => {
  return (
    <button
      type="button"
      className={cx('btn', useColor && 'btn_color')}
      onClick={onClick}
      aria-disabled={isDisabled}
      disabled={isDisabled}
    >{text}
    </button>
  );
};

interface IButtonContainer {
  saleType: ESaleType;
  isOwner: boolean;
  isTimeout: boolean;
  highestPrice: number;
  currency: ECurrencyType;
  myBiddingPrice: number;
  setShowBidLayer: (showBidLayer: boolean) => void;
  setShowBuyNowLayer: (showBuyLayer: boolean) => void;
  status: ESaleStatus;
  tokenId: number;
}

const refreshPage = () => window.location.replace(window.location.href);

const ButtonContainer: React.FC<IButtonContainer> = ({ saleType, isOwner, isTimeout, highestPrice, currency, myBiddingPrice, setShowBidLayer, setShowBuyNowLayer, status, tokenId }) => {
  const history = useHistory();
  const dispatch = useDispatch();
  const id = URLInfo.getId();
  const { checkLogin } = useLogin();

  const handleBid = () => {
    if (!checkLogin()) {
      return;
    }
    setShowBidLayer(true);
  };

  const handleClickBuy = () => {
    if (!checkLogin()) {
      return;
    }
    setShowBuyNowLayer(true);
  };

  const handleCancleBid = async () => {
    await APIs.cancelBid(id).then(() => {
      alert('입찰이 취소되었습니다.');
      refreshPage();
    });
  };

  const saleHighestPrice = async () => {
    if (!highestPrice || !currency) {
      alert('입찰을 기다리고 있습니다.');
      return;
    }

    dispatch(toggleLoadingState());
    await APIs.saleHighestPrice({
      bid_price: highestPrice,
      currency,
      sale_id: id
    }).then(() => {
      dispatch(toggleLoadingState());
      alert('최고가에 판매되었습니다.');
      refreshPage();
    }).catch(() => {
      dispatch(toggleLoadingState());
      alert('최고가 판매에 실패했습니다. 잠시 후 다시 시도해주세요.');
    });
  };

  const closeSell = async () => {
    await APIs.changeSaleStatus(id).then(() => {
      alert('판매가 종료되었습니다.');
      refreshPage();
    });
  };

  const handleShare = () => {
    navigator.clipboard.writeText(window.location.href).then(() => {
      alert('복사되었습니다.');
    });
  };

  const handleResale = () => {
    history.push(URLInfo.getResaleUrl(tokenId));
  };

  const isOnGoing = status === ESaleStatus.ON_GOING;

  {/* ------------ 판매자 ------------- */ }
  if (isOwner) {
    if (isOnGoing) {
      // 지정가
      if (saleType === ESaleType.FIXED) {
        return (
          <div className={cx('btn_area')}>
            {/* <div className={cx('btn_wrap')}>
              <Button text='공유하기' onClick={handleShare} />
            </div> */}
            <div className={cx('btn_wrap')}>
              <Button text='판매 취소' useColor={true} onClick={closeSell} />
            </div>
          </div>
        );
      }

      // 입찰가
      if (saleType === ESaleType.AUCTION && highestPrice) {
        return (
          <div className={cx('btn_area')}>
            {/* <div className={cx('btn_wrap')}>
              <Button text='공유하기' onClick={handleShare} />
            </div> */}
            {!!highestPrice && (
              <div className={cx('btn_wrap')}>
                <Button text='최고가에 판매하기' useColor={true} onClick={saleHighestPrice} />
              </div>
            )}
          </div>
        );
      }

      // 타임옥션 & 종료
      if (saleType === ESaleType.TIME && isTimeout && highestPrice) {
        return (
          <div className={cx('btn_area')}>
            {/* <div className={cx('btn_wrap')}>
              <Button text='공유하기' onClick={handleShare} />
            </div> */}
            <div className={cx('btn_wrap')}>
              <Button text='최고가에 판매하기' onClick={saleHighestPrice} />
            </div>
          </div>
        );
      }

      // 타임옥션 & 진행중
      if (saleType === ESaleType.TIME && !highestPrice) {
        return (
          <div className={cx('btn_area')}>
            {/* <div className={cx('btn_wrap')}>
              <Button text='공유하기' onClick={handleShare} />
            </div> */}
            <div className={cx('btn_wrap')}>
              <Button text='판매 취소' useColor={true} onClick={closeSell} />
            </div>
          </div>
        );
      }

      return (
        <div className={cx('btn_area')}>
          {/* <div className={cx('btn_wrap')}>
            <Button text='공유하기' onClick={handleShare} />
          </div> */}
        </div>
      );
    } else {
      // 판매 종료
      return (
        <div className={cx('btn_area')}>
          {/* <div className={cx('btn_wrap')}>
            <Button text='공유하기' onClick={handleShare} />
          </div> */}
          <div className={cx('btn_wrap')}>
            <Button text='판매 재등록' useColor={true} onClick={handleResale} />
          </div>
        </div>
      );
    }
  } else {
    {/* ------------ 소비자 ------------- */ }
    // 판매 종료
    if (!isOnGoing) {
      return (
        <div className={cx('btn_area')}>
          {/* <div className={cx('btn_wrap')}>
            <Button text='공유하기' onClick={handleShare} />
          </div> */}
        </div>
      );
    }
    // 지정가
    if (saleType === ESaleType.FIXED) {
      return (
        <div className={cx('btn_area')}>
          {/* <div className={cx('btn_wrap')}>
            <Button text='공유하기' onClick={handleShare} />
          </div> */}
          <div className={cx('btn_wrap')}>
            <Button text='즉시 구매하기' useColor={true} onClick={handleClickBuy} />
          </div>
        </div>
      );
    }

    // 입찰가
    if (saleType === ESaleType.AUCTION && !myBiddingPrice) {
      return (
        <div className={cx('btn_area')}>
          {/* <div className={cx('btn_wrap')}>
            <Button text='공유하기' onClick={handleShare} />
          </div> */}
          <div className={cx('btn_wrap')}>
            <Button text='입찰하기' useColor={true} onClick={handleBid} />
          </div>
        </div>
      );
    }

    // 타임옥션 & 종료
    const text = (highestPrice && isOnGoing) ? '소유자의 확인을 기다리는 중입니다.' : '이미 종료된 경매입니다';

    if (saleType === ESaleType.TIME && isTimeout) {
      return (
        <div className={cx('btn_area')}>
          <div className={cx('btn_wrap')}>
            <Button text={text} isDisabled={true} />
          </div>
        </div>
      );
    }

    // (입찰가 || 타임옥션)
    if ((saleType === ESaleType.AUCTION || saleType === ESaleType.TIME)) {
      // 내 입찰가 있을 때
      if (myBiddingPrice) {
        return (
          <div className={cx('btn_area')}>
            <div className={cx('btn_wrap')}>
              <Button text='내 입찰가 취소' onClick={handleCancleBid} />
            </div>
            <div className={cx('btn_wrap')}>
              <Button text='입찰하기' useColor={true} onClick={handleBid} />
            </div>
          </div>
        );
      } else {
        // 내 입찰가 없을 때
        return (
          <div className={cx('btn_area')}>
            <div className={cx('btn_wrap')}>
              <Button text='입찰하기' onClick={handleBid} />
            </div>
          </div>
        );
      }
    }

    return (
      <div className={cx('btn_area')}>
        {/* <div className={cx('btn_wrap')}>
          <Button text='공유하기' onClick={handleShare} />
        </div> */}
      </div>
    );
  }
};

interface IOwnProps {
  type: EItemType;
  saleType: ESaleType;
  isOwner: boolean;
  isTimeout: boolean;
  highestPrice: number;
  currency: ECurrencyType;
  name: string;
  artist_name: string;
  myBiddingPrice: number;
  price: number;
  status: ESaleStatus;
  tokenId: number;
  startPrice: number;
};

const SaleButtonContainer: React.FC<IOwnProps> = (props) => {
  const id = URLInfo.getId();
  const dispatch = useDispatch();
  const { userInfo } = useSelector(store => store.user);

  const avaliablePrice = Number(userInfo?.simple_profile[`${props.currency}_balance`]);
  // 입찰하기
  const [showBidLayer, setShowBidLayer] = useState<boolean>(false);
  const [bidPrice, setBidPrice] = useState<string>('');

  const handleClickBid = async () => {
    const price = Number(bidPrice);
    if (props.saleType === ESaleType.AUCTION) {
      if (props.highestPrice && props.highestPrice > price) {
        alert('입찰 금액이 입찰가보다 낮습니다.');
        return;
      }
    }

    if (props.saleType === ESaleType.TIME) {
      const minPrice = props.highestPrice ? props.highestPrice : props.startPrice;

      if (minPrice > price) {
        alert('입찰 금액이 입찰가보다 낮습니다.');
        return;
      }
    }

    if (price > avaliablePrice || Number(userInfo?.settings.network_commission) > Number(userInfo?.simple_profile.available_eth_balance)) {
      alert('가용 잔고가 부족합니다.');
      return;
    }

    await APIs.saleBid({
      bid_price: price,
      currency: props.currency,
      sale_id: id
    }).then(() => {
      setShowBidLayer(false);
      refreshPage();
    }).catch(() => {
      if (props.myBiddingPrice) {
        alert('입찰가가 있습니다. 새로 입찰을 원할 경우 입찰을 취소해주세요.');
      }
    });
  };

  // 즉시구매 레이어
  const [showBuyNowLayer, setShowBuyNowLayer] = useState<boolean>(false);

  const handleClickBuy = async () => {
    if (props.price > avaliablePrice || Number(userInfo?.settings.network_commission) > Number(userInfo?.simple_profile.available_eth_balance)) {
      alert('가용 잔고가 부족합니다.');
      return;
    }

    dispatch(toggleLoadingState());
    await APIs.saleBuy({
      bid_price: props.price,
      currency: props.currency,
      sale_id: id
    }).then((res) => {
      setCollectionHash(res);
      setShowBuyNowLayer(false);
      setShowBuyCompleteLayer(true);
      dispatch(toggleLoadingState());
    }).catch(() => {
      dispatch(toggleLoadingState());
      alert('구매에 실패했습니다. 잠시 후 다시 시도해주세요.');
    });
  };

  // 구매 완료
  const [collectionHash, setCollectionHash] = useState<string>('');

  const handleClickTransaction = () => {
    setShowBuyCompleteLayer(false);
    window.open(URLInfo.getTransactionUrl(collectionHash), '_blank');
    refreshPage();
  };

  // 구매완료 레이어
  const [showBuyCompleteLayer, setShowBuyCompleteLayer] = useState<boolean>(false);
  const handleClickBuyCompleteLayer = () => {
    setShowBuyCompleteLayer(false);
    refreshPage();
  };

  useEffect(() => {
    if (showBidLayer || showBuyNowLayer) {
      dispatch(fetchUserInfo());
    }
  }, [showBidLayer, showBuyNowLayer]);

  let currency
  if(props.currency !== undefined) {
    currency = props.currency.toUpperCase();
  }

  let _currency = ""
  if (currency === "MR") {
    _currency = "MTRA"
  }
  if (currency === "MF") {
    _currency = "MF1"
  }
  if (currency === "ETH") {
    _currency = "ETH"
  }
  

  return (
    <div className={cx('sale_button_container')}>
      <ButtonContainer {...props} setShowBidLayer={setShowBidLayer} setShowBuyNowLayer={setShowBuyNowLayer} />
      {/* 입찰하기 레이어 */}
      {showBidLayer && (
        <LayerContainer onClose={() => setShowBidLayer(false)} useDimmedColor={true}>
          <Layer title={'입찰하기'} buttonText={'입찰하기'} onClickButton={handleClickBid}>
            <div className={cx('buy_wrap')}>
              <div className={cx('buy_area')}>
                <div className={cx('title')}>아이템</div>
                <div className={cx('info')}>{props.name}</div>
              </div>
              <div className={cx('buy_area')}>
                <div className={cx('title')}>작가</div>
                <div className={cx('info')}>{props.artist_name}</div>
              </div>
              <div className={cx('price_area')}>
                <div className={cx('input_box')}>
                  <InputPrice placeholder={'입찰가'} type={props.currency} setValue={setBidPrice} useSelectBox={false} value={bidPrice} />
                </div>
                <div className={cx('detail_box')}>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>내 잔고</div>
                    <div className={cx('info')}>{NumberUtil.formatBalance(userInfo?.simple_profile[`${props.currency}_balance`])} {_currency}</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>가용 잔고</div>
                    <div className={cx('info')}>{NumberUtil.formatBalance(userInfo?.simple_profile[`available_${props.currency}_balance`])} {_currency}</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>플랫폼 이용료</div>
                    <div className={cx('info')}>{userInfo?.settings.service_commission}%</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>네트워크 수수료</div>
                    <div className={cx('info')}>gas fee {userInfo?.settings.network_commission} ETH</div>
                    <small style={{color: 'red'}}>*이더리움 가스비는 정해진 것이 없으므로 충분하게 사전 입금 필요. 실제 거래 시 대부분 더 낮게 소요됨.</small>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>합계</div>
                    <div className={cx('info')}>{bidPrice} {_currency}</div>
                  </div>
                  
                </div>
              </div>
            </div>
          </Layer>
        </LayerContainer>
      )}
      {/* 즉시구매 레이어 */}
      {showBuyNowLayer && (
        <LayerContainer onClose={() => setShowBuyNowLayer(false)} useDimmedColor={true}>
          <Layer title={'즉시구매'} buttonText={'구매하기'} onClickButton={handleClickBuy}>
            <div className={cx('buy_wrap')}>
              <div className={cx('buy_area')}>
                <div className={cx('title')}>아이템</div>
                <div className={cx('info')}>{props.name}</div>
              </div>
              <div className={cx('buy_area')}>
                <div className={cx('title')}>작가</div>
                <div className={cx('info')}>{props.artist_name}</div>
              </div>
              <div className={cx('price_area')}>
                <div className={cx('detail_box')}>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>내 잔고</div>
                    <div className={cx('info')}>{userInfo?.simple_profile[`${props.currency}_balance`]} {_currency}</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>가용 잔고</div>
                    <div className={cx('info')}>{userInfo?.simple_profile[`available_${props.currency}_balance`]} {_currency}</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>플랫폼 이용료</div>
                    <div className={cx('info')}>{userInfo?.settings.service_commission}%</div>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>네트워크 수수료</div>
                    <div className={cx('info')}>gas fee {userInfo?.settings.network_commission} ETH</div>
                    <small style={{ color: 'red' }}>*이더리움 가스비는 정해진 것이 없으므로 충분하게 사전 입금 필요. 실제 거래 시 대부분 더 낮게 소요됨.</small>
                  </div>
                  <div className={cx('detail')}>
                    <div className={cx('title')}>합계</div>
                    <div className={cx('info')}>{props.price} {_currency}</div>
                  </div>
                </div>
              </div>
            </div>
          </Layer>
        </LayerContainer>
      )}
      {/* 구매 완료 레이어 */}
      {showBuyCompleteLayer && (
        <LayerContainer onClose={handleClickBuyCompleteLayer} useDimmedColor={true}>
          <Layer title={'구매 완료'} buttonText={'트렌젝션 확인하기'} onClickButton={handleClickTransaction}>
            <HashBox address={StringUtil.summaryWalletAddress(collectionHash)} />
          </Layer>
        </LayerContainer>
      )}
    </div>
  );
};

export default SaleButtonContainer;
