"use client"

import { BASE_BEARING, BASE_DURATION, BASE_PITCH, BASE_ZOOM } from "@/app/_utils/const/map"
import { createFillColorExpression, getFillOpacity, processDistrictFeature } from "@/app/_utils/map/common"
import type { IDistrictLayerProps } from "@/app/_utils/types/map"
import { useEffect } from "react"

export default function DistrictFillLineLayer({
    visible = true,
    map,
    onClick,
    onDistrictClick,
    year,
    month,
    filterCategory = "all",
    crimes = [],
    tilesetId,
    focusedDistrictId,
    setFocusedDistrictId,
    crimeDataByDistrict,
    showFill = true,
    activeControl,
}: IDistrictLayerProps & { onDistrictClick?: (district: any) => void }) {
    useEffect(() => {
        if (!map || !visible) return

        const handleDistrictClick = (e: any) => {
            const possibleLayers = [
                "unclustered-point",
                "clusters",
                "crime-points",
                "units-points",
                "incidents-points",
                "timeline-markers",
                "recent-incidents",
            ]
            const availableLayers = possibleLayers.filter(layer => map.getLayer(layer))
            const incidentFeatures = map.queryRenderedFeatures(e.point, {
                layers: availableLayers,
            })

            if (incidentFeatures && incidentFeatures.length > 0) {
                return
            }

            if (!map || !e.features || e.features.length === 0) return

            const feature = e.features[0]
            const districtId = feature.properties.kode_kec

            if (focusedDistrictId === districtId) {
                if (setFocusedDistrictId) {
                    setFocusedDistrictId(null)
                }

                map.easeTo({
                    zoom: BASE_ZOOM,
                    pitch: BASE_PITCH,
                    bearing: BASE_BEARING,
                    duration: BASE_DURATION,
                    easing: (t) => t * (2 - t),
                })

                const fillColorExpression = createFillColorExpression(null, crimeDataByDistrict)
                map.setPaintProperty("district-fill", "fill-color", fillColorExpression as any)

                if (map.getLayer("clusters")) {
                    map.setLayoutProperty("clusters", "visibility", "visible")
                }
                if (map.getLayer("unclustered-point")) {
                    map.setLayoutProperty("unclustered-point", "visibility", "visible")
                }

                return
            } else if (focusedDistrictId) {
                if (setFocusedDistrictId) {
                    setFocusedDistrictId(null)
                }

                return
            }

            const district = processDistrictFeature(feature, e, districtId, crimeDataByDistrict, crimes, year, month)

            if (!district) return

            const focusedFillColorExpression = createFillColorExpression(district.id, crimeDataByDistrict)
            map.setPaintProperty("district-fill", "fill-color", focusedFillColorExpression as any)

            if (setFocusedDistrictId) {
                setFocusedDistrictId(district.id)
            }

            if (map.getLayer("clusters")) {
                map.setLayoutProperty("clusters", "visibility", "none")
            }
            if (map.getLayer("unclustered-point")) {
                map.setLayoutProperty("unclustered-point", "visibility", "none")
            }

            if (onDistrictClick) {
                onDistrictClick(district)
            } else if (onClick) {
                onClick(district)
            }
        }

        const onStyleLoad = () => {
            if (!map) return

            try {
                if (!map.getSource("districts")) {
                    const layers = map.getStyle().layers
                    let firstSymbolId: string | undefined
                    for (const layer of layers) {
                        if (layer.type === "symbol") {
                            firstSymbolId = layer.id
                            break
                        }
                    }

                    map.addSource("districts", {
                        type: "vector",
                        url: `mapbox://${tilesetId}`,
                    })

                    let fillColorExpression = createFillColorExpression(focusedDistrictId, crimeDataByDistrict)
                    if (
                        Array.isArray(fillColorExpression) &&
                        fillColorExpression[0] === "match" &&
                        fillColorExpression.length < 4
                    ) {
                        fillColorExpression = [
                            "match",
                            ["get", "kode_kec"],
                            "",
                            "#90a4ae",
                            "#90a4ae"
                        ]
                    }

                    const fillOpacity = getFillOpacity(activeControl, showFill)

                    if (!map.getLayer("district-fill")) {
                        map.addLayer(
                            {
                                id: "district-fill",
                                type: "fill",
                                source: "districts",
                                "source-layer": "Districts",
                                paint: {
                                    "fill-color": fillColorExpression as any,
                                    "fill-opacity": fillOpacity,
                                },
                            },
                            firstSymbolId,
                        )
                    }

                    if (!map.getLayer("district-line")) {
                        map.addLayer(
                            {
                                id: "district-line",
                                type: "line",
                                source: "districts",
                                "source-layer": "Districts",
                                paint: {
                                    "line-color": "#ffffff",
                                    "line-width": 1,
                                    "line-opacity": 0.5,
                                },
                            },
                            firstSymbolId,
                        )
                    }

                    map.on("mouseenter", "district-fill", () => {
                        map.getCanvas().style.cursor = "pointer"
                    })

                    map.on("mouseleave", "district-fill", () => {
                        map.getCanvas().style.cursor = ""
                    })

                    map.off("click", "district-fill", handleDistrictClick)
                    map.on("click", "district-fill", handleDistrictClick)
                } else {
                    if (map.getLayer("district-fill")) {
                        let fillColorExpression = createFillColorExpression(focusedDistrictId, crimeDataByDistrict)
                        if (
                            Array.isArray(fillColorExpression) &&
                            fillColorExpression[0] === "match" &&
                            fillColorExpression.length < 4
                        ) {
                            fillColorExpression = [
                                "match",
                                ["get", "kode_kec"],
                                "",
                                "#90a4ae",
                                "#90a4ae"
                            ]
                        }
                        map.setPaintProperty("district-fill", "fill-color", fillColorExpression as any)

                        const fillOpacity = getFillOpacity(activeControl, showFill)
                        map.setPaintProperty("district-fill", "fill-opacity", fillOpacity)
                    }
                }
            } catch (error) {
                console.error("Error adding district layers:", error)
            }
        }

        if (map.isStyleLoaded()) {
            onStyleLoad()
        } else {
            map.once("style.load", onStyleLoad)
        }

        return () => {
            if (map) {
                map.off("click", "district-fill", handleDistrictClick)
            }
        }
    }, [
        map,
        visible,
        tilesetId,
        crimes,
        filterCategory,
        year,
        month,
        focusedDistrictId,
        crimeDataByDistrict,
        onClick,
        onDistrictClick,
        setFocusedDistrictId,
        showFill,
        activeControl,
    ])

    useEffect(() => {
        if (!map || !map.getLayer("district-fill")) return

        try {
            let fillColorExpression = createFillColorExpression(focusedDistrictId, crimeDataByDistrict)
            if (
                Array.isArray(fillColorExpression) &&
                fillColorExpression[0] === "match" &&
                fillColorExpression.length < 4
            ) {
                fillColorExpression = [
                    "match",
                    ["get", "kode_kec"],
                    "",
                    "#90a4ae",
                    "#90a4ae"
                ]
            }
            map.setPaintProperty("district-fill", "fill-color", fillColorExpression as any)

            const fillOpacity = getFillOpacity(activeControl, showFill)
            map.setPaintProperty("district-fill", "fill-opacity", fillOpacity)
        } catch (error) {
            console.error("Error updating district fill colors or opacity:", error)
        }
    }, [map, focusedDistrictId, crimeDataByDistrict, activeControl, showFill])

    return null
}

