import React, { useCallback, useState, useEffect, useRef, FC } from 'react';
import { connect } from 'react-redux';
import { Input, Button, Spin, Radio, Collapse } from '@easyv/antd';
import ConfirmModal from 'components/ConfirmModal';
import SwitchWithLoading from 'components/SwitchWithLoading';
import { updateScreenShare } from 'models/screens';
import styles from './ShareScreenModal.less';
import { publishScreenToApp, getApps } from 'models/app';
import { useMousetrapPause } from 'components/easyUse';
import classnames from 'classnames';
import { Upload } from '@easyv/react-gui';
import { uploadAssets } from 'utils/upload';
import { getSize, pwdValidate ,getAssetsUrl} from 'utils/utils';
import Publish from './Publish';
import { QuestionCircleOutlined } from '@ant-design/icons';
import message from 'components/message';
import { Course } from 'models/course.types';
import EasyvTooltip from 'components/EasyvTooltip';
import { useAuth } from 'components/easyUse';
const { Panel } = Collapse;

function imgValidate(url) {
  return url ? /(https?:[^:<>"]*\/)([^:<>"]*)(\.((png!thumbnail)|(png)|(jpg)))/.test(url) : true;
}

const ShareScreenModal: FC<{
  screenId: number;
  share: string | null;
  password?: string;
  token?: string;
  info: any;
  apps: { id: number; name: string }[];
  sharedApps: number[];
  dispatch: any;
  course: {
    [x: string]: any;
  };
  userInfo: any;
  screenName?: string;
  theme?: 'black' | 'white';
  children: React.ReactNode;
}> = ({
  screenId,
  share,
  course,
  password,
  token = '',
  userInfo,
  info,
  children,
  apps = [],
  screenName = document.title,
  theme = 'white',
  sharedApps = [],
  dispatch
}) => {
  const linkRef = useRef<Input>(null);
  const [visible, setVisible] = useState(false);
  const [sharePassword, setSharePassword] = useState('');
  const [loading, setLoading] = useState(false);
  const [radioValue, setRadioValue] = useState(-1);
  const [oldPassword, setOldPassword] = useState(''); //旧密码
  const [shareInfo, setShareInfo] = useState<{
    title: string;
    description: string;
    thumb: string;
  }>({
    title: '',
    description: '',
    thumb: ''
  });
  const { checkAuth } = useAuth();
  const { LOCAL } = window.appConfig;
  const [sharInfoSwitch, setSharInfoSwitch] = useState<boolean>(false);
  const isTokenPublish = LOCAL || checkAuth('isTokenPublish');
  const isShareInfo = !LOCAL ? checkAuth('isShareInfo') : false;
  const [uploadLoading, setUploadLoading] = useState(false);

  useEffect(() => {
    if (token && !password) {
      setRadioValue(0);
    } else if (!token && password) {
      setRadioValue(1);
    }
  }, [token, password]);

  const shareUrl = !!share
    ? `${window.location.origin}${BASENAME}/shareScreen/${window.btoa(JSON.stringify({ screenId: screenId }))}`
    : undefined;

  useEffect(() => {
    if (visible && apps.length === 0) {
      dispatch(getApps());
    }
  }, [visible]);

  useEffect(() => {
    if (visible) {
      const _info = info
        ? info
        : {
            title: '',
            description: '',
            thumb: ''
          };
      setShareInfo(_info);
      const _switch = !!(_info.title || _info.description || _info.thumb);
      setSharInfoSwitch(_switch);
    }
  }, [info, visible]);

  useMousetrapPause(visible);

  const handleClose = useCallback(() => {
    setVisible(false);
  }, []);

  const handleCopyLink = () => {
    linkRef.current?.select();
    document.execCommand('Copy');
    message.success('复制成功');
  };

  const handleShareChange = async (checked: boolean) => {
    setLoading(true);
    const result = await dispatch(updateScreenShare({ id: screenId, needToken: !!token, share: checked, needPassword: false, shareInfo }));
    setLoading(false);
    return result;
  };

  const handleNeedPassword = async (needPassword) => {
    setLoading(true);
    if (!needPassword) {
      setSharePassword('');
      await dispatch(updateScreenShare({ id: screenId, needToken: false, share: true, needPassword, sharePassword: null, shareInfo }));
    } else {
      await dispatch(
        updateScreenShare({ id: screenId, needToken: false, share: true, needPassword: true, sharePassword: null, shareInfo })
      );
    }
    setLoading(false);
  };

  const appShareChange = async ({ appId, publish }) => {
    setLoading(true);
    await dispatch(publishScreenToApp({ screenId, publish, appId }));
    setLoading(false);
  };

  useEffect(() => {
    if (password) {
      setSharePassword(password);
      setOldPassword(password);
    }
  }, [password]);

  const onSharePasswordBlur = async () => {
    // 新旧密码比对是为了，防止用户无操作。仅仅失去焦点即更新密码，不可理。
    if (!password || oldPassword === sharePassword) {
      return;
    }

    if (!pwdValidate(sharePassword)) {
      message.error('请输入字母或数字,长度6-20位');
      setSharePassword(password);
      return;
    }
    setLoading(true);
    await dispatch(
      updateScreenShare({ shareInfo, needToken: !!token, id: screenId, share: true, needPassword: !!password, sharePassword })
    );
    setLoading(false);
  };

  type shareInKey = 'title' | 'description' | 'thumb';
  const updateShareInfo = async (value, type: shareInKey) => {
    if (type === 'thumb') {
      if (!imgValidate(value)) {
        setShareInfo({
          ...shareInfo,
          thumb: ''
        });
        message.error('请上传图片格式png、jpg类型');
        return false;
      }
    }
    if (value === info[type]) {
      return;
    }
    const data = {
      ...shareInfo
    };
    data[type] = value;

    setLoading(true);
    await dispatch(
      updateScreenShare({
        id: screenId,
        share: true,
        shareInfo: data,
        needPassword: !!password,
        needToken: !!token
      })
    );
    setLoading(false);
  };

  const uplodaChange = async (data: any) => {
    if (!data) {
      setShareInfo({
        ...shareInfo,
        thumb: ''
      });
      updateShareInfo('', 'thumb');
      return false;
    }
    const imageMaxSize = 500 * 1024;
    if (data.file.size > imageMaxSize) {
      // message.destroy();
      message.warning(`图片不能超过${getSize(imageMaxSize)}`);
      return false;
    }
    await setUploadLoading(true);
    const result = await uploadAssets({
      path: data.file.name,
      file: data.file
    });
    await setUploadLoading(false);
    if (!result) {
      return false;
    }
    const url =getAssetsUrl(result);
    setShareInfo({
      ...shareInfo,
      thumb: url
    });
    updateShareInfo(url, 'thumb');
  };

  const onRadioChange = async (e) => {
    const radioV = e.target.value;
    setRadioValue(radioV);
    if (share !== undefined) {
      const param = {
        id: screenId,
        share: !!share,
        needPassword: false,
        needToken: false,
        shareInfo
      };
      if (radioV) {
        // 密码
        param.needPassword = true;
      } else {
        // token
        param.needToken = true;
      }
      setLoading(true);
      await dispatch(updateScreenShare(param));
      setLoading(false);
    }
  };

  const shareInfoChange = (value, type: shareInKey) => {
    if (type) {
      const data = {
        ...shareInfo
      };
      data[type] = value;
      setShareInfo(data);
    }
  };

  const trimVal = (e) => {
    return e && e.target.value.trim();
  };
  const _course = course[Course.SHARE_TOKEN];
  const _w = { width: 196 };
  const encryptionSwitch = !!password || !!token;
  return (
    <span className={styles.share}>
      <span onClick={() => setVisible(true)}>{children}</span>
      <ConfirmModal
        destroyOnClose={true}
        theme={theme}
        visible={visible}
        title="发布"
        onClose={handleClose}
        contentStyle={{ padding: 0 }}
        width={530}>
        <Spin spinning={loading} style={{ background: 'rgba(35,38,48,0.9)' }}>
          <div style={{ padding: '36px 36px 28px 36px' }}>
            {!share ? (
              <Publish onPublish={handleShareChange} theme={theme} />
            ) : (
              <>
                <div className={classnames([styles.item, styles[theme]])}>
                  <label className={styles.label}>发布</label>
                  <span>
                    <SwitchWithLoading checked={!!share} onChange={handleShareChange} />
                  </span>
                </div>
                <div className={classnames([styles.item, styles[theme]])}>
                  <label className={styles.label}>投屏链接</label>
                  <div style={{ flex: 1, display: 'flex', alignItems: 'center' }}>
                    <div style={{ flex: 1, marginRight: 16 }}>
                      <Input value={shareUrl} id="share" readOnly placeholder="发布获取投屏链接" />
                    </div>
                    {/* 用于复制 */}
                    <Input
                      value={`${shareUrl}?timeStamp=${new Date().valueOf().toString(16)}${token ? '&secretKey=' + token : ''}${
                        sharePassword ? `（密码：${sharePassword}）` : ' '
                      }《${screenName}》`}
                      id="share_all"
                      readOnly
                      style={{ position: 'absolute', width: 300, top: -3000 }}
                      ref={linkRef}
                    />
                    <Button type="primary" onClick={handleCopyLink} disabled={!share} id="introStep11">
                      {!!password ? '复制链接及密码' : !!token ? '复制链接及密钥' : '复制'}
                    </Button>
                  </div>
                </div>

                <div className={classnames([styles.item, styles[theme]])}>
                  <label className={styles.label}>加密分享</label>
                  <SwitchWithLoading checked={encryptionSwitch} onChange={handleNeedPassword} />
                </div>

                {encryptionSwitch && (
                  <div className={classnames([styles.item, styles[theme]])}>
                    <label className={classnames(styles.label, styles[isTokenPublish ? 'clearAfter' : ''])}>
                      {!isTokenPublish && '密码'}
                    </label>
                    <div className={styles.encryption}>
                      <div>
                        {isTokenPublish && (
                          <Radio.Group onChange={onRadioChange} value={radioValue}>
                            <Radio value={1}>密码</Radio>
                            <Radio value={0}>Token验证</Radio>
                          </Radio.Group>
                        )}
                        {isTokenPublish && _course && (
                          <a target="_blank" href={_course.courseUrl} style={{ marginLeft: -8 }}>
                            使用教程 &gt;
                          </a>
                        )}
                      </div>
                      <div style={{ marginTop: 5 }}>
                        {radioValue ? (
                          <Input
                            value={loading ? 'Loading...' : sharePassword}
                            onChange={(e) => setSharePassword(trimVal(e))}
                            onBlur={onSharePasswordBlur}
                            id="sharePassword"
                            readOnly={!password}
                          />
                        ) : (
                          <>
                            <Input value={loading ? 'Loading...' : token} readOnly />
                          </>
                        )}
                      </div>
                    </div>
                  </div>
                )}

                {apps.length && checkAuth('toSpaceship') ? (
                  <div className={classnames([styles.item, styles[theme]])}>
                    <label className={styles.label}>开放应用</label>
                    {apps.map((d) => (
                      <span className={styles.app} key={d.id}>
                        <SwitchWithLoading
                          checked={sharedApps.includes(d.id)}
                          onChange={(publish) => appShareChange({ appId: d.id, publish })}
                        />
                        <span style={{ marginLeft: 4 }}>{d.name}</span>
                      </span>
                    ))}
                  </div>
                ) : null}

                {isShareInfo && (
                  <Collapse
                    onChange={(keys) => {
                      setSharInfoSwitch(!!keys.length);
                    }}
                    expandIconPosition="right"
                    className={classnames(styles.collapse, styles[theme])}
                    activeKey={sharInfoSwitch ? ['1'] : []}
                    ghost>
                    <Panel
                      header={
                        <div className={styles.shareInfo}>
                          <EasyvTooltip title="分享信息为空默认读取项目名称及封面">
                            <QuestionCircleOutlined style={{ marginRight: '5px' }} className="whiteHover" color="#fff" />
                          </EasyvTooltip>
                          <span>分享信息</span>
                        </div>
                      }
                      key="1">
                      <div className={styles.itemBox}>
                        <div className={classnames([styles.item, styles[theme]])}>
                          <label className={styles.label}>标题</label>
                          <Input
                            maxLength={20}
                            style={{ ..._w }}
                            value={shareInfo.title}
                            onChange={(e) => {
                              shareInfoChange(e.target.value, 'title');
                            }}
                            onBlur={(e) => {
                              updateShareInfo(e.target.value, 'title');
                            }}
                            onPressEnter={(e: any) => {
                              e.target.blur();
                            }}
                            placeholder="请输入标题"
                          />
                        </div>
                        <div className={classnames([styles.item, styles[theme]])}>
                          <label className={styles.label}>描述</label>
                          <Input
                            maxLength={128}
                            style={{ ..._w }}
                            value={shareInfo.description}
                            onChange={(e) => {
                              shareInfoChange(e.target.value, 'description');
                            }}
                            onBlur={(e) => {
                              updateShareInfo(e.target.value, 'description');
                            }}
                            onPressEnter={(e: any) => {
                              e.target.blur();
                            }}
                            placeholder="请输入描述"
                          />
                        </div>
                        <div className={classnames([styles.item, styles[theme]])}>
                          <label className={styles.label}>图片</label>
                          <Input
                            style={{ ..._w }}
                            value={shareInfo.thumb}
                            onChange={(e) => {
                              const value = e.target.value;
                              imgValidate(value) && shareInfoChange(value, 'thumb');
                            }}
                            onBlur={(e) => {
                              const value = e.target.value;
                              if (imgValidate(value)) {
                                updateShareInfo(value, 'thumb');
                              } else {
                                message.error('请上传图片格式png、jpg类型');
                                shareInfoChange('', 'thumb');
                              }
                            }}
                            onPressEnter={(e: any) => {
                              e.target.blur();
                            }}
                            placeholder="图片地址"
                          />
                        </div>
                        <div className={styles.imageUpload}>
                          <Upload
                            showDownload={false}
                            accept={'image/jpg,image/png'}
                            value={shareInfo?.thumb}
                            size={500 * 1024}
                            content={
                              <div style={{ overflow: 'hidden', height: '100%' }}>
                                <img style={{ width: '100%', height: '100%', objectFit: 'contain' }} src={shareInfo.thumb} alt="" />
                              </div>
                            }
                            changeError={(msg, file) => {
                              msg && message.error(msg);
                            }}
                            loading={uploadLoading}
                            customRequest={uplodaChange}
                            onChange={uplodaChange}
                          />

                          {!shareInfo?.thumb ? (
                            <div className={styles.tip}>
                              <span>请上传小于500K</span>
                              <span>分辨率128*128</span>
                              <span>JPG/PNG格式图片</span>
                            </div>
                          ) : null}
                        </div>
                      </div>
                    </Panel>
                  </Collapse>
                )}
              </>
            )}
          </div>
        </Spin>
      </ConfirmModal>
    </span>
  );
};

const mapStateToProps = ({ apps, user, course }) => {
  const { userInfo } = user;
  return {
    apps: apps.list,
    userInfo,
    course
  };
};

export default connect(mapStateToProps)(ShareScreenModal);
