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

export const DageMap = forwardRef<DageMapMethods, DageMapProps>(
  (
    { latitude, longitude, disabled, address, city, onChange, onMapComplete },
    ref
  ) => {
    const mapRef = useRef<AMap.Map_2>();
    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]
    );
    const _onChange = useRef(onChange).current;

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

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

          const { data } = await axios.get<AMapTipsResponse>(
            `https://restapi.amap.com/v3/assistant/inputtips?key=e98c2a32f09d82868faace9329e58c26&keywords=${value}&city=${city}&citylimit=true`
          );
          setOptions(data.tips);
        }, 500),
      [city]
    );

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

        const { lng, lat } = data.lnglat;
        setLat(lat);
        setLng(lng);
        _onChange?.({
          lat,
          lng,
        });
      },
      [_onChange, disabled]
    );

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

    const handleMarker = useMemo(
      () =>
        debounce((e: any) => {
          const [lng, lat] = e._position;
          setLat(lat);
          setLng(lng);
          _onChange?.({
            lat,
            lng,
          });
        }, 200),
      [_onChange]
    );

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

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

        handlePosition(lng, lat);

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

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

    const handleGeocoderAddress = useCallback(
      (res: AMapGeocoderGetAddressResult) => {
        _onChange?.({
          address: res.regeocode.formattedAddress,
        });
      },
      [_onChange]
    );

    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={handlePosition.bind(undefined, lng, lat)}
            >
              查询
            </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";
