import _regeneratorRuntime from "@babel/runtime/regenerator";
var _excluded = ["cacheTime", "timeout", "ak", "loadingValue", "failedValue", "readOnly", "autoLocation", "onClick", "onChange", "clear", "clearReadOnly", "type", "preview", "onPreviewHide", "mapPageProps", "routePath", "value"];

function _extends() { _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; }; return _extends.apply(this, arguments); }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

import React, { forwardRef, useRef, useImperativeHandle, useContext, useState, useEffect, Fragment } from 'react';
import InputText from './../InputText';
import Bridge from './../Bridge';
import MapView from './../MapView';
import MapChoose from './../MapChoose';
import Context from '../Context/instance.js'; // 定位超时setTimeout指针

var getLocationTimeout = null; // 地图预览数据

var viewMapData = null; // 函数组件因为没有实例, 所以也没有ref, 必须通过forwardRef回调ref

var InputLocation = forwardRef(function (_ref, ref) {
  var _ref$cacheTime = _ref.cacheTime,
      cacheTime = _ref$cacheTime === void 0 ? 10000 : _ref$cacheTime,
      timeout = _ref.timeout,
      ak = _ref.ak,
      loadingValue = _ref.loadingValue,
      failedValue = _ref.failedValue,
      readOnly = _ref.readOnly,
      autoLocation = _ref.autoLocation,
      onClick = _ref.onClick,
      onChange = _ref.onChange,
      clear = _ref.clear,
      clearReadOnly = _ref.clearReadOnly,
      _ref$type = _ref.type,
      type = _ref$type === void 0 ? 'location' : _ref$type,
      _ref$preview = _ref.preview,
      preview = _ref$preview === void 0 ? true : _ref$preview,
      onPreviewHide = _ref.onPreviewHide,
      mapPageProps = _ref.mapPageProps,
      _ref$routePath = _ref.routePath,
      routePath = _ref$routePath === void 0 ? 'componentPage=1' : _ref$routePath,
      value = _ref.value,
      others = _objectWithoutPropertiesLoose(_ref, _excluded);

  // 国际化
  var context = useContext(Context) || {};

  var locale = context.locale || function (remark) {
    return remark || '';
  }; // 因为在click事件内改变数据的可能性, 所以更新句柄, 防止synchronization模式读取创建时的状态


  var onChangeRef = useRef();
  onChangeRef.current = onChange;
  var onPreviewRef = useRef();
  onPreviewRef.current = preview; // 返回的dom

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

  var _useState = useState(false),
      viewMapShow = _useState[0],
      setViewMapShow = _useState[1]; // 自动定位


  useEffect(function () {
    handleAutoLocation();
  }, [autoLocation]);

  if (!loadingValue || typeof loadingValue !== 'string') {
    loadingValue = locale('定位中...', 'location');
  }

  if (!failedValue || typeof failedValue !== 'string') {
    failedValue = locale('定位失败, 请检查定位权限是否开启', 'hint_location_failed');
  } // 自动定位


  function handleAutoLocation() {
    return _handleAutoLocation.apply(this, arguments);
  }

  function _handleAutoLocation() {
    _handleAutoLocation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
      var result, address;
      return _regeneratorRuntime.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (!(autoLocation !== true)) {
                _context2.next = 2;
                break;
              }

              return _context2.abrupt("return");

            case 2:
              if (!(value && value.latitude && value.longitude)) {
                _context2.next = 17;
                break;
              }

              if (!value.address) {
                _context2.next = 7;
                break;
              }

              // 有地址, 则定位完成
              if (onChangeRef && onChangeRef.current) onChangeRef.current({
                target: inputTextRef.current
              }, value);
              _context2.next = 15;
              break;

            case 7:
              // 无地址, 则需要地址逆解析
              status = '-1';
              setStatus('-1'); // 定位中...

              _context2.next = 11;
              return Bridge.getAddress({
                // 只支持gcj02
                latitude: value.latitude,
                longitude: value.longitude
              });

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

              if (address) {
                status = '1';
                setStatus('1'); // 回调onChange

                if (onChangeRef && onChangeRef.current) onChangeRef.current({
                  target: inputTextRef.current
                }, result); // 自动定位设置选择地图的数据

                viewMapData = {
                  point: [result.longitude, result.latitude],
                  address: result.address
                };
              } else {
                status = '0';
                setStatus('0');
              }

            case 15:
              _context2.next = 18;
              break;

            case 17:
              location({
                target: inputTextRef.current,
                currentTarget: inputTextRef.current
              });

            case 18:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    }));
    return _handleAutoLocation.apply(this, arguments);
  }

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


  function handleClick(event, val) {
    var e = event.nativeEvent; // 触发点击事件

    if (onClick) {
      onClick(e, val);
    } // 正在定位不允许操作


    if (status === '-1') {
      return;
    } // 定位按钮


    if (e.target.classList.contains('input-location-icon')) {
      location(e);
      return;
    } // 清除按钮


    if (e.target.classList.contains('clearicon')) {
      return;
    } // 预览


    if (val && (type === 'choose' || onPreviewRef.current)) {
      if (value && value.longitude && value.latitude) {
        viewMapData = {
          point: [value.longitude, value.latitude],
          address: value.address
        };
        openPreview();
      } else {
        if (typeof onPreviewRef.current === 'function') {
          onPreviewRef.current(e, {
            errMsg: "preview:fail" + locale('坐标不正确, 预览失败', 'hint_location_preview_fail')
          });
        }
      }

      return;
    } // 编辑状态下仅允许点击右边图标定位


    if (readOnly === false) {
      if (status === '0') {
        // 非只读状态下, 点击错误面板, 允许手动输入位置
        status = '1';
        setStatus('1');
      }

      return;
    } // 非编辑状态下点击整行定位


    location(e);
  } // 定位, isAutoLocation表示初始化时自动定位


  function location(e) {
    // 如果type为choose为选择定位
    // if (!isAutoLocation && type === 'choose') {
    //   openPreview()
    //   return
    // }
    // 定位中...
    status = '-1';
    setStatus('-1'); // 定位超时处理

    if (!isNaN(timeout)) {
      if (Number(timeout) < 1000) {
        console.warn('InputLocation: 超时参数timeout不能小于1000毫秒');
      } else {
        if (getLocationTimeout) window.clearTimeout(getLocationTimeout);
        getLocationTimeout = setTimeout(function () {
          if (status === '-1') {
            if (onChangeRef && onChangeRef.current) onChangeRef.current(e, {
              errMsg: "getLocation:fail" + locale('定位超时', 'hint_location_timeout') + " Timeout"
            });
            status = '0';
            setStatus('0');
          }
        }, timeout);
      }
    } // 开始定位


    Bridge.getLocation({
      cacheTime: cacheTime,
      type: 'gcj02',
      success: function () {
        var _success = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(data) {
          var result, address;
          return _regeneratorRuntime.wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  if (!(status === '0')) {
                    _context.next = 3;
                    break;
                  }

                  console.log('定位超时, 不再执行成功回调');
                  return _context.abrupt("return");

                case 3:
                  if (!data.address) {
                    _context.next = 6;
                    break;
                  }

                  // 赋值
                  if (onChange) {
                    data.value = data.address;
                    if (onChangeRef && onChangeRef.current) onChangeRef.current(e, data);
                    status = '1';
                    setStatus('1'); // 自动定位设置选择地图的数据

                    viewMapData = {
                      point: [data.longitude, data.latitude],
                      address: data.address
                    };
                  }

                  return _context.abrupt("return");

                case 6:
                  _context.next = 8;
                  return Bridge.getAddress({
                    // 只支持gcj02
                    latitude: data.latitude,
                    longitude: data.longitude
                  });

                case 8:
                  result = _context.sent;
                  result = _extends({}, data, result);
                  address = result && result.address ? result.address : '';
                  result.value = address;
                  if (onChangeRef && onChangeRef.current) onChangeRef.current(e, result);

                  if (address) {
                    status = '1';
                    setStatus('1'); // 自动定位设置选择地图的数据

                    viewMapData = {
                      point: [data.longitude, data.latitude],
                      address: address
                    };
                  } else {
                    status = '0';
                    setStatus('0');
                  }

                case 14:
                case "end":
                  return _context.stop();
              }
            }
          }, _callee);
        }));

        function success(_x) {
          return _success.apply(this, arguments);
        }

        return success;
      }(),
      fail: function fail(res) {
        // 定位超时后不再执行回调
        if (status === '0') {
          console.log('定位超时, 不再执行失败回调');
          return;
        } // 赋值


        if (onChangeRef && onChangeRef.current) onChangeRef.current(e, res);
        status = '0';
        setStatus('0');
      }
    });
  } // 显示h5预览


  function openPreview() {
    setViewMapShow(true); // 增加历史记录

    Bridge.addHistoryBack(function () {
      closePreview('history');
    }, routePath); // 预览回调

    if (typeof onPreviewRef.current === 'function') onPreviewRef.current({
      target: inputTextRef.current
    }, value);
  } // 关闭h5预览, [closeType] history: 地址栏返回; 其它: 主动隐藏;


  function closePreview(closeType) {
    if (window.location.href.indexOf(routePath) !== -1) {
      window.history.go(-1);
    } else {
      setViewMapShow(false);
      if (onPreviewHide) onPreviewHide(closeType);
    }
  } // 地图选点


  function handleChoose(e, val, data) {
    closePreview('history');
    var address = data && data.address ? data.address : '';
    data.value = address;
    data.errMsg = 'getLocation:ok';
    if (onChangeRef && onChangeRef.current) onChangeRef.current({
      target: inputTextRef.current
    }, data);
  } // 计算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 = /*#__PURE__*/React.createElement("div", {
      className: "input-text " + inputClassName + " input-location",
      style: (others.inputAttribute || {}).style || {}
    }, loadingValue);
  } else if (status === '0') {
    statusDOM = /*#__PURE__*/React.createElement("div", {
      className: "input-text " + inputClassName + " input-location-error",
      style: (others.inputAttribute || {}).style || {}
    }, failedValue);
  }

  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(InputText, _extends({
    ref: inputTextRef,
    readOnly: !readOnly && readOnly !== false ? true : readOnly // 不填写readOnly则认为文本框不允许输入, 只有readOnly为false时才允许输入
    ,
    onClick: handleClick,
    onChange: onChange,
    children: statusDOM,
    value: value && typeof value === 'object' ? value.value || '' : value || '',
    clear: clear,
    clearReadOnly: clearReadOnly
  }, 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

  })), type !== 'choose' && /*#__PURE__*/React.createElement(MapView, _extends({
    ak: ak,
    show: viewMapShow,
    header: viewMapData && viewMapData.address ? /*#__PURE__*/React.createElement("div", {
      className: "map-bar border-b"
    }, viewMapData.address) : null,
    points: viewMapData && viewMapData.point ? [viewMapData.point] : null,
    portal: context.portal || document.getElementById('root') || document.body,
    onHide: closePreview
  }, mapPageProps || {})), type === 'choose' && /*#__PURE__*/React.createElement(MapChoose, _extends({
    ak: ak,
    show: viewMapShow,
    autoLocation: true,
    point: viewMapData && viewMapData.point ? viewMapData.point : null,
    address: viewMapData && viewMapData.address ? viewMapData.address : null,
    portal: context.portal || document.getElementById('root') || document.body,
    onHide: closePreview,
    onChange: handleChoose
  }, mapPageProps || {})));
});
export default InputLocation;