import React, { Component, useMemo } from 'react';
import PropTypes from 'prop-types';
import { useBarStatus } from '../utils';
import '../style/camera-control.less';
import { Slider, message } from 'antd';

import { BaseStore, LMConfig } from '@zenview/micro-basic-library';
import IconFont from '../../../themeComponents/IconFont';
import Service from '../service';

const DIRECTION_DIC = ['up', 'rightup', 'right', 'rightdown', 'down', 'leftdown', 'left', 'leftup'];
const MOUSE_DIRECTION_DIC = ['mouse_up', 'mouse_right', 'mouse_down', 'mouse_left'];
const ZOOM_DIC = ['zoomin', 'zoomout'];
const FOCUS_DIC = ['focusin', 'focusout'];
const { BSConfig } = LMConfig;
// 停止-延迟常量-从系统配置获取
const DIRECTION_DELAY_TIME = BSConfig?.player?.PTZ?.DIRECTION_DELAY_TIME || 100;
const ZOOM_DELAY_TIME = BSConfig?.player?.PTZ?.ZOOM_DELAY_TIME || 100;
const FOCUS_DELAY_TIME = BSConfig?.player?.PTZ?.FOCUS_DELAY_TIME || 100;
const STOP_AFTER_MOVEDELAY_TIME = BSConfig?.player?.PTZ?.STOP_AFTER_MOVEDELAY_TIME || 2000;
const DIRECTION_STOP_COUNT = BSConfig?.player?.PTZ?.DIRECTION_STOP_COUNT || 1;
const ZOOM_STOP_COUNT = BSConfig?.player?.PTZ?.ZOOM_STOP_COUNT || 1;
const FOCUS_STOP_COUNT = BSConfig?.player?.PTZ?.FOCUS_STOP_COUNT || 1;

class CameraControlView extends Component {
  static contextTypes = {
    fileData: PropTypes.object,
  };
  /**
   * 初始化-step1
   // 国标摄像机
    // 控制速度0-3
    // 不能控制焦距，只能步骤控制（点控）

    // SDK
    // 控制速度0-8
    // 可以控制云台转动和焦距，持续控制

    // CIG
    // 控制速度1-3
    // 可以控制云台转动和焦距，持续控制


    // 非国标
    // 控制速度0-255
    // 上下控制较明显、左右不明显
    // 不能控制焦距，只能步骤控制（点控）
   * @param {*} props 
   */
  constructor(props) {
    super(props);
    this.isGB = false;
    this.CIG = false;
    this.isHKnvr = false;//海康NVR接入sourceFrom: 115921
    this.mouseZoomType = null;
    this.mouseZoomTimer = null;
    this.type = '';
    [].concat(DIRECTION_DIC, ZOOM_DIC, FOCUS_DIC, MOUSE_DIRECTION_DIC).forEach((item) => {
      this[item] = React.createRef();
    });
    this.state = {
      speed: 2,
      totalSpeed: 3,
      show: false,
      operationFalg: true
    };
    this.user = BaseStore.app.userInfo;
  }

  // 初始化-step2
  componentDidMount() {
    const { deviceInfo, playBox } = this.props;
    let speed, totalSpeed;
    try {
      const accessType = deviceInfo.accessType.toLowerCase()
      if (+deviceInfo.sourceFrom === 115921) {
        this.isHKnvr = true;
        speed = 3;
        totalSpeed = 8;
      }
      if (accessType === 'gb' || (deviceInfo.extJson.cameraInfo.type && deviceInfo.extJson.cameraInfo.type.toLowerCase() === 'gb')) {
        this.isGB = true;
        speed = 2;
        totalSpeed = 3;
      }
      if (accessType === 'sdk') {
        this.isGB = true;
        speed = 3;
        totalSpeed = 8;
      }
      if (accessType === 'cig') {
        this.CIG = true;
        speed = 2;
        totalSpeed = 3;
      }
    } catch (e) {
      console.warn('fileData.extJson.cameraInfo', deviceInfo);
    }
    playBox && playBox.current.addEventListener('mousewheel', this.mousewheelFn)
    MOUSE_DIRECTION_DIC.forEach((v) => {
      this[v].current.addEventListener('mousedown', this.startDirectionHandle);
      this[v].current.addEventListener('mouseup', this.stopDirectionHandle);
    });
    this.setState({
      speed: speed ? speed : 2,
      totalSpeed: totalSpeed ? totalSpeed : 3,
      show: false,
    });
  }

  componentWillUnmount() {
    const { playBox } = this.props;
    this.mouseZoomType = null;
    this.mouseZoomTimer = null;
    MOUSE_DIRECTION_DIC.forEach((v) => {
      this[v].current?.removeEventListener('mousedown', this.startDirectionHandle);
      this[v].current?.removeEventListener('mouseup', this.stopDirectionHandle);
    });
    playBox.current?.removeEventListener('mousewheel', this.mousewheelFn)
  }

  /**
   * 点击显示时，创建云台相关事件
   */
  createPtz = () => {
    const { deviceInfo } = this.props;
    const isSDK = typeof deviceInfo.accessType === 'string' && deviceInfo.accessType.toLowerCase() === 'sdk';
    // 方向
    DIRECTION_DIC.forEach((v) => {
      this[v].current.addEventListener('mousedown', this.startDirectionHandle);
      this[v].current.addEventListener('mouseup', this.stopDirectionHandle);
    });
    // 变倍
    ZOOM_DIC.forEach((v) => {
      this[v].current.addEventListener('mousedown', this.startZoomHandle);
      this[v].current.addEventListener('mouseup', this.stopZoomHandle);
    });
    // 聚焦
    isSDK &&
      FOCUS_DIC.forEach((v) => {
        this[v].current.addEventListener('mousedown', this.startManualFocusHandle);
        this[v].current.addEventListener('mouseup', this.stopFocusHandle);
      });
  };

  mousewheelFn = (ev) => {
    var ev = ev || window.event;
    var down = true;
    down = ev.wheelDelta ? ev.wheelDelta < 0 : ev.detail > 0;
    if (down) {
      this.startMouseZoomHandle('zoomout')
    } else {
      this.startMouseZoomHandle('zoomin')
      // this.stopFocusHandle(ev)
    }
  }
  // 滚轮控制变倍-开始
  startMouseZoomHandle = (e) => {
    if (!this.mouseZoomType) {
      this.mouseZoomType = e
      this.controlPTZ(e, 'move', false)

    } else if (this.mouseZoomType === e) {
      clearTimeout(this.mouseZoomTimer)
    } else {
      this.mouseZoomType = e
      clearTimeout(this.mouseZoomTimer)
      this.stopZoomHandle(e)
      this.controlPTZ(e, 'move', false)
    }
    this.mouseZoomTimer = setTimeout(() => {
      this.stopZoomHandle(e)
      this.mouseZoomType = null
    }, 500)

  };
  // 点击隐藏时，销毁云台相关事件
  destroyPtz = () => {
    const { deviceInfo } = this.props;
    const isSDK = typeof deviceInfo.accessType === 'string' && deviceInfo.accessType.toLowerCase() === 'sdk';
    // 方向
    DIRECTION_DIC.forEach((v) => {
      this[v].current.removeEventListener('mousedown', this.startDirectionHandle);
      this[v].current.removeEventListener('mouseup', this.stopDirectionHandle);
    });
    // 变倍
    ZOOM_DIC.forEach((v) => {
      this[v].current.removeEventListener('mousedown', this.startZoomHandle);
      this[v].current.removeEventListener('mouseup', this.stopZoomHandle);
    });
    // 聚焦
    isSDK &&
      FOCUS_DIC.forEach((v) => {
        this[v].current.removeEventListener('mousedown', this.startManualFocusHandle);
        this[v].current.removeEventListener('mouseup', this.stopFocusHandle);
      });
  };

  // 方向-开始
  startDirectionHandle = (e, isStop = false) => {
    const { operationFalg } = this.state
    if (!operationFalg) {
      return
    }
    this.controlPTZ(e, 'move', true);
  };

  // 方向-停止
  stopDirectionHandle = (e) => {
    
    // if (!(this.isGB || this.CIG || this.isHKnvr)) {
    //   return;
    // }
    
    this.setState({ operationFalg: false })
    new Array(DIRECTION_STOP_COUNT).fill(0).forEach((item, index) => {
      setTimeout(() => {
        this.controlPTZ(e, 'stop', true);
      }, DIRECTION_DELAY_TIME * (index + 1));
    });
  };

  // 变倍-事件-mousedown
  startZoomHandle = (e) => {
    this.controlPTZ(e, 'move', false);
  };

  // 变倍-停止
  stopZoomHandle = (e) => {
    // if (!(this.isGB || this.CIG || this.isHKnvr)) {
    //   return;
    // }
    new Array(ZOOM_STOP_COUNT).fill(0).forEach((item, index) => {
      setTimeout(() => {
        this.controlPTZ(e, 'stop');
      }, ZOOM_DELAY_TIME * (index + 1));
    });
  };

  // 手动聚焦-开始
  startManualFocusHandle = (e) => {
    this.controlFocusCommon(e, 'manual');
  };

  // 聚焦-停止
  stopFocusHandle = (e) => {
    new Array(FOCUS_STOP_COUNT).fill(0).forEach((item, index) => {
      setTimeout(() => {
        this.controlFocusCommon(e, 'stop');
      }, FOCUS_DELAY_TIME * (index + 1));
    });
  };

  // 【公共】聚焦-请求服务逻辑
  controlFocusCommon = (e, action) => {
    const direction = e.target.dataset.type;
    const { deviceInfo } = this.props;
    Service.controlFocus({
      cid: deviceInfo.cid,
      cmd: action,
      control: {
        operation: direction,
        speed: 4,
      },
    });
  };

  /**
   * cig云台控制方法
   * @param {*} data
   */
  unifyControlCigPTZ = (data, action) => {
    const { cid, cmd, direction, speed } = data;
    Service.unifyControlPTZRaven({
      cid,
      cmd,
      speed,
      direction: cmd === 'stop' ? 'down' : direction,
    }).then((res) => {
      //如果第一次请求失败第二次弹出提示
      if (res.code !== 0 && res.message && action === 'stop') {
        message.warn(res.message);
      }
      if (action !== 'stop') {
        setTimeout(() => {
          let options = { ...data, cmd: 'stop' }
          this.unifyControlCigPTZ(options, 'stop')
        }, STOP_AFTER_MOVEDELAY_TIME)
      }

    }).finally(() => {
      if (cmd === 'stop') {
        this.setState({
          operationFalg: true
        })
      }
    });
  };
  /**
   * 国标和sdk 云台控制方法
   * @param {*} data
   */
  unifyControlPTZ = async (data, action, ind = 0) => {
    const { cid, direction, speed, turnFlag } = data;
    
    let cmd = data.cmd;
    let control = { direction: cmd === 'stop' ? 'down' : direction, speed };
    // if (!this.isGB && !this.CIG&&!this.isHKnvr) {
    //   cmd = 'direction';
    //   control = {
    //     direction,
    //     delay: 100,
    //     step: speed,
    //   };
    // }
    let unifyControlPTZOptions = {
      cid,
      cmd,
      control,
      userGrade: this.user.userGrade,
      userId: this.user.id,
      turnFlag
    }
    if (cmd === 'stop') {
      delete unifyControlPTZOptions.userGrade
      delete unifyControlPTZOptions.turnFlag
      if(!this.CIG ){
        delete unifyControlPTZOptions.control
      }
    }
    this.setState({
      operationFalg: false
    })

    try {
      let res = await Service.unifyControlPTZ(unifyControlPTZOptions)
      if (res.code === 0 && res.data === '云台当前资源已被独占') {
        return message.warn(res.data)
      }
      //如果第一次请求失败第二次弹出提示
      if (res.code !== 0 && res.message && action === 'stop') {
        message.warn(res.message);
        let newInd = ind + 1
        let options = { ...data, cmd: 'stop' }
        newInd < 3 && this.unifyControlPTZ(options, 'stop', newInd)
      }


      // if (action !== 'stop') {
      //   setTimeout(() => {
      //     let options = { ...data, cmd: 'stop' }
      //     this.unifyControlPTZ(options, 'stop')
      //   }, STOP_AFTER_MOVEDELAY_TIME)
      // }
    } catch (error) {
      if (cmd === 'stop') {
        let options = { ...data, cmd: 'stop' }
        let newInd = ind + 1
        newInd < 3 && this.unifyControlPTZ(options, 'stop', newInd)
      }
    }
    console.log(cmd, `operationFalg:${JSON.stringify(this.state.operationFalg)}`);
    if (cmd === 'stop') {
      this.setState({
        operationFalg: true
      })
      console.log('停止命令发送成功');
    } else {
      if (this.state.operationFalg) {//当转动请求完成时发现停止命令已经发出,则再发一次停止命令
        let options = { ...data, cmd: 'stop' }
        console.log('当转动请求完成时发现停止命令已经发出,则再发一次停止命令');
        this.unifyControlPTZ(options, 'stop')
      }
    }

    // Service.unifyControlPTZ(unifyControlPTZOptions).then((res) => {


    // }).catch(() => {

    // }).finally(() => {

    // });
  };

  // 【公共】云台控制逻辑-停止、移动
  controlPTZ = (e, action, turnFlag) => {
    
    const direction = e.target ? e.target.dataset.type : e;
    const { deviceInfo } = this.props;
    const { speed } = this.state;
    const obj = { cid: deviceInfo.cid, cmd: action, direction, speed, turnFlag };
    const PLUS_TYPE = BSConfig?.player?.PTZ?.PLUS_TYPE || 0;
    if (this.CIG && PLUS_TYPE * 1 === 1) {
      this.unifyControlCigPTZ(obj, action);
    } else {
      this.unifyControlPTZ(obj, action);
    }
  };

  // 自动聚焦
  autoFocusHandle = () => {
    const { deviceInfo } = this.props;
    Service.controlFocus({
      cid: deviceInfo.cid,
      cmd: 'auto',
    });
  };

  // 控制速度
  speedControlHandle = (speed) => {
    this.setState({ speed });
  };

  // 初始化加载云台
  initPTZControl = () => {
    const show = !this.state.show;
    if (show) {
      this.setState({ show }, this.createPtz);
    } else {
      this.destroyPtz();
      this.setState({ show });
    }
  };

  render() {
    let { show, totalSpeed, speed } = this.state;
    const { deviceInfo } = this.props;
    const isSDK = typeof deviceInfo.accessType === 'string' && deviceInfo.accessType.toLowerCase() === 'sdk';
    return (
      <>
        {
          MOUSE_DIRECTION_DIC.map(item => {
            let text = item.split('_')[1]
            return <div key={item} className={`playview-box-control-${text}`} data-type={text} ref={this[item]}> <IconFont type='icon-S_Arrow_SmallLeft'></IconFont> </div>
          })
        }
        <div className="camera-control-layer" onDoubleClick={(e) => { e.stopPropagation() }}>
          <span className={`ptz-btn ${show ? 'open' : ''}`} onClick={this.initPTZControl}>
            <span className="ptz-status-icon" />
          </span>
          {show && (
            <div className="layout-content">
              <div className="camera-control-wrapper">
                <ul>
                  {DIRECTION_DIC.map((item) => (
                    <li key={item} className={`camera-control-${item}`}>
                      <span className="control-item" data-type={item} ref={this[item]}>
                        <span />
                      </span>
                    </li>
                  ))}
                </ul>
                <div className="center-layer" />
              </div>
              <div className={`box-zoom`}>
                <span className="zoomin" data-type="zoomin" ref={this.zoomin}>
                  <IconFont type="icon-S_Arrow_SolidUp" title="缩小" />
                </span>
                <span className="box-label">变倍</span>
                <span className="zoomout" data-type="zoomout" ref={this.zoomout}>
                  <IconFont type="icon-S_Arrow_SolidDown" title="放大" />
                </span>
              </div>
              {isSDK && (
                <div className={`box-focus`}>
                  <span className="focusin" data-type="near" ref={this.focusin}>
                    <IconFont type="icon-S_Arrow_SolidUp" title="焦距拉近" />
                  </span>
                  <span className="box-label">聚焦</span>
                  <span className="focusout" data-type="far" ref={this.focusout}>
                    <IconFont type="icon-S_Arrow_SolidDown" title="焦距推远" />
                  </span>
                  <span className="focusauto" data-type="focusauto" onClick={this.autoFocusHandle} ref={this.focusauto}>
                    <IconFont type="icon-S_Bar_LatLongYes" title="自动聚焦" />
                  </span>
                </div>
              )}
              <div className="box-speed">
                <span className="box-speed-icon" />
                <Slider min={1} max={totalSpeed} value={speed} defaultValue={speed / totalSpeed} onChange={this.speedControlHandle} /></div>
            </div>
          )}
        </div>
      </>
    );
  }
}

export default function CameraControl({ deviceInfo, player, isFile, inputRef, playBox }) {
  const barStatus = useBarStatus(player);
  const isHide = useMemo(() => !isFile, [isFile]);
  return !isHide ? <CameraControlView deviceInfo={deviceInfo} getPlayContainer={() => player.__player} barStatus={barStatus} isFile={isFile} inputRef={inputRef} playBox={playBox} /> : null;
}
