import { useCallback, useEffect, useRef, useState } from 'react'
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Draw, Modify, Select, Snap, Translate } from 'ol/interaction'
import { ImageStatic, OSM, Vector as VectorSource, XYZ } from 'ol/source'
import { Tile as TileLayer, VectorImage, Vector as VectorLayer } from 'ol/layer'
import { click, never, platformModifierKeyOnly, primaryAction, shiftKeyOnly } from 'ol/events/condition'
import Feature from 'ol/Feature'
import { IRectCoords, SatelliteMapsProvider } from '../../interfaces/map'
import { Extent } from 'ol/extent'
import { drawingLayerStyle, highlightStyleRed, highlightStyleYellow, overlayStyle, regionsLayerStyle } from './MapStyles'
import { googleMapsSatelliteSource, regionsLayerSource, yandexMapsSatelliteSource } from './MapSources'
import ImageLayer from 'ol/layer/Image'
import { LineString, Point, SimpleGeometry } from 'ol/geom'
import { fromExtent } from 'ol/geom/Polygon'
import Collection from 'ol/Collection'
import { Coordinate } from 'ol/coordinate'
import { addInteractions, calculateCenter, loadFeatures, processFigure, processLine, regionsInit, saveFeatures, updateImageSource } from './mapUtils'
import MapBrowserEvent from 'ol/MapBrowserEvent'
import { get, transform } from 'ol/proj'
import useSWR from 'swr'
import { fetcher } from '../../http/axiosInstance'
import { BASE_URL } from '../../constants'
import { ActionIcon, Autocomplete, Box, CloseButton, Flex, Select as MantineSelect, MantineStyleProp, rem, Slider, useMantineColorScheme, Portal, Menu, Button, Group, Divider, LoadingOverlay } from '@mantine/core'
import { IconBoxMultiple, IconChevronDown, IconPlus, IconSearch, IconSettings, IconUpload } from '@tabler/icons-react'
import { getGridCellPosition } from './mapUtils'
import { IFigure, ILine } from '../../interfaces/gis'
import axios from 'axios'
import MapToolbar from './MapToolbar/MapToolbar'
import MapStatusbar from './MapStatusbar/MapStatusbar'
import { measureStyleFunction, modifyStyle } from './Measure/MeasureStyles'
import { setCurrentCoordinate, setCurrentX, setCurrentY, setCurrentZ, setSatMapsProvider, useMapStore } from '../../store/map'
import { v4 as uuidv4 } from 'uuid'
import { useThrottle } from '@uidotdev/usehooks'
import ObjectTree from '../Tree/ObjectTree'
import { setCurrentObjectId, setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../store/objects'
import MapLayers from './MapLayers/MapLayers'
import ObjectParameters from './ObjectParameters/ObjectParameters'
import TabsPane, { ITabsPane } from './TabsPane/TabsPane'
import { mapExtent } from './MapConstants'

// Tab settings
const objectsPane: ITabsPane[] = [
    {
        title: 'Объекты',
        value: 'objects',
        view: <ObjectTree />
    },
    {
        title: 'Неразмещенные',
        value: 'unplaced',
        view: <></>
    },
    {
        title: 'Другие',
        value: 'other',
        view: <></>
    },
]

const paramsPane: ITabsPane[] = [
    {
        title: 'История изменений',
        value: 'history',
        view: <></>
    },
    {
        title: 'Параметры',
        value: 'parameters',
        view: <ObjectParameters />
    },
    {
        title: 'Вычисляемые',
        value: 'calculated',
        view: <></>
    },
]

// Settings for cities
const citySettings = [
    {
        city_id: 145,
        image_width: 8500,
        image_height: 12544,
        // scale: 10000,
        scale: 9000,
        offset_x: 14442665.697619518,
        offset_y: 8884520.63524492,
        rotation: 0
    }
]

const MapComponent = () => {
    const { colorScheme } = useMantineColorScheme();

    // States
    const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore()
    const { currentTool, satMapsProvider, selectedObjectType } = useMapStore()
    ///

    const [file, setFile] = useState<File | null>(null)
    const [polygonExtent, setPolygonExtent] = useState<Extent | undefined>(undefined)

    const [rectCoords, setRectCoords] = useState<IRectCoords | undefined>(undefined)

    // Measure
    const measureSource = useRef(new VectorSource())
    const measureModify = useRef(new Modify({ source: measureSource.current, style: modifyStyle }))

    const measureLayer = useRef(new VectorLayer({
        source: measureSource.current,
        style: function (feature) {
            return measureStyleFunction(feature);
        },
        properties: {
            id: uuidv4(),
            type: 'measure',
            name: 'Линейка'
        }
    }))

    const measureDraw = useRef<Draw | null>(null)

    const mapElement = useRef<HTMLDivElement | null>(null)

    const map = useRef<Map | null>(null)

    const gMapsSatSource = useRef<XYZ>(googleMapsSatelliteSource)

    const customMapSource = useRef<XYZ>(new XYZ({
        url: `${import.meta.env.VITE_API_EMS_URL}/tiles/tile/custom/{z}/{x}/{y}`,
        attributions: 'Custom map data'
    }))

    const yMapsSatSource = useRef<XYZ>(yandexMapsSatelliteSource)

    const satLayer = useRef<TileLayer>(new TileLayer({
        source: gMapsSatSource.current,
        properties: {
            id: uuidv4(),
            name: 'Спутник'
        }
    }))

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

    const selectFeature = useRef<Select>(new Select({
        condition: function (mapBrowserEvent) {
            return click(mapBrowserEvent) && shiftKeyOnly(mapBrowserEvent);
        },
    }))

    const nodeLayer = useRef<VectorLayer | null>(null)
    const nodeLayerSource = useRef<VectorSource>(new VectorSource())

    const overlayLayer = useRef<VectorLayer | null>(null)
    const overlayLayerSource = useRef<VectorSource>(new VectorSource())

    const drawingLayer = useRef<VectorLayer | null>(null)
    const drawingLayerSource = useRef<VectorSource>(new VectorSource())

    const citiesLayer = useRef<VectorLayer>(new VectorLayer({
        source: new VectorSource(),
        properties: {
            id: uuidv4(),
            name: 'Города'
        }
    }))

    const figuresLayer = useRef<VectorLayer>(new VectorLayer({
        source: new VectorSource(),
        declutter: true,
        properties: {
            id: uuidv4(),
            name: 'Фигуры'
        }
    }))

    const linesLayer = useRef<VectorLayer>(new VectorLayer({
        source: new VectorSource(),
        declutter: true,
        properties: {
            id: uuidv4(),
            name: 'Линии'
        }
    }))

    const regionsLayer = useRef<VectorImage>(new VectorImage({
        source: regionsLayerSource,
        declutter: true,
        style: regionsLayerStyle,
        properties: {
            id: uuidv4(),
            name: 'Регион'
        }
    }))

    const selectedArea = useRef<Feature | null>(null)

    const baseLayer = useRef<TileLayer>(new TileLayer({
        source: new OSM(),
        properties: {
            id: uuidv4(),
            name: 'OpenStreetMap'
        }
    }))

    const imageLayer = useRef<ImageLayer<ImageStatic>>(new ImageLayer({
        properties: {
            id: uuidv4(),
            name: 'Изображение'
        }
    }))

    const staticMapLayer = useRef<ImageLayer<ImageStatic>>(new ImageLayer({
        properties: {
            id: uuidv4(),
            name: 'Static image'
        }
    }))

    // tile processing
    const handleImageDrop = useCallback((event: DragEvent) => {
        event.preventDefault();
        event.stopPropagation();

        if (!event.dataTransfer?.files) return

        const files = event.dataTransfer.files;
        if (files.length > 0) {
            const file = files[0];
            setFile(file)

            if (file.type.startsWith('image/')) {
                const reader = new FileReader();

                reader.onload = () => {
                    const imageUrl = reader.result as string;
                    const img = new Image();
                    img.src = imageUrl;
                    img.onload = () => {
                        if (map.current) {
                            const view = map.current.getView();
                            const center = view.getCenter() || [0, 0];

                            const width = img.naturalWidth;
                            const height = img.naturalHeight;
                            const resolution = view.getResolution() || 0;

                            const extent = [
                                center[0] - (width * resolution) / 20,
                                center[1] - (height * resolution) / 20,
                                center[0] + (width * resolution) / 20,
                                center[1] + (height * resolution) / 20,
                            ];

                            // Create a polygon feature with the same extent as the image
                            const polygonFeature = new Feature({
                                geometry: fromExtent(extent),
                            });

                            // Add the polygon feature to the drawing layer source
                            overlayLayerSource.current?.addFeature(polygonFeature);

                            // Set up the initial image layer with the extent
                            const imageSource = new ImageStatic({
                                url: imageUrl,
                                imageExtent: extent,
                            });
                            imageLayer.current.setSource(imageSource);

                            //map.current.addLayer(imageLayer.current);

                            // Add interactions for translation and scaling
                            const translate = new Translate({
                                layers: [imageLayer.current],
                                features: new Collection([polygonFeature]),
                            });

                            const defaultStyle = new Modify({ source: overlayLayerSource.current })
                                .getOverlay()
                                .getStyleFunction();

                            const modify = new Modify({
                                insertVertexCondition: never,
                                source: overlayLayerSource.current,
                                condition: function (event) {
                                    return primaryAction(event) && !platformModifierKeyOnly(event);
                                },
                                deleteCondition: never,
                                features: new Collection([polygonFeature]),
                                style: function (feature) {
                                    feature.get('features').forEach(function (modifyFeature: Feature) {
                                        const modifyGeometry = modifyFeature.get('modifyGeometry')
                                        if (modifyGeometry) {
                                            const point = (feature.getGeometry() as Point).getCoordinates()
                                            let modifyPoint = modifyGeometry.point
                                            if (!modifyPoint) {
                                                // save the initial geometry and vertex position
                                                modifyPoint = point;
                                                modifyGeometry.point = modifyPoint;
                                                modifyGeometry.geometry0 = modifyGeometry.geometry;
                                                // get anchor and minimum radius of vertices to be used
                                                const result = calculateCenter(modifyGeometry.geometry0);
                                                modifyGeometry.center = result.center;
                                                modifyGeometry.minRadius = result.minRadius;
                                            }
                                            const center = modifyGeometry.center;
                                            const minRadius = modifyGeometry.minRadius;
                                            let dx, dy;
                                            dx = modifyPoint[0] - center[0];
                                            dy = modifyPoint[1] - center[1];
                                            const initialRadius = Math.sqrt(dx * dx + dy * dy);
                                            if (initialRadius > minRadius) {
                                                const initialAngle = Math.atan2(dy, dx);
                                                dx = point[0] - center[0];
                                                dy = point[1] - center[1];
                                                const currentRadius = Math.sqrt(dx * dx + dy * dy);
                                                if (currentRadius > 0) {
                                                    const currentAngle = Math.atan2(dy, dx);
                                                    const geometry = modifyGeometry.geometry0.clone();
                                                    geometry.scale(currentRadius / initialRadius, undefined, center);
                                                    geometry.rotate(currentAngle - initialAngle, center);
                                                    modifyGeometry.geometry = geometry;
                                                }
                                            }
                                        }
                                    })
                                    const res = map?.current?.getView()?.getResolution()
                                    if (typeof res === 'number' && feature && defaultStyle) {
                                        return defaultStyle(feature, res)
                                    }
                                }
                            });

                            translate.on('translateend', () => updateImageSource(imageUrl, imageLayer, polygonFeature, setPolygonExtent, setRectCoords));
                            //modify.on('modifyend', updateImageSource);

                            modify.on('modifystart', function (event) {
                                event.features.forEach(function (feature) {
                                    feature.set(
                                        'modifyGeometry',
                                        { geometry: feature.getGeometry()?.clone() },
                                        true,
                                    );
                                });
                            });

                            modify.on('modifyend', function (event) {
                                event.features.forEach(function (feature) {
                                    const modifyGeometry = feature.get('modifyGeometry');
                                    if (modifyGeometry) {
                                        feature.setGeometry(modifyGeometry.geometry);
                                        feature.unset('modifyGeometry', true);
                                    }
                                })
                                updateImageSource(imageUrl, imageLayer, polygonFeature, setPolygonExtent, setRectCoords)
                            })

                            map.current.addInteraction(translate);
                            map.current.addInteraction(modify);
                        }
                    };
                };
                reader.readAsDataURL(file);
            }
        }
    }, [])

    useEffect(() => {
        drawingLayer.current = new VectorLayer({
            source: drawingLayerSource.current,
            style: drawingLayerStyle,
            properties: {
                id: uuidv4(),
                name: 'Чертеж'
            }
        })

        overlayLayer.current = new VectorLayer({
            source: overlayLayerSource.current,
            style: overlayStyle,
            properties: {
                id: uuidv4(),
                name: 'Наложения'
            }
        })

        nodeLayer.current = new VectorLayer({
            source: nodeLayerSource.current,
            style: drawingLayerStyle,
            properties: {
                id: uuidv4(),
                name: 'Узлы'
            }
        })

        map.current = new Map({
            controls: [],
            layers: [
                baseLayer.current,
                satLayer.current,
                staticMapLayer.current,
                regionsLayer.current,
                citiesLayer.current,
                linesLayer.current,
                figuresLayer.current,
                drawingLayer.current,
                imageLayer.current,
                overlayLayer.current,
                nodeLayer.current,
                measureLayer.current
            ],
            target: mapElement.current as HTMLDivElement,
            view: new View({
                center: transform([129.7466541, 62.083504], 'EPSG:4326', 'EPSG:3857'),//center: fromLonLat([130.401113, 67.797368]),
                //zoom: 16,
                zoom: 5,
                maxZoom: 21,
                extent: mapExtent,
            }),
        })

        map.current.on('pointermove', function (e: MapBrowserEvent<UIEvent>) {
            setCurrentCoordinate(e.coordinate)
            const currentExtent = get('EPSG:3857')?.getExtent() as Extent
            const { tileX, tileY } = getGridCellPosition(e.coordinate[0], e.coordinate[1], currentExtent, Number(map.current?.getView().getZoom()?.toFixed(0)))
            setCurrentZ(Number(map.current?.getView().getZoom()?.toFixed(0)))
            setCurrentX(tileX)
            setCurrentY(tileY)
        })

        map.current.on('click', function (e: MapBrowserEvent<UIEvent>) {
            const pixel = map.current?.getEventPixel(e.originalEvent)

            if (pixel) {
                map.current?.forEachFeatureAtPixel(pixel, function (feature) {
                    setCurrentObjectId(feature.get('object_id'))
                })
            }
        })

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

        map.current.addInteraction(selectFeature.current)

        selectFeature.current.on('select', (e) => {
            const selectedFeatures = e.selected

            if (selectedFeatures.length > 0) {
                selectedFeatures.forEach((feature) => {
                    drawingLayerSource.current?.removeFeature(feature)
                })
            }
        })

        loadFeatures(drawingLayerSource)

        regionsInit(map, selectedArea, regionsLayer)

        if (mapElement.current) {
            mapElement.current.addEventListener('dragover', (e) => {
                e.preventDefault()
            })

            mapElement.current.addEventListener('drop', handleImageDrop)
        }

        return () => {
            map?.current?.setTarget(undefined)

            if (mapElement.current) {
                mapElement.current.removeEventListener('drop', handleImageDrop)
            }
        }
    }, [])

    useEffect(() => {
        if (currentTool) {
            if (draw.current) map?.current?.removeInteraction(draw.current)
            //if (snap.current) map?.current?.removeInteraction(snap.current)
            addInteractions(drawingLayerSource, translate, draw, map, snap, measureDraw, measureSource, measureModify)
        } else {
            if (translate.current) map?.current?.removeInteraction(translate.current)
            if (draw.current) map?.current?.removeInteraction(draw.current)
            if (snap.current) map?.current?.removeInteraction(snap.current)
            if (measureDraw.current) map?.current?.removeInteraction(measureDraw.current)
        }
    }, [currentTool])

    const [satelliteOpacity, setSatelliteOpacity] = useState<number>(0)

    // Visibility setting
    useEffect(() => {
        satLayer.current?.setOpacity(satelliteOpacity)

        if (satelliteOpacity == 0) {
            baseLayer.current?.setVisible(true)
            satLayer.current?.setVisible(false)
        } if (satelliteOpacity == 1) {
            baseLayer.current?.setVisible(false)
            satLayer.current?.setVisible(true)
        } else if (satelliteOpacity > 0 && satelliteOpacity < 1) {
            baseLayer.current?.setVisible(true)
            satLayer.current?.setVisible(true)
        }
    }, [satelliteOpacity])

    // Satellite tiles setting
    useEffect(() => {
        satLayer.current?.setSource(
            satMapsProvider == 'google' ? gMapsSatSource.current :
                satMapsProvider == 'yandex' ? yMapsSatSource.current :
                    satMapsProvider == 'custom' ? customMapSource.current :
                        gMapsSatSource.current)
        satLayer.current?.getSource()?.refresh()
    }, [satMapsProvider])

    const submitOverlay = async () => {
        if (file && polygonExtent && rectCoords?.bl && rectCoords?.tl && rectCoords?.tr && rectCoords?.br) {
            const formData = new FormData()
            formData.append('file', file)
            formData.append('extentMinX', polygonExtent[0].toString())
            formData.append('extentMinY', polygonExtent[1].toString())
            formData.append('extentMaxX', polygonExtent[2].toString())
            formData.append('extentMaxY', polygonExtent[3].toString())
            formData.append('blX', rectCoords?.bl[0].toString())
            formData.append('blY', rectCoords?.bl[1].toString())
            formData.append('tlX', rectCoords?.tl[0].toString())
            formData.append('tlY', rectCoords?.tl[1].toString())
            formData.append('trX', rectCoords?.tr[0].toString())
            formData.append('trY', rectCoords?.tr[1].toString())
            formData.append('brX', rectCoords?.br[0].toString())
            formData.append('brY', rectCoords?.br[1].toString())

            await fetch(`${import.meta.env.VITE_API_EMS_URL}/tiles/upload`, { method: 'POST', body: formData })
        }
    }

    const mapControlsStyle: MantineStyleProp = {
        borderRadius: '4px',
        position: 'absolute',
        zIndex: '1',
        backgroundColor: colorScheme === 'light' ? '#F0F0F0CC' : '#000000CC',
        backdropFilter: 'blur(8px)',
        border: '1px solid #00000022'
    }

    const { data: nodes } = useSWR('/nodes/all', () => fetcher('/nodes/all', BASE_URL.ems), { revalidateOnFocus: false })

    useEffect(() => {
        // Draw features based on database data
        if (Array.isArray(nodes)) {
            nodes.map(node => {
                if (node.shape_type === 'LINE') {
                    const coordinates: Coordinate[] = []
                    if (Array.isArray(node.shape)) {
                        node.shape.map((point: { x: number, y: number }) => {
                            const coordinate = [point.x as number, point.y as number] as Coordinate
                            coordinates.push(coordinate)
                        })
                    }
                    //console.log(coordinates)
                    nodeLayerSource.current.addFeature(new Feature({ geometry: new LineString(coordinates) }))
                }
            })
        }
    }, [nodes])

    const [searchObject, setSearchObject] = useState<string | undefined>("")
    const throttledSearchObject = useThrottle(searchObject, 500);

    useEffect(() => {
        if (!selectedObjectType || !map.current) return;

        if (figuresLayer.current) {
            // Reset styles and apply highlight to matching features
            figuresLayer.current.getSource()?.getFeatures().forEach((feature) => {
                if (selectedObjectType == feature.get('type')) {
                    feature.setStyle(highlightStyleYellow);
                } else {
                    feature.setStyle(undefined); // Reset to default style
                }
            })
        }

        if (linesLayer.current) {
            // Reset styles and apply highlight to matching features
            linesLayer.current.getSource()?.getFeatures().forEach((feature) => {
                if (selectedObjectType == feature.get('type')) {
                    feature.setStyle(highlightStyleYellow);
                } else {
                    feature.setStyle(undefined); // Reset to default style
                }
            })
        }
    }, [selectedObjectType])

    useEffect(() => {
        if (currentObjectId) {
            if (figuresLayer.current) {
                // Reset styles and apply highlight to matching features
                figuresLayer.current.getSource()?.getFeatures().forEach((feature: Feature) => {
                    if (currentObjectId == feature.get('object_id')) {
                        feature.setStyle(highlightStyleRed);

                        const geometry = feature.getGeometry()

                        if (geometry) {
                            map.current?.getView().fit(geometry as SimpleGeometry, { duration: 500, maxZoom: 18 })
                            //map.current?.getView().animate({ center: calculateCenter(geometry as SimpleGeometry).center })
                        }

                    } else {
                        feature.setStyle(undefined); // Reset to default style
                    }
                })
            }

            if (linesLayer.current) {
                // Reset styles and apply highlight to matching features
                linesLayer.current.getSource()?.getFeatures().forEach((feature: Feature) => {
                    if (currentObjectId == feature.get('object_id')) {
                        feature.setStyle(highlightStyleRed);

                        const geometry = feature.getGeometry()
                        if (geometry) {
                            map.current?.getView().fit(geometry as SimpleGeometry, { duration: 500, maxZoom: 18 })
                        }
                    } else {
                        feature.setStyle(undefined); // Reset to default style
                    }
                })
            }
        }
    }, [currentObjectId])

    const { data: regionsData } = useSWR(
        `/general/regions/all`,
        (url) => fetcher(url, BASE_URL.ems),
        {
            revalidateOnFocus: false
        }
    )

    const { data: districtsData } = useSWR(
        selectedRegion ? `/general/districts/all?region_id=${selectedRegion}` : null,
        (url) => fetcher(url, BASE_URL.ems),
        {
            revalidateOnFocus: false
        }
    )

    const { data: searchData } = useSWR(
        throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null,
        (url) => fetcher(url, BASE_URL.ems),
        {
            revalidateOnFocus: false
        }
    )

    const { data: figuresData, isValidating: figuresValidating } = useSWR(
        selectedDistrict && selectedYear ? `/gis/figures/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null,
        (url) => axios.get(url, {
            baseURL: BASE_URL.ems
        }).then((res) => res.data),
        {
            revalidateOnFocus: false
        }
    )

    const { data: linesData, isValidating: linesValidating } = useSWR(
        !figuresValidating && selectedDistrict && selectedYear ? `/gis/lines/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null,
        (url) => axios.get(url, {
            baseURL: BASE_URL.ems
        }).then((res) => {
            return res.data
        }),
        {
            revalidateOnFocus: false
        }
    )

    useEffect(() => {
        let offset_x = 14444582.697619518
        let offset_y = 8866450.63524492
        let scale = {
            w: 100000,
            h: 100000
        }
        //let rotation = 0

        const settings = citySettings.find(el => el.city_id === selectedDistrict)

        if (settings) {
            console.log("City settings found")

            if (settings.scale) {
                scale = {
                    w: settings.scale,
                    h: settings.scale
                }
            }
            if (settings.offset_x && settings.offset_y) {
                offset_x = settings.offset_x
                offset_y = settings.offset_y
            }

            if (settings.rotation) {
                //rotation = settings.rotation
            }
        } else {
            console.log("City settings NOT found")
        }

        if (Array.isArray(figuresData)) {
            figuresLayer.current.getSource()?.clear()
            if (figuresData.length > 0) {
                const scaling = {
                    w: scale.w, // responseData[0].width
                    h: scale.h // responseData[0].width
                }

                figuresData.map((figure: IFigure) => {
                    processFigure(figure, scaling, [offset_x, offset_y], figuresLayer)
                })

                if (map.current) {
                    const extent = figuresLayer.current.getSource()?.getExtent()

                    if (extent) {
                        map.current.getView().fit(fromExtent(extent), { duration: 500 })
                    }
                }
            }
        }

        if (Array.isArray(linesData)) {
            linesLayer.current.getSource()?.clear()
            if (linesData.length > 0) {
                const scaling = {
                    w: scale.w, // responseData[0].width
                    h: scale.h // responseData[0].width
                }

                linesData.map((line: ILine) => {
                    processLine(line, scaling, [offset_x, offset_y], linesLayer)
                })
            }
        }
    }, [figuresData, linesData, selectedDistrict, selectedYear])

    useEffect(() => {
        if (selectedDistrict) {
            let offset_x = 14442665.697619518
            let offset_y = 8884520.63524492
            //let scale = 9000
            //let rotation = 0
            //let image_width = 8500
            //let image_height = 12544

            const settings = citySettings.find(el => el.city_id === selectedDistrict)

            if (settings) {
                console.log("City settings found")

                if (settings.scale) {
                    //scale = settings.scale
                }
                if (settings.offset_x && settings.offset_y) {
                    offset_x = settings.offset_x
                    offset_y = settings.offset_y
                }

                if (settings.image_width && settings.image_height) {
                    //image_width = settings.image_width
                    //image_height = settings.image_height
                }

                if (settings.rotation) {
                    //rotation = settings.rotation
                }
            } else {
                console.log("City settings NOT found")
            }

            const imageUrl = `${import.meta.env.VITE_API_EMS_URL}/static/${selectedDistrict}`;
            const img = new Image();
            img.src = imageUrl;
            img.onload = () => {
                if (map.current) {

                    const width = img.naturalWidth;
                    const height = img.naturalHeight;
                    console.log(width, height)
                    //const k = (width < height ? width / height : height / width)
                    const k = 0.40340

                    console.log(k)

                    const wk = width * k
                    const hk = height * k

                    const center = [offset_x + (wk), offset_y - (hk)];

                    const extent = [
                        center[0] - (wk),
                        center[1] - (hk),
                        center[0] + (wk),
                        center[1] + (hk),
                    ];

                    // Set up the initial image layer with the extent
                    const imageSource = new ImageStatic({
                        url: imageUrl,
                        imageExtent: extent,
                    });
                    staticMapLayer.current.setSource(imageSource);

                    //map.current.addLayer(imageLayer.current);
                }
            };
        }
    }, [selectedDistrict])

    useEffect(() => {
        // if (map.current) {
        //     map.current.on('postcompose', function () {
        //         if (colorScheme === 'dark') {
        //             document.querySelector('canvas').style.filter = 'grayscale(80%) invert(100%) hue-rotate(180deg)'
        //         } else {
        //             document.querySelector('canvas').style.filter = 'grayscale(0%) invert(0%) hue-rotate(0deg)'
        //         }
        //     })
        // }

        if (baseLayer.current) {
            baseLayer.current.on('prerender', function (e) {
                if (colorScheme === 'dark') {
                    if (e.context) {
                        const context = e.context as CanvasRenderingContext2D;
                        context.filter = 'grayscale(80%) invert(100%) hue-rotate(180deg) ';
                        context.globalCompositeOperation = 'source-over';
                    }
                } else {
                    if (e.context) {
                        const context = e.context as CanvasRenderingContext2D;
                        context.filter = 'none';
                    }
                }
            })

            baseLayer.current.on('postrender', function (e) {
                if (e.context) {
                    const context = e.context as CanvasRenderingContext2D;
                    context.filter = 'none';
                }
            })
        }
    }, [colorScheme])

    return (
        <Box w={'100%'} h='100%' pos={'relative'}>
            <Portal target='#header-portal'>
                <Flex gap={'sm'} direction={'row'}>
                    <Autocomplete
                        form='search_object'
                        placeholder="Поиск"
                        flex={'1'}
                        data={searchData ? searchData.map((item: { value: string, id_object: string }) => ({ label: item.value, value: item.id_object.toString() })) : []}
                        //onSelect={(e) => console.log(e.currentTarget.value)}
                        onChange={(value) => setSearchObject(value)}
                        onOptionSubmit={(value) => setCurrentObjectId(value)}
                        rightSection={
                            searchObject !== '' && (
                                <CloseButton
                                    size="sm"
                                    onMouseDown={(event) => event.preventDefault()}
                                    onClick={() => {
                                        setSearchObject('')
                                        //setSelectedCity(null)
                                    }}
                                    aria-label="Clear value"
                                />
                            )
                        }
                        leftSection={<IconSearch size={16} />}
                        value={searchObject}
                    />

                    <MantineSelect
                        placeholder="Регион"
                        flex={'1'}
                        data={regionsData ? regionsData.map((item: { name: string, id: number }) => ({ label: item.name, value: item.id.toString() })) : []}
                        onChange={(value) => setSelectedRegion(Number(value))}
                        clearable
                        searchable
                        value={selectedRegion ? selectedRegion.toString() : null}
                    />

                    <MantineSelect
                        placeholder="Населённый пункт"
                        flex={'1'}
                        data={districtsData ? districtsData.map((item: { name: string, id: number, district_name: string }) => ({ label: [item.name, item.district_name].join(' - '), value: item.id.toString() })) : []}
                        onChange={(value) => setSelectedDistrict(Number(value))}
                        clearable
                        searchable
                        value={selectedDistrict ? selectedDistrict.toString() : null}
                    />

                    <MantineSelect
                        w='84px'
                        data={['2018', '2019', '2020', '2021', '2022', '2023', '2024'].map(el => ({ label: el, value: el }))}
                        onChange={(e) => {
                            setSelectedYear(Number(e))
                        }}
                        defaultValue={selectedYear?.toString()}
                        allowDeselect={false}
                    />

                    <Menu
                        position="bottom-end"
                        transitionProps={{ transition: 'pop-top-right' }}
                        withinPortal
                    >
                        <Menu.Target>
                            <Button variant='transparent'>
                                <Group gap={7} wrap='nowrap' style={{ flexShrink: 0 }} title='Слои'>
                                    <IconBoxMultiple style={{ width: rem(20), height: rem(20) }} />
                                    <IconChevronDown style={{ width: rem(12), height: rem(12) }} stroke={1.5} />
                                </Group>
                            </Button>
                        </Menu.Target>
                        <Menu.Dropdown>
                            <Menu.Label>{'Настройка видимости слоёв'}</Menu.Label>

                            <Flex p='sm' direction='column' gap='xs'>
                                <Flex align='center' direction='row' gap='sm'>
                                    <Slider w='100%' min={0} max={1} step={0.001} value={satelliteOpacity} defaultValue={satelliteOpacity} onChange={(value) => setSatelliteOpacity(Array.isArray(value) ? value[0] : value)} />
                                    <MantineSelect variant='filled' value={satMapsProvider} data={[{ label: 'Google', value: 'google' }, { label: 'Яндекс', value: 'yandex' }, { label: 'Подложка', value: 'custom' }, { label: 'Static', value: 'static' }]} onChange={(value) => setSatMapsProvider(value as SatelliteMapsProvider)} />
                                </Flex>
                                <Flex direction='row'>
                                    <ActionIcon size='lg' variant='transparent' onClick={() => submitOverlay()}>
                                        <IconUpload style={{ width: rem(20), height: rem(20) }} />
                                    </ActionIcon>

                                    <ActionIcon size='lg' variant='transparent' title='Добавить подложку'>
                                        <IconPlus style={{ width: rem(20), height: rem(20) }} />
                                    </ActionIcon>
                                </Flex>
                                <MapLayers map={map} />
                            </Flex>

                        </Menu.Dropdown>
                    </Menu>

                    <ActionIcon size='lg' variant='transparent' title='Настройки ИКС'>
                        <IconSettings style={{ width: rem(20), height: rem(20) }} />
                    </ActionIcon>
                </Flex>
            </Portal>

            <LoadingOverlay visible={linesValidating || figuresValidating} />

            <Flex w={'100%'} h={'100%'} pos={'absolute'}>
                {selectedRegion && selectedDistrict &&
                    <MapToolbar
                        onSave={() => saveFeatures(drawingLayer)}
                        onRemove={() => draw.current?.removeLastPoint()}
                    />
                }

                {selectedRegion && selectedDistrict &&
                    <Flex direction='column' mah={'94%'} h={'100%'} pl='sm' style={{
                        ...mapControlsStyle,
                        maxWidth: '340px',
                        width: '100%',
                        top: '8px',
                        left: '8px',
                    }}>
                        <TabsPane defaultTab='objects' tabs={objectsPane} />
                        <Divider />
                        <TabsPane defaultTab='parameters' tabs={paramsPane} />
                    </Flex>
                }

                <MapStatusbar
                    mapControlsStyle={mapControlsStyle}
                />
            </Flex>

            <div
                id="map-container"
                ref={mapElement}
                style={{ width: '100%', height: '100%', maxHeight: '100%', position: 'fixed', flexGrow: 1 }}
            >
            </div>
        </Box >
    );
};

export default MapComponent
