import { useMemo } from 'react'
import { Map } from '@tarojs/components'
import type { GeoPoint, NearbyPet } from '@/types/domain'
import './index.scss'

// ─── Personalized (cute) map skin ───────────────────────────────────────────
// To use a soft / cute map style instead of the default Tencent skin:
//   1. Go to https://lbs.qq.com → 「个性化地图」, design a style (e.g. pastel
//      purple/pink to match the app) and publish it to get a styleId.
//   2. Create / bind a map key (subkey) that has that style enabled.
//   3. Fill the two constants below. Leaving MAP_SUBKEY empty keeps the
//      default skin, so the map still works with no extra setup.
const MAP_SUBKEY = '' // e.g. 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
const MAP_LAYER_STYLE = 1 // the published personalized style number
// ─────────────────────────────────────────────────────────────────────────────

interface NearbyMapProps {
  pets: NearbyPet[]
  center: GeoPoint
  scale: number
  activeId?: string
  onSelect: (id: string) => void
  onRegionChange?: (causedBy: string) => void
}

export const NEARBY_MAP_ID = 'nearbyMap'

const ACTIVE_BG = '#d8b4ff'
const ACTIVE_FG = '#2a1d4a'
const NORMAL_BG = 'rgba(31,23,66,0.92)'
const NORMAL_FG = '#ffffff'

export function NearbyMap({ pets, center, scale, activeId, onSelect, onRegionChange }: NearbyMapProps) {
  // Marker id is the pet's index so onMarkerTap can resolve it directly.
  const markers = pets
    .map((pet, index) => ({ pet, index }))
    .filter(({ pet }) => typeof pet.latitude === 'number' && typeof pet.longitude === 'number')
    .map(({ pet, index }) => {
      const isActive = pet._id === activeId
      return {
        id: index,
        latitude: pet.latitude as number,
        longitude: pet.longitude as number,
        width: isActive ? 32 : 24,
        height: isActive ? 32 : 24,
        callout: {
          content: pet.name,
          color: isActive ? ACTIVE_FG : NORMAL_FG,
          bgColor: isActive ? ACTIVE_BG : NORMAL_BG,
          fontSize: 12,
          padding: 6,
          borderRadius: 10,
          display: 'ALWAYS' as const
        }
      }
    })

  const onMarkerTap = (e: any) => {
    const pet = pets[e.detail.markerId]
    if (pet) onSelect(pet._id)
  }

  // include-points must NEVER be empty: the Tencent (gljs) map runs fitBounds on
  // it and crashes ("Cannot read property 'lat' of undefined") on an empty set.
  // With real location data the pet list can be empty, so fall back to a small
  // box around the centre. Memoised so manual zoom isn't refit between loads.
  const includePoints = useMemo(() => {
    const pts = pets
      .filter(p => typeof p.latitude === 'number' && typeof p.longitude === 'number')
      .map(p => ({ latitude: p.latitude as number, longitude: p.longitude as number }))
    if (pts.length) {
      // Keep "me" in view and guarantee ≥2 points so a lone pet doesn't max-zoom.
      return [{ latitude: center.latitude, longitude: center.longitude }, ...pts]
    }
    const d = 0.02 // ≈ 2km — an empty map still frames the neighbourhood.
    return [
      { latitude: center.latitude - d, longitude: center.longitude - d },
      { latitude: center.latitude + d, longitude: center.longitude + d }
    ]
  }, [pets, center.latitude, center.longitude])

  return (
    <Map
      id={NEARBY_MAP_ID}
      className='nearby-map'
      latitude={center.latitude}
      longitude={center.longitude}
      scale={scale}
      showLocation
      enableZoom
      enableScroll
      enableRotate={false}
      subkey={MAP_SUBKEY || undefined}
      layerStyle={MAP_SUBKEY ? MAP_LAYER_STYLE : undefined}
      markers={markers as any}
      includePoints={includePoints as any}
      onMarkerTap={onMarkerTap}
      onRegionChange={(e: any) => {
        if (e?.type === 'end') onRegionChange?.(e.causedBy || '')
      }}
      onError={() => undefined}
    />
  )
}

export default NearbyMap
