import { Button, ButtonProps, ITouchEvent } from '@tarojs/components';

import classNames from 'classnames';
import { useCallback, useState } from 'react';

import { AgreementPopup } from '@/components/agreement-popup';
import LoginDialog from '@/components/login-dialog';
import useUserInfo from '@/hooks/use-user-info';
import { getAgreementSigned, isNeedLogin, requestUserInfo, setAgreementSigned } from '@/utils/user';

import './index.less';

export enum BindPhoneStatus {
  Success,
  Cancel,
  Error,
}

export interface ILoginButtonProps extends ButtonProps {
  needPhone?: boolean;
  needRefresh?: boolean;
  onRefresh?: (() => void) | (() => Promise<void>);
  needAssignment?: boolean;
}

const PREFIX = 'login-button';

function LoginButton(props: ILoginButtonProps) {
  const { className, children, needPhone, onRefresh, onClick, needRefresh, ...otherProps } = props;
  const userInfo = useUserInfo();
  const [loginVisible, setLoginVisible] = useState(false);
  const [assignVisible, setAssignVisible] = useState(false);
  const needLogin = isNeedLogin(userInfo);
  // 点击按钮时，协议同意也手机也授权了 -> 下一步
  //
  // 点击按钮时，协议同意但是手机授权没给 ->  弹登录
  //   -> 如果授权了手机号就进行下一步
  //   -> 不给授权没下一步
  //
  // 点击按钮时，协议不同意 ->  弹协议窗口
  //   -> 如果同意就进行下一步
  //   -> 不同意没下一步
  const handleClick = useCallback(
    (e: ITouchEvent) => {
      if (!getAgreementSigned()) {
        setAssignVisible(true);
      } else if (needLogin) {
        setLoginVisible(true);
      } else if (onClick) {
        onClick(e);
      }
    },
    [needLogin, onClick]
  );

  const handleConfirm = useCallback(
    (e: ITouchEvent) => {
      setAssignVisible(false);
      setAgreementSigned(true);
      if (onClick) {
        onClick(e);
      }
    },
    [onClick]
  );

  const handleCancel = useCallback(() => {
    setAgreementSigned(false);
    setAssignVisible(false);
  }, []);

  const handleLoginSuccess = useCallback(
    async e => {
      setLoginVisible(false);
      if (needRefresh) {
        requestUserInfo();
        onRefresh && (await onRefresh());
      }
      onClick?.(e);
    },
    [needRefresh, onClick]
  );

  return (
    <>
      <Button {...otherProps} className={classNames(PREFIX, className)} onClick={handleClick}>
        {children}
      </Button>
      <AgreementPopup
        open={assignVisible}
        onCancel={handleCancel}
        onConfirm={handleConfirm}
        needBindPhone={needLogin}
      />
      {loginVisible && (
        <LoginDialog onCancel={() => setLoginVisible(false)} onSuccess={handleLoginSuccess} needPhone={needPhone} />
      )}
    </>
  );
}

export default LoginButton;
