import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { Amap, Marker } from '@amap/amap-react';
import { AutoComplete, Button, Input, Space } from 'antd';
import { debounce } from 'lodash';
import {
  AMapGeocoderGetAddressResult,
  DageMapMethods,
  DageMapPoisType,
  DageMapProps,
} from './types';
import { DageMapGeocoder } from './plugins';
import { getAmapInputTips } from './utils';

export const DageMap = forwardRef<DageMapMethods, DageMapProps>(
  (
    {
      latitude,
      longitude,
      disabled,
      address,
      city,
      inputTipsApi,
      onAddressChange,
      onLngLatChange,
      onMapComplete,
    },
    ref,
  ) => {
    const mapRef = useRef<AMap.Map_2>();
    /** 是否禁用坐标解析地址 */
    const geocoderDisabled = useRef(false);
    const [loaded, setLoaded] = useState(false);
    /** 经度 */
    const [lng, setLng] = useState<number>(longitude);
    /** 纬度 */
    const [lat, setLat] = useState<number>(latitude);
    const [options, setOptions] = useState<DageMapPoisType[]>([]);
    const position = useMemo(() => [longitude, latitude], [longitude, latitude]);

    useImperativeHandle(ref, () => ({
      mapRef: mapRef.current,
    }));

    const handleSearch = useCallback(
      debounce(async (value: string) => {
        if (!value) {
          setOptions([]);
          return;
        }

        const { tips } = await getAmapInputTips(inputTipsApi, value, city);
        setOptions(tips || []);
      }, 500),
      [city],
    );

    const handleClick = useCallback(
      (e: AMap.Map_2, data: any) => {
        if (disabled) return;

        const { lng, lat } = data.lnglat;

        geocoderDisabled.current = false;

        setLat(lat);
        setLng(lng);
        onLngLatChange?.({
          lat,
          lng,
        });
      },
      [disabled, onLngLatChange],
    );

    /**
     * 地图初始化完成
     */
    const handleComplete = useCallback(() => {
      setLoaded(true);
      mapRef.current?.setCenter([longitude, latitude], false, 1000);
      onMapComplete?.();
    }, [longitude, latitude, onMapComplete]);

    const handleMarker = useCallback(
      debounce((e: any) => {
        const [lng, lat] = e._position;
        geocoderDisabled.current = false;
        setLat(lat);
        setLng(lng);
        onLngLatChange?.({
          lat,
          lng,
        });
      }, 200),
      [onLngLatChange],
    );

    const handlePosition = useCallback(
      (long = lng, lati = lat) => {
        if (!long || !lati) return;
        onLngLatChange?.({
          lat: lati,
          lng: long,
        });
        mapRef.current?.setCenter([long, lati], false, 1000);
      },
      [lng, lat, onLngLatChange],
    );

    /**
     * 坐标搜索
     */
    const handleLngLatSearch = useCallback(() => {
      geocoderDisabled.current = false;
      handlePosition();
    }, [handlePosition]);

    const handleSelect = useCallback(
      (val: string, opts: DageMapPoisType) => {
        const [lng, lat] = opts.location.split(',').map((i) => Number(i));

        setLng(lng);
        setLat(lat);
        geocoderDisabled.current = true;

        handlePosition(lng, lat);

        onLngLatChange?.({
          lat,
          lng,
        });
      },
      [handlePosition, onLngLatChange],
    );

    const handleAutoCompleteChange = useCallback(
      (val: string) => {
        onAddressChange?.(val);
      },
      [onAddressChange],
    );

    const handleGeocoderAddress = useCallback(
      (res: AMapGeocoderGetAddressResult) => {
        !geocoderDisabled.current && onAddressChange?.(res.regeocode.formattedAddress);
      },
      [onAddressChange],
    );

    return (
      <>
        <div>
          <AutoComplete
            allowClear
            disabled={disabled}
            value={address}
            style={{ width: 450 }}
            options={options.map((i) => ({
              ...i,
              value: i.name,
            }))}
            onSearch={handleSearch}
            onSelect={handleSelect}
            onChange={handleAutoCompleteChange}
          >
            <Input allowClear placeholder="请输入详细描述" />
          </AutoComplete>
        </div>

        <Space style={{ margin: '15px 0' }}>
          <Input
            readOnly={disabled}
            value={lng}
            type="number"
            placeholder="请输入经度"
            onChange={(e) => setLng(Number(e.target.value))}
          />
          <Input
            readOnly={disabled}
            value={lat}
            type="number"
            placeholder="请输入纬度"
            onChange={(e) => setLat(Number(e.target.value))}
          />
          {!disabled && (
            <Button type="primary" onClick={handleLngLatSearch}>
              查询
            </Button>
          )}
        </Space>

        <div style={{ width: 650, height: 400 }}>
          <Amap ref={mapRef} zoom={17} onComplete={handleComplete} onClick={handleClick}>
            {loaded && position ? (
              <>
                <Marker position={position} draggable={!disabled} onDragging={handleMarker} />

                {!disabled && (
                  <DageMapGeocoder
                    city={city}
                    position={position}
                    onChange={handleGeocoderAddress}
                  />
                )}
              </>
            ) : (
              <></>
            )}
          </Amap>
        </div>
      </>
    );
  },
);

export * from './types';
export * from './utils';
