import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import { fromLonLat } from "ol/proj";
import Point from "ol/geom/Point";
import {Fill, Stroke, Style, Text, Icon} from 'ol/style.js';
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from "ol/source";
import Feature from "ol/Feature";
import Overlay from "ol/Overlay";

const svg = () => {
  const screen_width = document.documentElement.clientWidth;

  let svg_width = 25;
  let svg_height = 45;

  if (
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
      navigator.userAgent
    )
  ) {
    svg_width = screen_width < 700 ? 30 : 50;
  }

  return `
  <svg xmlns="http://www.w3.org/2000/svg" fill="rgb(59 130 246)" width="${svg_width}" height="${svg_height}" viewBox="0 0 24 24" ><path fill="none" d="M0 0h24v24H0z"/><path d="M18.364 17.364L12 23.728l-6.364-6.364a9 9 0 1 1 12.728 0zM12 15a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-2a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/></svg>
  `
};

const createMap = (elId, zoom, coordinates = [37.619829, 55.752603]) => {
  return new Map(
    {
      target: elId,
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
      view: new View({
        projection: "EPSG:3857",
        center: fromLonLat(coordinates),
        zoom: zoom,
      }),
    }
  )
}

const mapFeature = (coordinate) => {
  return new Feature({
    geometry: new Point(coordinate).transform("EPSG:4326", "EPSG:900913"),
    projection: "EPSG:4326",
  });
}

const iconFeature = (point) => {
  return new Feature({
    geometry: new Point(point).transform("EPSG:4326", "EPSG:900913"),
    projection: "EPSG:4326",
  });
};

const iconStyle = (color, text, course = null) =>
  new Style({
    image: new Icon({
      scale: 1.4,
      anchor: [0.45, 32],
      anchorXUnits: "fraction",
      anchorYUnits: "pixels",
      src: "data:image/svg+xml;utf8," + svg(color, course),
    }),
    text: new Text({
      text: text,
      offsetY: -14,
      offsetX: -18,
      textBaseline: 'middle',
      backgroundFill: new Fill({color: [90, 90, 60, 0.8]}),
      backgroundStroke: new Stroke({color: [25, 230, 115, 0]}),
      padding: [3, 3, 3, 3],
      textAlign: 'right',
      justify: 'left',
      font: '12px bold Calibri,sans-serif',
      fill: new Fill({
        color: 'white',
      }),
    }),
  });

const labelStyle = (text) => new Style({
  text: new Text({
    text: text,
    font: '25px Calibri,sans-serif',
    fill: new Fill({
      color: '#fff',
    }),
  }),
});

const addLayerIcon = (map, coordinates, text) => {
  return map.addLayer(
    new VectorLayer({
      type: "vector_layer",
      source: new VectorSource({
        features: [iconFeature(coordinates)],
      }),
      style: [
        iconStyle("green", text),
      ],
    })
  )
}

const addLayer = (map, coordinates, text) => {
  return map.addLayer(
    new VectorLayer({
      type: "vector_layer",
      source: new VectorSource({
        features: [mapFeature(coordinates), iconFeature(coordinates)],
      }),
      style: [
        iconStyle("green", text),
      ],
    })
  )
}

const setView = (map, zoom, coordinates) => {
  return map.setView(new View({
    projection: "EPSG:3857",
    center: fromLonLat(coordinates),
    zoom: zoom,
  }))
}

const addLayerWithEmptyCoords = (map, labelText) => {
  return map.addLayer(
    new VectorLayer({
      type: "vector_layer",
      background: 'rgba(0,0,0,0.7)',
      source: new VectorSource({
        features: [mapFeature([37.619829, 55.752603])]
      }),
      style: [labelStyle(labelText)]
    })
  )
}

const removeLayers = (map) => {
  return map.getLayers().forEach(layer => {
    if(layer?.values_?.type == "vector_layer") {
      map.removeLayer(layer)
    }
  })
}

const setTooltip = (map, coordinates, machine, tooltip_id, content_id, closer_id) => {
  const tooltipSelector = document.getElementById(tooltip_id)
  const contentSelector = document.getElementById(content_id)
  const onClose = document.getElementById(closer_id)

  const tooltip = new Overlay({
    element: tooltipSelector,
  })
  map.addOverlay(tooltip)

  const tooltipContent = new Overlay({
    position: coordinates,
    positioning: 'center-center',
    element: contentSelector,
    stopEvent: false,
  });

  map.addOverlay(tooltipContent)

  
  const onClosed = () => {
    if(onClose) {
      tooltip.setPosition(undefined)
      onClose.blur()
      const tooltipText = tooltipSelector.querySelector(`.${content_id}`)
      if(tooltipText) {
        tooltipText.remove()
      }
    }
  }
  
  map.on('click', function (e) {
    const feature = map.forEachFeatureAtPixel(e.pixel, function (feature) {
      return feature;
    })

    onClosed()

    const tooltipText = document.createElement('div')
    tooltipText.classList.add(content_id)

    if (feature) {
      const container = tooltip.getElement();
      const props = feature.getProperties()

      const coordsFormated = feature.getGeometry()
      const coordsFormat = feature.getGeometry().getFlatCoordinates()

      // const hdms = toLonLat(coordinates)
  
      // setTimeout(() => {
      container.style.opacity = "1"
      container.style.display = "flex"
      container.style.minWidth = "max-content"
      tooltipText.innerHTML = `
        <div class="flex flex-col justify-items-center">
          <div class="tooltip-title flex text-lg text-blue-500"> ${machine.machine_type} </div>
          <code> ${coordinates} </code>
          <hr class="mt-1 mb-2">
          <div class="tooltip-title flex text-sm"><div class="w-20">Imei:</div> <div>${machine.imei}</div> </div>
          <div class="tooltip-title flex text-sm"><div class="w-20">Дорога:</div> <div>${machine.railway_name}</div> </div>
          <div class="tooltip-title flex text-sm"><div class="w-20">Компания:</div> <div>${machine.org_name}</div> </div>
          <div class="tooltip-title flex text-sm"><div class="w-20">8зн номер:</div> <div>${machine.nomer_zn8}</div> </div>
          <div class="tooltip-title flex text-sm"><div class="w-20">Устройство:</div> <div>${machine.device_number}</div> </div>
          <a class="flex justify-center items-center bg-blue-300 hover:bg-blue-400 text-gray-800 p-1 mt-2 rounded" target="_blank" href="/html/askr_devices/analyze_comm/${machine.imei}"}">Детализация</a>
        </div>`
      container.prepend(tooltipText)
      // }, 200)
  
      tooltip.setPosition(e.coordinate)
    }
  });
  
  map.on('pointermove', function (e) {
    const pixel = map.getEventPixel(e.originalEvent);
    const hit = map.hasFeatureAtPixel(pixel);
    // console.log('hit', hit)
    // console.log('pixel', pixel)
    // console.log('map', map)
    // map.getTarget().style.cursor = hit ? 'pointer' : '';
  })

  onClose.addEventListener('click', onClosed)
}


export class CoordsMap {

  constructor(id) {
    this.id = id
  }

  loadMap(coordinates, machine) {
    if(!coordinates) {
      if(!this.map) {
        console.log('coordinates', coordinates)
        console.log('machine', machine)
        this.map = createMap(this.id, 5)
        addLayerWithEmptyCoords(this.map, 'Данных о местоположении машины нет')
      } else {
        removeLayers(this.map)
        addLayerWithEmptyCoords(this.map, 'Данных о местоположении машины нет')
        setView(this.map, 5, [37.619829, 55.752603])
      }
    }

    if(coordinates) {
      console.log('coordinates', coordinates)
      console.log('machine', machine)
      if(!this.map) {
        this.map = createMap(this.id, 8, coordinates)
        addLayerIcon(this.map, coordinates, `${coordinates[1] ? +coordinates[1].toFixed(5) : ''} ${coordinates[0] ? +coordinates[0].toFixed(5) : ''}`)

      } else {
        removeLayers(this.map)
        addLayerIcon(this.map, coordinates, `${coordinates[1] ? +coordinates[1].toFixed(5) : ''} ${coordinates[0] ? +coordinates[0].toFixed(5) : ''}`)
        setView(this.map, 8, coordinates)
      }
    }
    
    if(coordinates && machine) {
      if(!this.map) {
        this.map = createMap(this.id, 8, coordinates)
        addLayerIcon(this.map, coordinates, machine.machine_type)
        setTooltip(this.map, coordinates, machine, 'popup', 'popup-content', 'popup-closer') 
        // this.map.addOverlay(popup)
        // this.map.addOverlay(marker(coordinates))
        // setOverlay(this.map)

      } else if (machine) {
        removeLayers(this.map)
        addLayer(this.map, coordinates, machine.machine_type)
        setView(this.map, 8, coordinates)
        setTooltip(this.map, coordinates, machine, 'popup', 'popup-content', 'popup-closer') 
        // this.map.addOverlay(popup)
        // this.map.addOverlay(marker(coordinates))
        // setOverlay(this.map)
      }
    }
  }
}