import React, { useMemo, useEffect, useRef, useState } from 'react';
import _ from 'lodash';

import { providerMap } from '../../providerMap';
import { map } from '../../mapContext';
import * as L from 'leaflet';
import { createJudgementGroupIcon } from '../../utils/overlayer';
import '../../style/abnormal-group-trajectory-map.less';
import IconFont from '../../../../themeComponents/IconFont';

const defaultColors = ['#198CFF', '#25DC9B', '#FFAA00', '#FF5252', '#13C2C2', '#44DBD9', '#BAE637', '#9254DE'];

function JudgementGroupTrajectory({ list = [], map, trajectoryType, style, dataId, lineColors = defaultColors }) {
  const [visibleAids, setVisibleAids] = useState(list.map((v) => v.aid));
  const groupRef = useRef(L.featureGroup().addTo(map));
  const trajectoryList = useMemo(() => {
    if (list.length === 0) {
      return [];
    }
    return list.map((v) => {
      const index = v.trails.findIndex((v) => v[trajectoryType] === dataId);
      v.trails.forEach((item, i) => {
        item.aid = v.aid;
        if (i < index) {
          item.direction = 'in';
        }
        if (i > index) {
          item.direction = 'out';
        }
      });
      return v.trails;
    });
  }, [list, dataId, trajectoryType]);
  useEffect(() => setVisibleAids(list.map((v) => v.aid)), [list]);

  useEffect(() => {
    groupRef.current.getLayers().forEach((v) => v.lineAid && v.remove());
    const lines = trajectoryList.map((v) => getLatlngForTrails(v, dataId, trajectoryType));
    lines.forEach((paths, i) => {
      let lineColor = lineColors[i];
      paths.forEach((path, index) => {
        const options = { showDir: true, strokeColor: index === 0 ? '#ff8800' : '#2299ff', strokeWeight: 5, lineCap: 'round', color: lineColor };
        const polyline = L.polyline(path, options);
        polyline.lineAid = list[i].aid;
        polyline.on('mouseover', function (e) {
          groupRef.current
            .getLayers()
            .filter((v) => v.lineAid === e.target.lineAid)
            .forEach((v) => {
              v.setStyle({ weight: 10, zIndex: 100 });
            });
        });
        polyline.on('mouseout', function (e) {
          groupRef.current
            .getLayers()
            .filter((v) => v.lineAid === e.target.lineAid)
            .forEach((v) => {
              v.setStyle({ weight: 5, zIndex: 90 });
            });
        });
        groupRef.current.addLayer(polyline);
      });
    });
    const bounds = groupRef.current.getBounds();
    if (bounds.isValid()) {
      map.fitBounds(bounds);
    }
  }, [list, map, dataId, trajectoryList, trajectoryType]);

  useEffect(() => {
    groupRef.current.getLayers().forEach((v) => v.markerId && v.remove());
    const points = [].concat(...trajectoryList);
    points.forEach((item) => {
      const isCenter = item[trajectoryType] === dataId;
      const { longitude, latitude } = item;
      const marker = L.marker(L.latLng(latitude, longitude), { icon: createJudgementGroupIcon({ isCenter, item }) });
      marker.markerId = item.aid;
      marker.extData = item;
      groupRef.current.addLayer(marker);
    });
  }, [map, dataId, trajectoryList, trajectoryType]);

  /**
   * 联动卡片
   */
  useEffect(() => {
    const allAids = _.uniq(
      groupRef.current
        .getLayers()
        .filter((v) => v.lineAid)
        .map((v) => v.lineAid)
    );
    const hideAids = _.difference(allAids, visibleAids);
    groupRef.current.getLayers().forEach((item) => {
      if (hideAids.includes(item.lineAid)) {
        item.lineAid && item.setStyle({ opacity: 0 });
      } else {
        item.lineAid && item.setStyle({ opacity: 1 });
      }
    });
    groupRef.current.getLayers().forEach((item) => {
      if (hideAids.includes(item.markerId)) {
        item.markerId && item.setOpacity(0);
      } else {
        item.markerId && item.setOpacity(1);
      }
    });
  }, [visibleAids]);

  const onChangeAidStatus = function (aid) {
    const inVisible = visibleAids.includes(aid);
    let aids = [];
    if (inVisible) {
      aids = visibleAids.filter((v) => v !== aid);
    } else {
      aids = [...visibleAids, aid];
    }
    setVisibleAids(aids);
  };

  return (
    <div className="map-avatar-aid" style={style}>
      {list.map((v, itemIndex) => (
        <div className="map-avatar-aid-item" onClick={() => onChangeAidStatus(v.aid)}>
          <IconFont style={{ backgroundColor: visibleAids.includes(v.aid) ? lineColors[itemIndex] : '#999' }} type="icon-S_Photo_MarkYes"></IconFont>
          <span>
            <img src={v.trails[0].faceUrl} alt="" />
          </span>
        </div>
      ))}
    </div>
  );
}

function getLatlngForTrails(list, dataId, trajectoryType) {
  const index = list.findIndex((v) => v[trajectoryType] === dataId);
  if (index === -1) {
    console.warn('轨迹未经过当前区域', dataId);
    return [];
  }
  const inArr = list.slice(0, index + 1);
  const outArr = list.slice(index);
  return [inArr.map((v) => L.latLng(v.latitude, v.longitude)), outArr.map((v) => L.latLng(v.latitude, v.longitude))];
}

export default providerMap('abnormal-group-trajectory-map')(map(JudgementGroupTrajectory));
