import _regeneratorRuntime from 'babel-runtime/regenerator';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

import React, { forwardRef, useRef, useImperativeHandle, useContext, useState, useEffect, Fragment, useDebugValue } from 'react';
import InputText from './../InputText';
import Bridge from './../Bridge';
import MapView from './../MapView';
import MapChoose from './../MapChoose';
import Context from '../Context/instance.js';

// 函数组件因为没有实例, 所以也没有ref, 必须通过forwardRef回调ref
var InputLocation = forwardRef(function (_ref, ref) {
  var ak = _ref.ak,
      loadingValue = _ref.loadingValue,
      failedValue = _ref.failedValue,
      readOnly = _ref.readOnly,
      autoLocation = _ref.autoLocation,
      onClick = _ref.onClick,
      onChange = _ref.onChange,
      _ref$type = _ref.type,
      type = _ref$type === undefined ? 'location' : _ref$type,
      _ref$preview = _ref.preview,
      preview = _ref$preview === undefined ? true : _ref$preview,
      selected = _ref.selected,
      others = _objectWithoutProperties(_ref, ['ak', 'loadingValue', 'failedValue', 'readOnly', 'autoLocation', 'onClick', 'onChange', 'type', 'preview', 'selected']);

  var refEl = useRef(null);
  useImperativeHandle(ref, function () {
    return refEl.current;
  });
  // 地图预览

  var _useState = useState(false),
      viewMapShow = _useState[0],
      setViewMapShow = _useState[1];

  var _useState2 = useState(null),
      viewMapData = _useState2[0],
      setViewMapData = _useState2[1];
  // 地图选点


  var _useState3 = useState(false),
      chooseMapInit = _useState3[0],
      setChooseMapInit = _useState3[1];

  var _useState4 = useState(false),
      chooseMapShow = _useState4[0],
      setChooseMapShow = _useState4[1];

  var _useState5 = useState(null),
      chooseMapData = _useState5[0],
      setChooseMapData = _useState5[1];

  var context = useContext(Context) || {};
  var locale = context.locale || function (key) {
    return key || '';
  };
  if (!loadingValue || typeof loadingValue !== 'string') {
    loadingValue = locale('定位中...', 'location');
  }
  if (!failedValue || typeof failedValue !== 'string') {
    failedValue = locale('定位失败, 请检查定位权限是否开启', 'hint_location_failed');
  }

  useEffect(function () {
    var fetchData = function () {
      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
        var result, address;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (!autoLocation) {
                  _context.next = 15;
                  break;
                }

                if (!(selected && selected.latitude && selected.longitude)) {
                  _context.next = 14;
                  break;
                }

                if (!selected.address) {
                  _context.next = 6;
                  break;
                }

                // 有地址, 则定位完成
                if (onChange) onChange({ target: refEl.current }, selected.address, selected);
                _context.next = 12;
                break;

              case 6:
                // 无地址, 则需要地址逆解析
                setStatus('-1'); // 定位中...
                _context.next = 9;
                return Bridge.getAddress({ // 只支持gcj02
                  latitude: selected.latitude,
                  longitude: selected.longitude
                });

              case 9:
                result = _context.sent;
                address = result && result.address ? result.address : '';

                if (address) {
                  setStatus('1');
                  // 回调onChange
                  if (onChange) onChange({ target: refEl.current }, address, result);
                  // 自动定位设置选择地图的数据
                  chooseMapData = {
                    point: [selected.longitude, selected.latitude],
                    address: address
                  };
                  setChooseMapData(chooseMapData);
                } else {
                  setStatus('0');
                }

              case 12:
                _context.next = 15;
                break;

              case 14:
                location({
                  target: refEl.current,
                  currentTarget: refEl.current
                }, true);

              case 15:
                // 选点模式, 默认读取传入的坐标
                if (type === 'choose' && selected && selected.latitude && selected.longitude) {
                  if (!chooseMapData || !chooseMapData.point || !chooseMapData.address) {
                    setChooseMapData({
                      point: [selected.longitude, selected.latitude],
                      address: selected.address || ''
                    });
                  }
                }

              case 16:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function fetchData() {
        return _ref2.apply(this, arguments);
      };
    }();

    fetchData();
  }, []);

  var _useState6 = useState('1'),
      status = _useState6[0],
      setStatus = _useState6[1]; // 定位状态, -1.定位中和0.定位失败时隐藏text框, 显示定位中或者定位失败的div, 1定位成功显示文本框


  function clickHandler(event, value) {
    var e = event.nativeEvent;
    // 触发点击事件
    if (onClick) {
      onClick(e, value);
    }
    // 只读状态下仅能预览定位
    if (readOnly) {
      if (preview) {
        // 预览
        if (selected && selected.longitude && selected.latitude) {
          setViewMapData({
            point: [selected.longitude, selected.latitude],
            address: selected.address,
            show: true
          });
          setViewMapShow(true);
          // 增加历史记录
          Bridge.addHistoryBack(function () {
            hideViewMap();
          }, 'componentLocation=1');
          preview(e, { errMsg: 'preview:ok' });
        } else {
          if (typeof preview === 'function') {
            preview(e, { errMsg: 'preview:fail' + locale('坐标不正确, 预览失败', 'hint_location_preview_fail') });
          }
        }
      }
      return;
    }
    // 正在定位不允许操作
    if (status === '-1') {
      return;
    }

    // 编辑状态下仅允许点击右边图标定位
    if (readOnly === false) {
      if (e.target.classList.contains('input-location-icon')) {
        location(e);
      } else if (status === '0') {
        // 非只读状态下, 点击错误面板, 允许手动输入位置
        setStatus('1');
      }
      return;
    }

    // 非编辑状态下点击整行定位
    location(e);
  }

  // 定位, isAutoLocation表示初始化时自动定位
  function location(e, isAutoLocation) {
    var _this = this;

    Bridge.debug = true;
    // 如果type为choose为选择定位
    if (!isAutoLocation && type === 'choose') {
      if (!chooseMapInit) {
        setChooseMapInit(true);
      }
      setChooseMapShow(true);
      // 增加历史记录
      Bridge.addHistoryBack(function () {
        hideChooseMap();
      }, 'componentLocation=1');
      return;
    }
    // 定位中...
    setStatus('-1');
    Bridge.getLocation({
      type: 'gcj02',
      success: function () {
        var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(data) {
          var result, address;
          return _regeneratorRuntime.wrap(function _callee2$(_context2) {
            while (1) {
              switch (_context2.prev = _context2.next) {
                case 0:
                  if (!data.address) {
                    _context2.next = 3;
                    break;
                  }

                  // 赋值
                  if (onChange) {
                    onChange(e, data.address, data);
                    setStatus('1');
                    // 自动定位设置选择地图的数据
                    setChooseMapData({
                      point: [data.longitude, data.latitude],
                      address: data.address
                    });
                  }
                  return _context2.abrupt('return');

                case 3:
                  _context2.next = 5;
                  return Bridge.getAddress({ // 只支持gcj02
                    latitude: data.latitude,
                    longitude: data.longitude
                  });

                case 5:
                  result = _context2.sent;
                  address = result && result.address ? result.address : '';

                  if (onChange) onChange(e, address, result);
                  if (address) {
                    setStatus('1');
                    // 自动定位设置选择地图的数据
                    setChooseMapData({
                      point: [data.longitude, data.latitude],
                      address: address
                    });
                  } else {
                    setStatus('0');
                  }

                case 9:
                case 'end':
                  return _context2.stop();
              }
            }
          }, _callee2, _this);
        }));

        return function success(_x) {
          return _ref3.apply(this, arguments);
        };
      }(),
      fail: function fail(res) {
        // 赋值
        if (onChange) onChange(e, '', null);
        setStatus('0');
        // 提示定位失败
        // Bridge.showToast(res.errMsg, {mask: false});
      }
    });
  }

  // 地图预览
  function hideViewMap() {
    setViewMapShow(false);
    if (window.location.href.indexOf('componentLocation=') !== -1) {
      window.history.go(-1);
    }
  }
  // 地图选点
  function chooseHandler(e, value, data) {
    setChooseMapShow(false);
    var address = data && data.address ? data.address : '';
    if (onChange) onChange({ target: refEl.current }, address, data);
  }
  function hideChooseMap() {
    setChooseMapShow(false);
    if (window.location.href.indexOf('componentLocation=') !== -1) {
      window.history.go(-1);
    }
  }

  // 计算class, 防止重要class被覆盖
  var inputClassName = (others.inputAttribute || {}).className || '';
  var riconClassName = (others.riconAttribute || {}).className;
  if (riconClassName === undefined) {
    riconClassName = 'input-location-icon size24 ' + (type === 'choose' ? 'input-location-icon-choose' : 'input-location-icon-location');
  }
  // 加载和错误面板, 显示这些面板时将会隐藏文本框, 样式必须与文本框一致
  var statusDOM = null;
  if (status === '-1') {
    statusDOM = React.createElement(
      'div',
      { className: 'input-text ' + inputClassName + ' input-location', style: (others.inputAttribute || {}).style || {} },
      loadingValue
    );
  } else if (status === '0') {
    statusDOM = React.createElement(
      'div',
      { className: 'input-text ' + inputClassName + ' input-location-error', style: (others.inputAttribute || {}).style || {} },
      failedValue
    );
  }
  return React.createElement(
    Fragment,
    null,
    React.createElement(InputText, _extends({
      ref: refEl,
      readOnly: !readOnly && readOnly !== false ? true : readOnly // 不填写readOnly则认为文本框不允许输入, 只有readOnly为false时才允许输入
      , onClick: clickHandler,
      onChange: onChange,
      children: statusDOM
    }, others, {
      riconAttribute: readOnly ? null : Object.assign({}, others.riconAttribute, { className: '' + (status === '-1' ? riconClassName + ' input-location-icon-active' : riconClassName) }),
      inputAttribute: Object.assign({}, others.inputAttribute, { className: statusDOM ? 'hide-important input-location-success ' + inputClassName : 'input-location-success ' + inputClassName }) // 定位中和定位失败时隐藏text框, 显示定位中或者定位失败的div
    })),
    viewMapData && React.createElement(MapView, {
      ak: ak,
      show: viewMapShow,
      header: viewMapData.address ? React.createElement(
        'div',
        { className: 'map-bar border-b' },
        viewMapData.address
      ) : null,
      points: [viewMapData.point],
      portal: context.portal || document.getElementById('root') || document.body,
      onHide: hideViewMap
    }),
    chooseMapInit && React.createElement(MapChoose, {
      ak: ak,
      show: chooseMapShow,
      autoLocation: true,
      point: chooseMapData && chooseMapData.point ? chooseMapData.point : null,
      address: chooseMapData && chooseMapData.address ? chooseMapData.address : null,
      portal: context.portal || document.getElementById('root') || document.body,
      onHide: hideChooseMap,
      onChange: chooseHandler
    })
  );
});

export default InputLocation;