import React, { useRef, useEffect, useState } from 'react';
// import { useNavigate } from 'react-router-dom';
//Helpers
import axios from 'axios';
//MapBox
/* eslint import/no-webpack-loader-syntax: off */
import mapboxgl from '!mapbox-gl'; // eslint-disable-line import/no-webpack-loader-syntax
//Styles
import 'mapbox-gl/dist/mapbox-gl.css';
import './styles/Map.css'
import { ThreeCircles } from 'react-loader-spinner';

mapboxgl.workerClass = require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default;

//HOSTED VERSION
mapboxgl.accessToken = `${process.env.REACT_APP_MAPBOX_PUBLIC_KEY}`;

export default function BikeMap() {
    const [postalSearch, setPostalSearch] = useState();
    const [error, setError] = useState('');
    const [isLoading, setLoading] = useState(true);
    const mapContainer = useRef(null);
    const map = useRef(null);
    const [lng, setLng] = useState(-73.5673);
    const [lat, setLat] = useState(45.5017);
    const [zoom, setZoom] = useState(11);

    function handleSearch() {
        let data = " ";
        if (postalSearch !== null) {
            data = { postalCode: postalSearch };
        }
        axios.post(`/api/stations/closestStation`, data).then((response) => {
            let stationElementId = "link-" + response.data.id;
            let stationClick = document.getElementById(stationElementId)
            stationClick.click();
        }).catch((error) => {
            setError(error.response.data.error ?? error.response.data.message ?? "There was a problem");

        });
    }

    //Fetches Station list from server, builds map, builds station list, and adds custom markers on page load
    useEffect(() => {
        window.scrollTo(0, 0)
        axios.get(`/api/stations`).then((response) => {
            const stationData = response.data;
            const GeoFeatures = buildGeojson(stationData);

            if (GeoFeatures) {
                buildMap();
                addMarkers(GeoFeatures);
                buildLocationList(GeoFeatures);
                setLoading(false);
            }

            function buildGeojson(stations) {
                const featuresArray = [];
                stations.forEach(station => {
                    let discountMessage = ""
                    let discountCheck = (station.availableSlots / station.totalSlots) * 100;
                    if (discountCheck >= 90) {
                        discountMessage = "Return Discount ACTIVE"
                    }
                    if (discountCheck <= 10) {
                        discountMessage = "Rent Discount ACTIVE"
                    }
                    const feature =
                    {
                        type: 'Feature',
                        geometry: {
                            type: 'Point',
                            coordinates: [station.longitude, station.latitude]
                        },
                        properties: {
                            title: station.name,
                            description: 'Available bikes: ' + station.numberOfBikes,
                            id: station.id,
                            discountStatus: discountMessage
                        }
                    }
                    featuresArray.push(feature);
                });
                return featuresArray;
            }

            function buildMap() {
                //Prevent map from reloading after interaction
                if (map.current) return;
                map.current = new mapboxgl.Map({
                    container: mapContainer.current,
                    style: 'mapbox://styles/mapbox/streets-v11',
                    center: [lng, lat],
                    zoom: zoom
                });

                // Add navigation control (the +/- zoom buttons)
                map.current.addControl(new mapboxgl.NavigationControl(), 'top-right');
                map.current.on('move', () => {
                    setLng(map.current.getCenter().lng.toFixed(4));
                    setLat(map.current.getCenter().lat.toFixed(4));
                    setZoom(map.current.getZoom().toFixed(2));
                });
            }

            function addMarkers(GeoFeatures) {
                // set marker data
                const geojson = {
                    type: 'FeatureCollection',
                    features: GeoFeatures
                };

                /* For each feature in the GeoJSON object above: */
                for (const marker of geojson.features) {
                    /* Create a div element for the marker. */
                    const el = document.createElement('div');
                    /* Assign a unique `id` to the marker. */
                    el.id = `marker-${marker.properties.id}`;
                    /* Assign the `marker` class to each marker for styling. */
                    el.className = 'marker';

                    /**
                    * Create a marker using the div element
                    * defined above and add it to the map.
                    **/
                    new mapboxgl.Marker(el, { offset: [0, -23] })
                        .setLngLat(marker.geometry.coordinates)
                        .addTo(map.current);

                    /**
                    * Listen to the element and when it is clicked, do three things:
                    * 1. Fly to the point
                    * 2. Close all other popups and display popup for clicked store
                    * 3. Highlight listing in sidebar (and remove highlight for all other listings)
                    **/
                    el.addEventListener('click', (e) => {
                        /* Fly to the point */
                        flyToStation(marker);
                        /* Close all other popups and display popup for clicked store */
                        createPopUp(marker);
                        /* Highlight listing in sidebar */
                        const activeItem = document.getElementsByClassName('active');
                        e.stopPropagation();
                        if (activeItem[0]) {
                            activeItem[0].classList.remove('active');
                        }
                        const listing = document.getElementById(
                            `listing-${marker.properties.id}`
                        );
                        listing.classList.add('active');
                    });
                }
            }

            function buildLocationList(stations) {
                const listings = document.getElementById('listings');
                listings.innerHTML = "";
                for (const station of stations) {
                    /* Add a new listing section to the sidebar. */
                    const listing = listings.appendChild(document.createElement('div'));
                    /* Assign a unique `id` to the listing. */
                    listing.id = `listing-${station.properties.id}`;
                    /* Assign the `item` class to each listing for styling. */
                    listing.className = 'item';

                    /* Add the link to the individual listing created above. */
                    const link = listing.appendChild(document.createElement('a'));
                    link.href = '#';
                    link.className = 'title';
                    link.id = `link-${station.properties.id}`;
                    link.innerHTML = `Station: ${station.properties.title}`;

                    /* Add details to the individual listing. */
                    const details = listing.appendChild(document.createElement('div'));
                    details.innerHTML = `${station.properties.description}`;

                    /**
                    * Listen to the element and when it is clicked, do four things:
                    * 1. Update the `currentFeature` to the station associated with the clicked link
                    * 2. Fly to the point
                    * 3. Close all other popups and display popup for clicked station
                    * 4. Highlight listing in sidebar (and remove highlight for all other listings)
                    **/
                    link.addEventListener('click', function () {
                        for (const feature of stations) {
                            if (this.id === `link-${feature.properties.id}`) {
                                flyToStation(feature);
                                createPopUp(feature);
                            }
                        }
                        const activeItem = document.getElementsByClassName('active');
                        if (activeItem[0]) {
                            activeItem[0].classList.remove('active');
                        }
                        this.parentNode.classList.add('active');
                    });
                }
            }

            function flyToStation(currentFeature) {
                map.current.flyTo({
                    center: currentFeature.geometry.coordinates,
                    zoom: 15
                });
            }

            /**
            * Create a Mapbox GL JS `Popup`.
            **/
            function createPopUp(feature) {
                const popUps = document.getElementsByClassName('mapboxgl-popup');
                if (popUps[0]) popUps[0].remove();
                new mapboxgl.Popup({ closeOnClick: false })
                    .setLngLat(feature.geometry.coordinates)
                    .setHTML(
                        `
                            <h3 class="shadow-sm">${feature.properties.title}</h3>
                            <p>${feature.properties.description}</p>
                            <small class='fst-italic fw-light text-success'>${feature.properties.discountStatus}</small>
                            <a class='w-75 btn btn-bg shadow mb-3' href="/stations/rent-bike/${feature.properties.id}"'>Rent Bike</a>
                            <a class='w-75 btn btn-bg shadow' href="/stations/return-bike/${feature.properties.id}"'>Return Bike</a>
                            `
                    )
                    .addTo(map.current);
            }

        });
    }, []);//lat, lng, zoom

    //FIXME: Map.js:254 Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
    // function postalCodeOnly(input) {
    //     console.log(input);
    //     var regex = /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/gi;
    //     input.value = input.value.replace(regex, "")
    // }

    return (
        <div className='h-100'>
            <div className="loadingContainer">
                <ThreeCircles
                    type="ThreeDots"
                    color="#00b22d"
                    height={100}
                    width={100}
                //3 secs
                />
            </div>
            <div style={(isLoading === true) ? { visibility: ' hidden' } : {}}>
                <div className='map-search w-100 d-flex justify-content-center align-items-center'>
                    <h3 className='text-white align-middle my-3 mx-3'>Find Nearest Station</h3>
                    <div className="d-flex justify-content-center align-items-center">
                        <input
                            type="search"
                            className="form-control rounded my-3 input-group rounded w-75"
                            placeholder="H1A 1A1"
                            aria-label="Search"
                            aria-describedby="Search"
                            onKeyUp={(event) => {
                                // postalCodeOnly(event.target.value);
                                setPostalSearch(event.target.value);
                            }}
                        />

                        <button
                            className="w-auto search-btn rounded-circle mx-4 shadow"
                            type="submit"
                            onClick={handleSearch}
                        >
                            <svg
                                xmlns="http://www.w3.org/2000/svg"
                                width="16"
                                height="16"
                                className="bi bi-search"
                                viewBox="0 0 16 16"
                            >
                                <path
                                    d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z">
                                </path>
                            </svg>
                        </button>

                        <span className="text-danger">{error}</span>
                    </div>
                </div>
                <div ref={mapContainer} className="map-container">
                    <div className="sidebar d-none d-md-block">
                        <div className="heading">
                            <h1 className='station-list-title'>Stations</h1>
                        </div>
                        <div className='d-flex flex-column justify-content-start'>
                            <div>Longitude: {lng} | Latitude: {lat} | Zoom: {zoom}</div>
                            <hr />
                            <div id="listings" className="listings"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )

}
