/* global google */

import {
  default as React,
  Component,
} from "react";

import Helmet from "react-helmet";

import {
  withGoogleMap,
  GoogleMap,
  Marker,
  lodash, InfoWindow, TrafficLayer, DirectionsRenderer, SearchBox
} from "react-google-maps";
import moment from "moment";

import TimePicker from 'material-ui/TimePicker';

const INPUT_STYLE = {
  boxSizing: `border-box`,
  MozBoxSizing: `border-box`,
  border: `1px solid transparent`,
  width: `240px`,
  height: `32px`,
  marginTop: `27px`,
  padding: `0 12px`,
  borderRadius: `1px`,
  boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
  fontSize: `14px`,
  outline: `none`,
  textOverflow: `ellipses`,
};

const PopUpInfoWindowExampleGoogleMap = withGoogleMap(props => {
  return (
    <GoogleMap
      defaultZoom={17}
      defaultCenter={{
        lat: 41.819078,
        long: -87.623129
      }}
    >
      <TrafficLayer autoUpdate />
      {props.markers.map((marker, index) => (
        <Marker
          key={index}
          position={marker.position}
          onClick={() => props.onMarkerClick(marker)}
          icon={marker.icon}
        >

          {marker.showInfo && (
            <InfoWindow onCloseClick={() => props.onMarkerClose(marker)}>
              <div>{marker.infoContent}</div>
            </InfoWindow>
          )}

        </Marker>
      ))}
      {props.directions && <DirectionsRenderer directions={props.directions} options={props.directionsRenderer} />}
    </GoogleMap>
  )
});

const carImageStyle = { width: "100px", height: "44px" }
const driverImageStyle = { height: "22px" }
/*
 *
 *  Add <script src="https://maps.googleapis.com/maps/api/js"></script>
 *  to your HTML to provide google.maps reference
 *
 *  @author: @chiwoojo
 */
export default class PopUpInfoWindowExample extends Component {
  constructor(props) {
    super(props);
    this.props = props;

    this.state = {
      ride: {
        "ride_uuid": "",
        "user": {
          "useruuid": "",
          "name": "",
          "member": ""
        },
        "status": {
          "key": "",
          "value": ""
        },
        "type": {
          "key": "",
          "value": ""
        },
        "notes": "",
        "passenger": {
          "user_id": "",
          "image_url": "",
          "first_name": "",
          "last_name": "",
          "phone_number": ""
        },
        "driver": {
          "rating": "",
          "image_url": "/assets/images/g1.jpg",
          "first_name": "",
          "phone_number": ""
        },
        "vehicle": {
          "color": "",
          "make": "",
          "license_plate": "",
          "image_url": "",
          "year": 0,
          "license_plate_state": "",
          "model": ""
        },
        "route": {
          "origin": {
            "name": "",
            "lat": 0,
            "lng": 0,
            "address": ""
          },
          "destination": {
            "name": "",
            "lat": 0,
            "lng": 0,
            "address": ""
          },
          "location": {
            "bearing": 0,
            "lat": 0,
            "lng": 0,
          },
          "route_kml": "",
          "distance": 0,
          "duration": 0,
          "eta": 0
        },
        "visit_date": new Date(),
        "visit_time": new Date(),
        "pickup_time": new Date()
      },
      bounds: null,
      center: {
        lat: 41.819078,
        long: -87.623129,
      },
      origin: null,
      destination: null,
      directions: null,
      // array of objects of markers
      rendererOptions: {
        suppressMarkers: true
      },
      markers: [
        {
          icon: '/assets/images/5_min.png',
          position: null,
          showInfo: false,
          infoContent: (
            <div>
              <TimePicker
                format="ampm"
                hintText="Pickup Time"
              />
              <div> <strong> Pickup </strong>
                <p> </p>
              </div>
              <i className="nav-icon material-icons">location_on</i>
            </div>
          ),
        },
        {
          icon: '/assets/images/5_min.png',
          position: null,
          showInfo: false,
          infoContent: (
            <div>
              <TimePicker
                format="ampm"
                hintText="Dropoff Time"
              />
              <div> <strong> Destination </strong>
                <p> </p>
              </div>
              <i className="nav-icon material-icons">local_hospital</i>
            </div>
          ),
        },
      ],
    }

    if (this.props.data !== null || this.props.data !== undefined) {
      this.state.ride = this.props.data;
    }
  }

  static propTypes = {
    data: React.PropTypes.object.isRequired,
  }

  componentWillReceiveProps(nextProps) {
    let state = this
    const routeObj = {
      origin: new google.maps.LatLng(nextProps.data.route.origin.lat, nextProps.data.route.origin.lng),
      destination: new google.maps.LatLng(nextProps.data.route.destination.lat, nextProps.data.route.destination.lng),
      travelMode: google.maps.TravelMode.DRIVING,
    };
    state.setState(Object.assign(state.state, { ride: nextProps.data }));


    const DirectionsService = new google.maps.DirectionsService();
    DirectionsService.route(routeObj, (result, status) => {
      if (status === google.maps.DirectionsStatus.OK) {
        let pickupMarker = {
          icon: '/assets/images/home.png',
          position: result.routes[0].legs[0].start_location,
          showInfo: false,
          infoContent: (
            <div style={{ opacity: '.8', color: 'brown' }} >
              <div >
                <p> <b>PICK UP</b> at {moment(nextProps.data.pickup_time).format("hh:mm a")} <br></br>{nextProps.data.route.origin.address} </p>
              </div>
            </div>
          ),
        };
        let dropOffMarker = {
          icon: '/assets/images/provider_pin.png',
          position: result.routes[0].legs[0].end_location,
          showInfo: false,
          infoContent: (
            <div>
              <div>
                <p> <b>DROP OFF</b> for {moment(nextProps.data.visit_time).format("hh:mm a")} visit. <br />  {nextProps.data.route.destination.address} </p>
              </div>
            </div>
          ),
        };

        if (nextProps.data.trip_type.key === 'from_visit' || nextProps.data.trip_type.key === 'from_visit_call') {
          if (nextProps.data.status.key === 'willCall') {
            pickupMarker = {
              icon: '/assets/images/provider_pin.png',
              position: result.routes[0].legs[0].end_location,
              showInfo: false,
              infoContent: (
                <div style={{ opacity: '.8', color: 'brown' }} >
                  <div >
                    <p> <b>PICK UP</b> Will Call <br></br>{nextProps.data.route.destination.address} </p>
                  </div>
                </div>
              ),
            };
          } else {
            pickupMarker = {
              icon: '/assets/images/provider_pin.png',
              position: result.routes[0].legs[0].end_location,
              showInfo: false,
              infoContent: (
                <div style={{ opacity: '.8', color: 'brown' }} >
                  <div >
                    <p> <b>PICK UP</b> at {moment(nextProps.data.pickup_time).format("hh:mm a")} <br></br>{nextProps.data.route.destination.address} </p>
                  </div>
                </div>
              ),
            };
          }
          dropOffMarker = {
            icon: '/assets/images/home.png',
            position: result.routes[0].legs[0].start_location,
            showInfo: false,
            infoContent: (
              <div>
                <div>
                  <p> <b>DROP OFF</b> <br />  {nextProps.data.route.origin.address} </p>
                </div>
              </div>
            ),
          };
        }

        let mapState = {
          origin: new google.maps.LatLng(nextProps.data.route.origin.lat, nextProps.data.route.origin.lng),
          destination: new google.maps.LatLng(nextProps.data.route.destination.lat, nextProps.data.route.destination.lng),
          directions: result,
          // array of objects of markers
          rendererOptions: {
            suppressMarkers: true
          },
          markers: [
            pickupMarker,
            dropOffMarker,
          ],
        }

        switch (state.state.ride.status.key) {
          case "accepted":
          case "pickepUp":
          case "arrived":
            let carMarker = {
              icon: '/assets/images/prius2.png',
              position: new google.maps.LatLng(state.state.ride.route.location.lat, state.state.ride.route.location.lng),
              showInfo: false,
              infoContent: (
                <div>
                  <div>
                    <p> <img src={state.state.ride.driver.image_url} style={driverImageStyle} /> {state.state.ride.driver.first_name} ({state.state.ride.driver.rating}) <br /> <img src={state.state.ride.vehicle.image_url} style={carImageStyle} /> {state.state.ride.vehicle.color} {state.state.ride.vehicle.make} {state.state.ride.vehicle.model} ({state.state.ride.vehicle.license_plate})</p>
                  </div>
                </div>
              ),
            };
            mapState.markers.push(carMarker);
            break;
        }

        state.setState(Object.assign(state.state, mapState));
      } else {
        try {
          if (result.status !== "ZERO_RESULTS") {
            console.error(`error fetching directions ${result}`);
          }
        } catch (err) {
          console.error(err);
        }
      }
    });
  }

  componentDidMount() {
    let data = this.props.data;
    this.setState(Object.assign(this.state, { ride: data }));

    const DirectionsService = new google.maps.DirectionsService();
    DirectionsService.route({
      origin: new google.maps.LatLng(this.state.ride.route.origin.lat, this.state.ride.route.origin.lng),
      destination: new google.maps.LatLng(this.state.ride.route.destination.lat, this.state.ride.route.destination.lng),
      travelMode: google.maps.TravelMode.DRIVING,
    }, (result, status) => {
      if (status === google.maps.DirectionsStatus.OK) {
        let mapState = {
          origin: new google.maps.LatLng(this.state.ride.route.origin.lat, this.state.ride.route.origin.lng),
          destination: new google.maps.LatLng(this.state.ride.route.destination.lat, this.state.ride.route.destination.lng),
          directions: result,
          // array of objects of markers
          rendererOptions: {
            suppressMarkers: true
          },
          markers: [
            {
              icon: '/assets/images/home.png',
              position: result.routes[0].legs[0].start_location,
              showInfo: false,
              infoContent: (
                <div>
                  {moment(this.state.ride.pickup_time).format("hh:mm a")}
                  <div> <strong> Origin </strong>
                    <p> {this.state.ride.route.origin.name} <br /> {this.state.ride.route.origin.address} </p>
                  </div>
                </div>
              ),
            },
            {
              icon: '/assets/images/provider.png',
              position: result.routes[0].legs[0].end_location,
              showInfo: false,
              infoContent: (
                <div>
                  {moment(this.state.ride.visit_time).format("hh:mm a")}
                  <div> <strong> Destination </strong>
                    <p> {this.state.ride.destination.name} <br /> {this.state.ride.destination.address} </p>
                  </div>
                </div>
              ),
            },
          ],
        };

        switch (this.state.ride.status.key) {
          case "accepted":
          case "pickepUp":
          case "arrived":
            let carMarker = {
              icon: '/assets/images/prius2.png',
              position: new google.maps.LatLng(state.state.ride.route.location.lat, state.state.ride.route.location.lng),
              showInfo: false,
              infoContent: (
                <div>
                  <div>
                    <p> <img src={this.state.ride.driver.image_url} style={driverImageStyle} /> {this.state.ride.driver.first_name} ({this.state.ride.driver.rating}) <br /><img src={this.state.ride.vehicle.image_url} style={carImageStyle} /> {this.state.ride.vehicle.color} {this.state.ride.vehicle.make} {this.state.ride.vehicle.model} ({this.state.ride.vehicle.license_plate})</p>
                  </div>
                </div>
              ),
            };
            mapState.markers.push(carMarker);
            break;
        }
        this.setState(Object.assign(this.state, mapState));
      } else {
        if (result.status !== "ZERO_RESULTS") {
          console.error(`error fetching directions ${result}`);
        }
      }
    });
  }

  handleMapMounted = this.handleMapMounted.bind(this);
  handleBoundsChanged = this.handleBoundsChanged.bind(this);
  handleSearchBoxMounted = this.handleSearchBoxMounted.bind(this);
  handlePlacesChanged = this.handlePlacesChanged.bind(this);

  handleMapMounted(map) {
    debugger;
    this._map = map;
  }

  handleBoundsChanged() {
    this.setState(Object.assign(this.state, {
      bounds: this._map.getBounds(),
      center: this._map.getCenter(),
    }));
  }

  handleSearchBoxMounted(searchBox) {
    this._searchBox = searchBox;
  }

  handlePlacesChanged() {
    const places = this._searchBox.getPlaces();

    // Add a marker for each place returned from search bar
    const markers = places.map(place => ({
      position: place.geometry.location,
    }));

    // Set markers; set map center to first search result
    const mapCenter = markers.length > 0 ? markers[0].position : this.state.center;

    this.setState(Object.assign(this.state, {
      center: mapCenter,
      markers,
    }));
  }

  handleMarkerClick = this.handleMarkerClick.bind(this);
  handleMarkerClose = this.handleMarkerClose.bind(this);

  // Toggle to 'true' to show InfoWindow and re-renders component
  handleMarkerClick(targetMarker) {
    this.setState(Object.assign(this.state, {
      markers: this.state.markers.map(marker => {
        if (marker === targetMarker) {
          return {
            ...marker,
            showInfo: true,
          };
        }
        return marker;
      }),
    }));
  }

  handleMarkerClose(targetMarker) {
    this.setState(Object.assign(this.state, {
      markers: this.state.markers.map(marker => {
        if (marker === targetMarker) {
          return {
            ...marker,
            showInfo: false,
          };
        }
        return marker;
      }),
    }));
  }

  render() {
    let maps = (<PopUpInfoWindowExampleGoogleMap
      containerElement={
        <div id={'containerMap'} style={{ minHeight: '400px', width: '100%', position: 'relative', overflow: 'visible', padding: '0px' }} className="col-md-12" />
      }
      mapElement={
        <div id={'mapElement'} style={{ minHeight: '100%', width: '100%', position: 'absolute', overflow: 'visible', padding: '0px' }} className="col-md-12" />
      }
      onMapMounted={this.handleMapMounted}
      onBoundsChanged={this.handleBoundsChanged}
      onSearchBoxMounted={this.handleSearchBoxMounted}
      bounds={this.state.bounds}
      onPlacesChanged={this.handlePlacesChanged}
      markers={this.state.markers}
      onMarkerClick={this.handleMarkerClick}
      onMarkerClose={this.handleMarkerClose}
      center={this.state.origin}
      directions={this.state.directions}
      directionsRenderer={this.state.rendererOptions}
      zoom={this.state.defaultZoom}
    />);

    return maps;
  }
}