import { Theme } from "@mui/material"
import { withStyles, createStyles, WithTheme, WithStyles } from "@mui/styles";
import React from "react";
import { parseGPS } from "services/google/mapHelpers";
import { geolocate } from "services/google/googleAPI";
import Loader from "common/Loader";
import MapGL from "common/MapGL";
import { pond } from "protobuf-ts/pond";

const styles = (theme: Theme) =>
  createStyles({
    mapContainer: {
      height: "375px",
      width: "100%",
      padding: theme.spacing(3),
      paddingTop: theme.spacing(1),
      [theme.breakpoints.up("sm")]: {
        height: "475px"
      }
    }
  });

interface Props extends WithStyles<typeof styles>, WithTheme {
  data: pond.Measurement[];
}

interface State {
  loading: boolean;
  coordinates: any[];
}

class GPS extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
      loading: false,
      coordinates: []
    };
  }

  componentDidMount = () => {
    this.parseData();
  };

  componentDidUpdate = (prevProps: Props) => {
    if (this.props.data !== prevProps.data) {
      this.parseData();
    }
  };

  parseData = () => {
    const { data } = this.props;
    this.setState({ loading: true, coordinates: [] });
    if (data.length <= 0) {
      return;
    }

    let promises = [];
    let timestamps: string[] = [];
    let coordinates: any[] = [];
    for (let i = 0; i < data.length; i++) {
      let e = data[i];
      if (e.measurement) {
        let ts = e.timestamp;
        let gps = e.measurement.gps;
        let { request, lat, lng } = parseGPS(gps);
        if (request) {
          promises.push(geolocate(request));
          timestamps.push(ts);
        } else if (lat !== 0 && lng !== 0) {
          coordinates.push({
            timestamp: ts,
            latitude: lat,
            longitude: lng
          });
        }
      }
    }

    Promise.all(promises)
      .then((responses: any[]) => {
        responses.forEach((r, i) => {
          coordinates.push({
            timestamp: timestamps[i],
            latitude: r.data.location.lat,
            longitude: r.data.location.lng,
            accuracy: r.data.accuracy
          });
        });
      })
      .catch((error: any) => {
        console.log(error);
      })
      .finally(() => {
        this.setState({ loading: false, coordinates: coordinates });
      });
  };

  render() {
    const { coordinates, loading } = this.state;
    const { classes } = this.props;

    if (loading) {
      return <Loader />;
    } else {
      let paths = new Map().set("path", coordinates);
      return (
        <div className={classes.mapContainer}>
          <MapGL paths={paths} />
        </div>
      );
    }
  }
}

export default withStyles(styles, { withTheme: true })(GPS);
