import { useEffect, useRef, useState } from 'react'
import GeoJSON from 'ol/format/GeoJSON'
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Draw, Modify, Snap } from 'ol/interaction'
import { OSM, Vector as VectorSource } from 'ol/source'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { transform, transformExtent } from 'ol/proj'
import { Divider, IconButton, Stack } from '@mui/material'
import { Adjust, Api, CircleOutlined, RectangleOutlined, Timeline, Undo, Warning } from '@mui/icons-material'
import { Type } from 'ol/geom/Geometry'

const MapComponent = () => {
    const mapElement = useRef<HTMLDivElement | null>(null)
    const [currentTool, setCurrentTool] = useState<Type>('Point')

    const map = useRef<Map | null>(null)
    const source = useRef<VectorSource>(new VectorSource())

    const draw = useRef<Draw | null>(null)
    const snap = useRef<Snap | null>(null)

    const drawingLayer = useRef<VectorLayer | null>(null)

    const addInteractions = () => {
        draw.current = new Draw({
            source: source.current,
            type: currentTool,
        })
        map?.current?.addInteraction(draw.current)
        snap.current = new Snap({ source: source.current })
        map?.current?.addInteraction(snap.current)
    }

    // Function to save features to localStorage
    const saveFeatures = () => {
        const features = drawingLayer.current?.getSource()?.getFeatures()
        if (features && features.length > 0) {
            const geoJSON = new GeoJSON()
            const featuresJSON = geoJSON.writeFeatures(features)
            localStorage.setItem('savedFeatures', featuresJSON)
        }
    }

    // Function to load features from localStorage
    const loadFeatures = () => {
        const savedFeatures = localStorage.getItem('savedFeatures')
        if (savedFeatures) {
            const geoJSON = new GeoJSON()
            const features = geoJSON.readFeatures(savedFeatures, {
                featureProjection: 'EPSG:4326', // Ensure the projection is correct
            })
            source.current?.addFeatures(features)  // Add features to the vector source
            //drawingLayer.current?.getSource()?.changed()
        }
    }

    useEffect(() => {
        const geoLayer = new VectorLayer({
            background: '#1a2b39',
            source: new VectorSource({
                url: 'https://openlayers.org/data/vector/ecoregions.json',
                format: new GeoJSON(),
            }),
            style: {
                'fill-color': ['string', ['get', 'COLOR'], '#eee'],
            },
        })

        const raster = new TileLayer({
            source: new OSM(),
        })

        drawingLayer.current = new VectorLayer({
            source: source.current,
            style: {
                'fill-color': 'rgba(255, 255, 255, 0.2)',
                'stroke-color': '#ffcc33',
                'stroke-width': 2,
                'circle-radius': 7,
                'circle-fill-color': '#ffcc33',
            },
        })

        // Center coordinates of Yakutia in EPSG:3857
        const center = transform([129.7694, 66.9419], 'EPSG:4326', 'EPSG:3857')

        // Extent for Yakutia in EPSG:4326
        const extent4326 = [105.0, 55.0, 170.0, 75.0] // Approximate bounding box
        // Transform extent to EPSG:3857
        const extent = transformExtent(extent4326, 'EPSG:4326', 'EPSG:3857')

        map.current = new Map({
            layers: [geoLayer, raster, drawingLayer.current],
            target: mapElement.current as HTMLDivElement,
            view: new View({
                center,
                zoom: 4,
                extent,
            }),
        })

        const modify = new Modify({ source: source.current })
        map.current.addInteraction(modify)

        addInteractions()

        loadFeatures()

        return () => {
            map?.current?.setTarget(undefined)
        }
    }, [])

    useEffect(() => {
        if (currentTool) {
            if (draw.current) map?.current?.removeInteraction(draw.current)
            if (snap.current) map?.current?.removeInteraction(snap.current)
            addInteractions()
        }
    }, [currentTool])

    return (
        <div>
            <Stack my={1} spacing={1} direction='row' divider={<Divider orientation='vertical' flexItem />}>
                <IconButton onClick={() => {
                    fetch(`${import.meta.env.VITE_API_EMS_URL}/hello`, { method: 'GET' }).then(res => console.log(res))
                }}>
                    <Api />
                </IconButton>

                <IconButton onClick={() => {
                    saveFeatures()
                }}>
                    <Warning />
                </IconButton>

                <IconButton
                    onClick={() => {
                        draw.current?.removeLastPoint()
                    }}>
                    <Undo />
                </IconButton>

                <IconButton
                    sx={{ backgroundColor: currentTool === 'Point' ? 'Highlight' : 'transparent' }}
                    onClick={() => setCurrentTool('Point')}>
                    <Adjust />
                </IconButton>

                <IconButton
                    sx={{ backgroundColor: currentTool === 'LineString' ? 'Highlight' : 'transparent' }}
                    onClick={() => setCurrentTool('LineString')}>
                    <Timeline />
                </IconButton>

                <IconButton
                    sx={{ backgroundColor: currentTool === 'Polygon' ? 'Highlight' : 'transparent' }}
                    onClick={() => setCurrentTool('Polygon')}>
                    <RectangleOutlined />
                </IconButton>

                <IconButton
                    sx={{ backgroundColor: currentTool === 'Circle' ? 'Highlight' : 'transparent' }}
                    onClick={() => setCurrentTool('Circle')}>
                    <CircleOutlined />
                </IconButton>
            </Stack>
            <div ref={mapElement} style={{ width: '100%', height: '400px' }}></div>
        </div>
    );
};

export default MapComponent
