import React, { Component } from "react";
import { connect } from "react-redux";
import MapView, { Circle, Marker, Polyline } from "react-native-maps";
import { StyleSheet, View } from "react-native";
import { getAllPositions, getAllTracks, getAllWarnings } from "../../selectors";
import Colors from "../../constants/Colors";
import latLngDistance from "../../helpers/latLngDistance";
import contactLengthText from "../../helpers/contactLengthText";
import commonColor from "../../native-base-theme/variables/commonColor";
import { setDetail } from "../../actions";

const diffCalc = (position, track) => {
  const distance = latLngDistance(
    track.lat,
    track.lng,
    position.lat,
    position.lng,
    "M"
  );

  const timeDifference = Math.abs(
    Date.parse(position.time) - Date.parse(track.time)
  );
  return { distance, timeDifference };
};

const options = {
  weekday: "short",
  year: "numeric",
  month: "numeric",
  day: "numeric",
  hour: "numeric",
  minute: "numeric"
};

const MapHistory = ({ positions, setDetailTrigger, warnings }) => {
  const lines = positions.map(point => {
    return {
      latitude: point.lat ? point.lat : 0,
      longitude: point.lng ? point.lng : 0
    };
  });

  const connectedPoints = warnings;

  var concatPoints = [];
  connectedPoints.forEach((position, i) => {
    const foundSimilar = concatPoints.findIndex(existingPoint => {
      const diff = diffCalc(position, existingPoint);
      if (diff.distance <= 100 && diff.timeDifference <= 1000 * 60 * 60 * 2) {
        return true;
      }
    });
    if (foundSimilar === -1) {
      concatPoints.push(position);
    }
  });

  const circle = positions.map((point, index) => {
    const coordinates = {
      longitude: point.lng,
      latitude: point.lat
    };
    return (
      <Circle
        key={index}
        strokeColor={commonColor.brandPrimary}
        center={coordinates}
        fillColor={commonColor.brandPrimary}
        radius={Platform.OS === "ios" ? 0.3 : 0.1}
      />
    );
  });

  const connectedLines = connectedPoints.map((point, index) => {
    if (point.matches && point.matches.length >= 1) {
      return point.matches.map((e, i) => (
        <Polyline
          key={`${i}-${index}`}
          coordinates={[
            { latitude: point.position.lat, longitude: point.position.lng },
            { latitude: e.lat, longitude: e.lng }
          ]}
          strokeColor="rgba(255,0,0,0.1)" // fallback for when `strokeColors` is not supported by the map-provider
          strokeColors={["rgba(255,0,0,0.5)", "rgba(255,168,12,0.8)"]}
          strokeWidth={15.5}
        />
      ));
    }
  });

  const points = connectedPoints.map((point, index) => {
    const coordinates = {
      longitude: point.position.lng,
      latitude: point.position.lat
    };

    return (
      <Marker
        key={index}
        anchor={Platform.OS === "ios" ? { x: 0, y: 0 } : { x: 0.53, y: 0.53 }}
        coordinate={coordinates}
        onCalloutPress={() => setDetailTrigger(point)}
        title={`${new Date(point.position.time).toLocaleDateString(
          "de-DE",
          options
        )}`}
        description={contactLengthText(point.duration)}
      >
        {point.matches.length >= 1 ? (
          <View style={styles.matchCircle}>
            <View style={styles.matchCircleBackground}></View>
            <View style={styles.matchCircleInner}></View>
          </View>
        ) : (
          <View style={styles.historyCircle} />
        )}
      </Marker>
    );
  });

  //
  //
  //
  return (
    <React.Fragment>
      <Polyline
        coordinates={lines}
        geodesic={true}
        // strokeColor={Colors.tintColor}  fallback for when `strokeColors` is not supported by the map-provider
        strokeWidth={2}
        strokeColor="rgba(0,122,255,0.7)"
      />
      {circle}
      {connectedLines}
      {points}
    </React.Fragment>
  );
};

const mapStateToProps = state => {
  return {
    warnings: getAllWarnings(state),
    positions: getAllPositions(state),
    tracks: getAllTracks(state)
  };
};

const mapDispatchToProps = dispatch => ({
  setDetailTrigger: id => dispatch(setDetail(id))
});

const styles = StyleSheet.create({
  historyCircle: {
    width: 10,
    height: 10,
    borderRadius: 50,
    backgroundColor: commonColor.brandPrimary
  },
  matchCircle: {
    width: Platform.OS === "ios" ? 40 : 30,
    height: Platform.OS === "ios" ? 40 : 30,
    borderRadius: 50
  },
  matchCircleBackground: {
    position: "absolute",
    width: Platform.OS === "ios" ? 40 : 30,
    height: Platform.OS === "ios" ? 40 : 30,
    borderRadius: 50,
    opacity: 0.1,
    backgroundColor: commonColor.brandDanger
  },
  matchCircleInner: {
    position: "absolute",
    width: Platform.OS === "ios" ? 12 : 12,
    height: Platform.OS === "ios" ? 12 : 12,
    left: Platform.OS === "ios" ? 14 : 10,
    top: Platform.OS === "ios" ? 14 : 10,
    borderColor: "white",
    borderWidth: 2,
    borderRadius: 25 / 2,
    backgroundColor: commonColor.brandDanger
  }
});

export default connect(mapStateToProps, mapDispatchToProps)(MapHistory);