import React, { Component } from 'react';
import { Connect as UIConnect } from 'amos-framework';
import PropTypes from 'prop-types';
import AmosWebSocket from 'amos-websocket';
import GIS3DView from './GIS3DView';
import { tileEquipAction, tileRiskAction, tileVideoAction } from './../../services/3dService';
import { markerImg } from './_markerConsts';
import { getEquipDescr, getRiskDescr, getVideoDescr } from './_tools';
import TileContent from './TileContent';
import SysWsURL from './../../consts/wsUrlConsts';
import { rulesDataFactory, eventTopics, globalMsg } from './consts';
import { initView } from './ruleActionTools';

const noop = d => d;
const eventConnect = UIConnect.eventConnect;

@eventConnect
class TileView extends Component {

  constructor(props) {
    super(props);
    this.state = {
      pickable: false,
      riskEquip: '0'
    };
    this.markerIds = [];
  }

  componentDidMount() {
    this.props.subscribe(eventTopics.plan_end, (topic, data) => {
      let { riskEquip } = this.state;
      riskEquip && this.removeByMarkerId(riskEquip);
    });
  }

  onCreated = (gis3d, plugin) => {
    this.gis3DRenderer = gis3d;
    this.GIFPlugin = plugin;
  }

  onItemClick = (item, checked) => {
    const { key } = item;

    // 场景自身控制, 最佳视角
    if (key === 'initView'){
      initView(this);
    }
    // 场景自身控制, 拾取坐标
    else if (key === 'picker'){
      this.setState({
        pickable: checked
      });
    }
    // 业务控制
    else {
      this.clearLast();
      if (checked){
        let asyncLoad;
        let dataFmt = noop;
        switch (key) {
          case 'equip':
            asyncLoad = tileEquipAction;
            dataFmt = this.createEquip;
            break;
          case 'risk':
            asyncLoad = tileRiskAction;
            dataFmt = this.createRisk;
            break;
          case 'video':
            asyncLoad = tileVideoAction;
            dataFmt = this.createVideoMonitor;
            break;
          default:
            break;
        }
        if (asyncLoad){
          asyncLoad().then(d => {
            this.createMarker(d, dataFmt);
          });
        }
      }
    }

  }

  clearLast = () => {
    if (this.markerIds && this.markerIds.length > 0){
      this.gis3DRenderer.removeByIds(this.markerIds);
      this.markerIds = [];
    }
  }

  createMarker = (datas, dataFmt) => {
    datas.forEach(d => {
      this.markerIds.push(d.rownum);
      this.gis3DRenderer.createMarker(dataFmt(d));
    });
  }

  removeByMarkerId = (id) => {
    this.markerIds.splice(this.markerIds.findIndex(i => id === i), 1);
    this.gis3DRenderer.removeByIds([id]);
  }

  addMarkerId = (id, target) => {
    this.removeByMarkerId(id);
    this.markerIds.push(id);
    this.gis3DRenderer.createMarker(target);
    this.setState({ riskEquip: id });
  }

  createEquip(param = {}){
    const { x, y, z, equippositioninfoid, equipmentId, equipname, ...rest } = param;
    return {
      ...rest,
      id: equippositioninfoid ? equippositioninfoid : equipmentId,
      name: equipname,
      label: {
        text: ''
      },
      billboard: {
        image: markerImg.equip
      },
      position: { x, y, z },
      description: getEquipDescr(param)
    };
  }

  createRisk(param = {}){
    const { x, y, z, rownum, riskpointname, riskrank, ...rest } = param;
    const image = markerImg[`risk_${riskrank}`] || markerImg.risk_1;
    return {
      ...rest,
      id: rownum,
      name: riskpointname,
      label: {
        text: ''
      },
      billboard: {
        image
      },
      position: { x, y, z },
      description: getRiskDescr(param)
    };
  }

  createVideoMonitor(param = {}){
    const { x, y, z, rownum, cameraname, ...rest } = param;

    return {
      ...rest,
      id: rownum,
      name: cameraname,
      label: {
        text: ''
      },
      billboard: {
        image: markerImg.video
      },
      position: { x, y, z },
      description: getVideoDescr(param)
    };
  }

  /**
   * 监控视图消息 (规则 ws)
   */
  handleData = data => {
    console.log('rule ws data:', data);
    const { topic, content } = rulesDataFactory(data);
    if (topic === eventTopics.global_msg) {
      globalMsg(content);
      return;
    }
    this.props.trigger(topic, content);
  };

  render() {
    const wsURL = SysWsURL.viewTileURI;
    const { pickable } = this.state;
    return (
      <div className="tileview">
        <AmosWebSocket ref={node => this.aws = node} url={wsURL} onMessage={this.handleData} reconnect debug />
        <TileContent onItemClick={this.onItemClick} />
        <GIS3DView onViewerCreated={this.onCreated} pickable={pickable} addMarkerId={this.addMarkerId} removeByMarkerId={this.removeByMarkerId} createEquip={this.createEquip} />
      </div>
    );
  }
}

TileView.propTypes = {
  trigger: PropTypes.func
};

export default TileView;
