import * as L from "leaflet";
import { createHighFeqPlaceIcon } from "./utils/overlayer";
import * as geometric from "geometric";
export default class TrackPlay {
  constructor(map, data, options) {
    this.status = {
      isStart: false,
      isEnd: false,
      isPause: false
    };
    this.map = map;
    this.data = data;
    this.trackOptions = options;
    this.moveIndex = 0;
    this.startLatlng = null;
    this.endLatLng = null;
    this.moveLatLng = null;
    this.init();
  }
  init() {
    this.moveMarker = L.marker(L.latLng(this.data[0].latitude, this.data[0].longitude), {
      icon: createHighFeqPlaceIcon(),
      className: "",
      zIndexOffset:100,
    }).addTo(this.map);
    this.lineList = this.formartTrackList(this.data);
    if (!this.lineList.length) {
      return;
    }
    this.featureGroup = L.featureGroup(this.lineList);
    this.map.fitBounds(this.featureGroup.getBounds());

    this.trackOptions.onInit(this.moveMarker);
    this.featureGroup.addTo(this.map);
    this.start();
  }
  getCurrentIndexLine() {
    return this.featureGroup.getLayers().find(v => v.__index === this.moveIndex);
  }
  hideLastLine() {
    const lines = this.featureGroup.getLayers();
    lines.forEach(v => {
      if (v.__index > this.moveIndex) {
        v.setStyle({ opacity: 0 });
      } else {
        const extData = v.__extendData;
        v.setLatLngs([extData.start, extData.end]);
        v.setStyle({ opacity: 1 });
      }
    });
  }
  dispose() {
    window.cancelAnimationFrame(this.timer);
    this.featureGroup && this.featureGroup.remove();
    this.moveMarker && this.moveMarker.remove();
  }

  formartTrackList(data) {
    let arr = [];
    data.forEach((v, index) => {
      if (data[index + 1]) {
        const next = data[index + 1];
        const start = L.latLng(v.latitude, v.longitude);
        start.__extendData = v;
        const end = L.latLng(next.latitude, next.longitude);
        end.__extendData = next;
        arr.push([start, end]);
      }
    });
    return arr.map((v, index) => {
      const polyline = L.polyline([v[0], v[1]], { weight: 8 });
      polyline.__extendData = {
        start: v[0],
        end: v[1]
      };
      polyline.__index = index;
      return polyline;
    });
  }
  start(index = 0, autoplay = true) {
    this.moveIndex = index;
    if (this.moveIndex > this.lineList.length) {
      this.status.isEnd = true;
      this.status.isStart = false;
      this.status.isPause = true;
      this.trackOptions.update();
      return;
    }
    this.trackOptions.moveChange(this.moveIndex);
    this.status.isEnd = false;
    this.status.isStart = true;
    this.hideLastLine();
    const currentLine = this.getCurrentIndexLine();
    if (!currentLine) {
      this.status.isEnd = true;
      this.status.isStart = false;
      this.status.isPause = true;
      this.trackOptions.update();
      return;
    }
    const LatLngs = currentLine.getLatLngs();
    this.startLatlng = LatLngs[0];
    this.endLatLng = LatLngs[1];
    this.animationLine = [[this.startLatlng.lat,this.startLatlng.lng],[this.endLatLng.lat,this.endLatLng.lng]]
    this.seepd = 0.01
    this.moveMarker.setLatLng(this.startLatlng);
    currentLine.setLatLngs([this.startLatlng, this.startLatlng]);
    if (autoplay) {
      this.play();
    }
  }
  pause() {
    if (!this.status.isPause) {
      this.status.isPause = true;
      window.cancelAnimationFrame(this.timer);
      this.trackOptions.update();
    }
  }
  play() {
    if (this.status.isEnd) {
      this.status.isEnd = false;
      this.start(0);
    } else {
      this.status.isPause = false;
      window.cancelAnimationFrame(this.timer);
      this.timer = window.requestAnimationFrame(this.animation);
      this.trackOptions.update();
    }
  }
  animation = () => {
    const currentLine = this.getCurrentIndexLine();
    const interpolator = geometric.lineInterpolate(this.animationLine);
    this.moveLatLng = interpolator(this.seepd)
    if (!this.endLatLng.equals(this.moveLatLng)) {
      this.seepd += 0.01
      currentLine.setLatLngs([this.startLatlng, this.moveLatLng]);
      this.moveMarker.setLatLng(this.moveLatLng);
      this.map.setView(this.moveLatLng,this.map.getZoom())
      this.timer = window.requestAnimationFrame(this.animation);
    } else {
      currentLine.setLatLngs([this.startLatlng, this.endLatLng]);
      this.moveMarker.setLatLng(this.endLatLng);
      this.start(this.moveIndex + 1);
    }
  };

  next() {
    if (this.status.isEnd) {
      return;
    } else {
      window.cancelAnimationFrame(this.timer);
      this.status.isPause = true;
      this.status.isStart = true;
      this.status.isEnd = false;
      this.start(this.moveIndex + 1, false);
      this.trackOptions.update();
    }
  }
  prev() {
    if (this.moveIndex === 0) {
      return;
    } else {
      window.cancelAnimationFrame(this.timer);
      this.status.isPause = true;
      this.status.isStart = true;
      this.status.isEnd = false;
      this.start(this.moveIndex - 1, false);
      this.trackOptions.update();
    }
  }
  reset() {
    window.cancelAnimationFrame(this.timer);
    this.status = {
      isStart: false,
      isEnd: true,
      isPause: false
    };
    this.trackOptions.update();
    this.start(0);
  }
}
