"use client"

import { useEffect, useMemo } from "react"
import { Layer, Source, useMap, Popup } from "react-map-gl/mapbox"
import { useState } from "react"
import { IGeoJSONPolygon } from "@/app/_utils/types/map"
import { CRIME_COLORS, CRIME_RATES } from "@/app/_utils/const/crime"

export type DistrictFeature = {
    id: string
    name: string
    cityName: string
    code: string
    polygon: IGeoJSONPolygon
    crimeRate: "low" | "medium" | "high" | "no_data"
    crimeCount: number
    year: number
}

type DistrictLayerProps = {
    data: DistrictFeature[]
    visible?: boolean
    onClick?: (feature: any) => void
}

type hoverInfoType = {
    feature: {
        properties: {
            crimeRate: "low" | "medium" | "high" | "no_data"
            name: string
            cityName: string
            crimeCount: number
        }
        geometry: {
            coordinates: number[][][]
        }
    }
    x: number
    y: number
}

export default function DistrictLayer({ data, visible = true, onClick }: DistrictLayerProps) {
    const { current: map } = useMap()
    const [hoverInfo, setHoverInfo] = useState<hoverInfoType | null>(null)

    // Convert data to GeoJSON
    const geojson = useMemo(() => {
        return {
            type: "FeatureCollection",
            features: data
                .filter((district) => district.polygon) // Only include districts with polygon data
                .map((district) => ({
                    type: "Feature",
                    properties: {
                        id: district.id,
                        name: district.name,
                        cityName: district.cityName,
                        crimeRate: district.crimeRate,
                        crimeCount: district.crimeCount,
                        color: CRIME_COLORS[district.crimeRate],
                    },
                    geometry: district.polygon,
                })),
        }
    }, [data])

    // Handle hover events
    useEffect(() => {
        if (!map) return

        const onHover = (event: any) => {
            const { features, point } = event
            const hoveredFeature = features && features[0]

            // Update hover state
            setHoverInfo(
                hoveredFeature
                    ? {
                        feature: hoveredFeature,
                        x: point.x,
                        y: point.y,
                    }
                    : null,
            )
        }

        // Change cursor on hover
        const onMouseEnter = () => {
            if (map) map.getCanvas().style.cursor = "pointer"
        }

        const onMouseLeave = () => {
            if (map) map.getCanvas().style.cursor = ""
            setHoverInfo(null)
        }

        // Add event listeners
        map.on("mousemove", "district-fills", onHover)
        map.on("mouseenter", "district-fills", onMouseEnter)
        map.on("mouseleave", "district-fills", onMouseLeave)
        map.on("click", "district-fills", (e) => {
            if (onClick && e.features && e.features[0]) {
                onClick(e.features[0])
            }
        })

        // Clean up
        return () => {
            map.off("mousemove", "district-fills", onHover)
            map.off("mouseenter", "district-fills", onMouseEnter)
            map.off("mouseleave", "district-fills", onMouseLeave)
            map.off("click", "district-fills", onClick as any)
        }
    }, [map, onClick])

    if (!visible) return null

    return (
        <>
            <Source id="districts" type="geojson" data={geojson as any}>
                <Layer
                    id="district-fills"
                    type="fill"
                    paint={{
                        "fill-color": ["get", "color"],
                        "fill-opacity": 0.6,
                    }}
                />
                <Layer
                    id="district-borders"
                    type="line"
                    paint={{
                        "line-color": "#627D98",
                        "line-width": 1,
                    }}
                />
            </Source>

            {/* Popup on hover */}
            {hoverInfo && (
                <Popup
                    longitude={hoverInfo.feature.geometry.coordinates[0][0][0]}
                    latitude={hoverInfo.feature.geometry.coordinates[0][0][1]}
                    closeButton={false}
                    closeOnClick={false}
                    anchor="bottom"
                    offset={[0, -10]}
                >
                    <div className="p-2">
                        <h3 className="font-bold">{hoverInfo.feature.properties.name}</h3>
                        <p>City: {hoverInfo.feature.properties.cityName}</p>
                        <p>Crime Rate: {CRIME_RATES[hoverInfo.feature.properties.crimeRate]}</p>
                        <p>Crime Count: {hoverInfo.feature.properties.crimeCount}</p>
                    </div>
                </Popup>
            )}
        </>
    )
}
