<template>
  <div
    v-loading="isLoading"
    :class='provider ? "maps-components" : "maps-container"'>
    
    <div class="filter-container">
      <el-form class="filter-view">
        <el-form-item
          class="flex1" style="min-width: 200px; max-width: 320px;">
          <el-input
            placeholder="Search using keywords"
            v-model="criteria"/>
        </el-form-item>
        <div>
          <el-button
            type="primary"
            icon="el-icon-search"
            @click="handleFilter">
            Search
          </el-button>
        </div>
      </el-form>
    </div>
    <div class="card-group">
      <div class="maps-card-view">
        <div class="card-title">Available</div>
        <div class="avaliable-card-value">{{ statistics.available || 0 }}</div>
      </div>
      <div class="maps-card-view">
        <div class="card-title">In Use</div>
        <div class="in-user-card-value">{{ statistics.inUse || 0}}</div>
      </div>
      <div class="maps-card-view">
        <div class="card-title">Reserved</div>
        <div class="reserved-card-value">{{ statistics.reserved || 0}}</div>
      </div>
      <div class="maps-card-view">
        <div class="card-title">Faulted</div>
        <div class="faulted-card-value">{{ statistics.faulted || 0 }}</div>
      </div>
      <div class="maps-card-view">
        <div class="card-title">Unavailable</div>
        <div class="unavaliable-card-value">{{ statistics.unavailable }}</div>
      </div>
    </div>

    <div class="google-map-container">
      <div class="google-map" ref="googleMap"></div>
    </div>
  </div>
</template>

<script>

import { Loader } from "@googlemaps/js-api-loader"
import MarkerClusterer from '@googlemaps/markerclustererplus';
import api from '@/http/api/map'

export default {
  props: {
    provider: {
      type: String|Number,
      default: ""
    }
  },
  data() {
    return {
      isLoading: false,
      map: null,
      apiKey: 'AIzaSyAVzs860l2Iuu1zG80IT1Zu4w7OvbVmJ4g',
      markerCluster: null,
      mapConfig: {
        center: { lat: 1.31701950, lng: 103.86336710 },
        zoom: 13,
      },
      siteInfoList: [],
      criteria: '',
      statistics: {
        inUse: 0,
        reserved: 0,
        faulted: 0,
        available: 0,
        unavailable: 0,
      },
    }
  },
  async mounted() {
    this.getConnectorStatusCount()
    this.initializeMap()
    this.getCurrentLocation()
    this.getSiteInfoList()
  },
  methods: {
    getMarkerImageSize() {
      const markerImageSize = new google.maps.Size(61 / 1.8, 72 / 1.8)
      return markerImageSize
    },
    getMarkerImage() {
      const size = this.getMarkerImageSize()
      const markerImageUrl = require('@/assets/ic_marker.png')
      const markerImage = {
        url: markerImageUrl,
        size,
        scaledSize: size,
      }
      return markerImage
    },
    getUnavailableMarkerImage() {
      const size = this.getMarkerImageSize()
      const unavailableMarkerImageUrl = require('@/assets/ic_marker_un.png')
      const unavailableMarkerImage = {
        url: unavailableMarkerImageUrl,
        size,
        scaledSize: size,
      }
      return unavailableMarkerImage
    },
    getMarkerIcon(siteInfo) {
      const { allConnector } = siteInfo
      if (allConnector && allConnector.available) {
        return this.getMarkerImage()
      }
      return this.getUnavailableMarkerImage()
    },
    getMarkerPosition(siteInfo) {
      const {
        locationLongitude: lng,
        locationLatitude: lat,
      } = siteInfo
      const position = new google.maps.LatLng(lat, lng)
      return position
    },
    getMarker(siteInfo) {
      const marker = new google.maps.Marker({
        position: this.getMarkerPosition(siteInfo),
        icon: this.getMarkerIcon(siteInfo),
      })
      marker.site = siteInfo
      return marker
    },
    generateMarkerList() {
      const markerList = this.siteInfoList.map(
        siteInfo => this.getMarker(siteInfo)
      )
      return markerList
    },
    refreshMap() {
      if (this.markerCluster) {
        this.markerCluster.clearMarkers()
      }
      const markerList = this.generateMarkerList()
      this.markerCluster = new MarkerClusterer(
        this.map,
        markerList,
        {
          calculator: (markers, clusterIconStylesCount) => {
            const hasAvailableSite = markers.some((marker) => {
              const {
                site: {
                  allConnector,
                }
              } = marker
              return allConnector && allConnector.available
            })
            return {
              url: hasAvailableSite
                ? require("@/assets/ic_cluster.png")
                : require("@/assets/ic_cluster_un.png"),
              text: markers.length,
              index: markers.length < 10 ? hasAvailableSite ? 3 : 4 : hasAvailableSite ? 1 : 2
            }
          },
          averageCenter: true,
          styles: [
            MarkerClusterer.withDefaultStyle({
              width: this.getMarkerImageSize().width,
              height: this.getMarkerImageSize().height,
              anchorIcon: [26, 15],
              anchorText: [-3, 0],
              textColor: "#fff",
              textSize: 15,
              fontWeight: 'bold',
              className: "google-map-cluster"
            }),
            MarkerClusterer.withDefaultStyle({
              width: this.getMarkerImageSize().width,
              height: this.getMarkerImageSize().height,
              anchorText: [-3, 0],
              textColor: "#999",
              textSize: 15,
              fontWeight: 'bold',
              className: "google-map-cluster"
            }),
            MarkerClusterer.withDefaultStyle({
              width: this.getMarkerImageSize().width,
              height: this.getMarkerImageSize().height,
              textColor: "#fff",
              anchorText: [-3, 0],
              fontWeight: 'bold',
              textSize: 17,
              className: "google-map-cluster"
            }),
            MarkerClusterer.withDefaultStyle({
              width: this.getMarkerImageSize().width,
              height: this.getMarkerImageSize().height,
              textColor: "#999",
              anchorText: [-3, 0],
              fontWeight: 'bold',
              textSize: 17,
              className: "google-map-cluster"
            })
          ],
        }
      )
    },
    getSiteInfoList() {
      api.getSiteInfoList(this.criteria).then(res => {
        if (res.data) {
          this.siteInfoList = res.data
        } else {
          this.siteInfoList = []
        }
        this.refreshMap()
      }).catch(err => {

      })
    },
    getConnectorStatusCount() {
      api.getConnectorStatusCount().then(res => {
        if (res.data) {
          this.statistics = res.data
        }
      }).catch(() => {

      })
    },
    initializeMap() {
      const mapContainer = this.$refs.googleMap
      const loader = new Loader({
        apiKey: this.apiKey,
        language: 'en',
       })
      return loader.load().then(() => {
        this.map = new google.maps.Map(mapContainer, this.mapConfig)
      }).catch((error) => {
        console.log(error)
      })
    },
    getCurrentLocation() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          (position) => {
            const pos = {
              lat: position.coords.latitude,
              lng: position.coords.longitude,
            };
            this.map.setCenter(pos)
          },
          () => {
            console.log(this.map.getCenter());
          }
        );
      }
    },
    handleFilter() {
      this.isLoading = true
      this.getSiteInfoList().then(() => {
        this.refreshMap()
      }).finally(() => {
        this.isLoading = false
      })
    }
  }
}
</script>

<style lang="scss" scoped="scoped">
  @import '../../../styles/variables.scss';

  .maps-container {
    width: 100%;
    padding: 20px;
    min-height: $mainAppMinHeight;
    background-color: #F0F5FC;
  }
  
  .maps-components {
    margin: 0px;
  }

  .card-group {
    display: flex;
    flex-wrap: wrap;
    flex-flow: wrap;
    align-items: flex-start;
  }

  .maps-card-view {
    flex: 1;
    display: flex;
    min-width: 200px;
    max-width: 320px;
    flex-direction: column;
    background-color: white;
    justify-content: center;
    align-items: center;
    padding: 10px 10px;
    margin-right: 10px;
    margin-bottom: 10px;
    border-radius: 6px;
  }
  
  .maps-card-view:last-child {
    margin-right: 0px;
  }
  
  .card-view-content {
    display: inline;
  }

  .card-title {
    font-family: sans-serif;
    font-style: normal;
    font-weight: bold;
    font-size: 16px;
    line-height: 24px;
    color: #333333;
  }

  .card-value-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
  }

  %card-value {
    font-family: sans-serif;
    font-style: normal;
    font-weight: 500;
    font-size: 42px;
    line-height: 63px;
  }

  .in-user-card-value {
    @extend %card-value;
    color: #F3B901;
  }

  .reserved-card-value {
    @extend %card-value;
    color: #3179E4;
  }

  .faulted-card-value {
    @extend %card-value;
    color: #ED3F3F;
  }

  .avaliable-card-value {
    @extend %card-value;
    color: #1ABD00;
  }

  .unavaliable-card-value {
    @extend %card-value;
    color: #666666;
  }

  %card-flag {
    display: inline;
    width: 120px;
    height: 3px;
    border-radius: 10px;
    margin-right: 20px;
    margin-bottom: 12px;
  }

  .in-user-card-flag {
    @extend %card-flag;
    background: linear-gradient(270deg, rgba(255, 204, 44, 0.1) 0%, #F3B901 100%);
  }

  .reserved-card-flag {
    @extend %card-flag;
    background: linear-gradient(270deg, rgba(49, 121, 228, 0.1) 0%, #3179E4 100%);
  }

  .faulted-card-flag {
    @extend %card-flag;
    background: linear-gradient(270deg, rgba(237, 63, 63, 0.1) 0%, #ED3F3F 100%);
  }

  .avaliable-card-flag {
    @extend %card-flag;
    background: linear-gradient(270deg, rgba(255, 204, 44, 0.1) 0%, #82CF08 100%);
  }

  .unavaliable-card-flag {
    @extend %card-flag;
    background: linear-gradient(270deg, rgba(102, 102, 102, 0.1) 0%, #666666 100%);
  }

  .google-map-container {
    padding: 0px;
    background-color: white;
  }

  .google-map {
    width: 100%;
    height: calc(#{$mainAppMinHeight} - 200px);
  }
  
  .google-map-cluster {
    background: var(--cluster-color);
    color: #fff;
    border-radius: 100%;
    font-weight: bold;
    font-size: 15px;
    display: flex;
    align-items: center;
    width: 30px;
    height: 35px;
  }

  .google-map-cluster img {
    width: 100%;
    height: auto;
    position: relative !important;
  }

  @media screen and (max-width: 851px) {

    .card-title {
      width: 129px;
      margin: 0px;
      text-align: center;
    }

  }

</style>
