import { View, Text, Map } from '@tarojs/components'
import { useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { getToken } from '@/services/auth'
import { loadCurrentChildBindingContext } from '@/services/binding'
import {
  getCurrentDeviceLocation,
  getDeviceTrajectory,
  DeviceLocation,
  DeviceTrajectoryPoint,
} from '@/services/location'
import { useSystemBanner } from '@/components/system-banner/use-system-banner'
import './index.scss'

type TrajectoryMode = 'current' | 'today' | 'recent'

const DEVICE_MARKER_ID = 1
const TRAJECTORY_MARKER_BASE_ID = 1000
const DEVICE_MARKER_ICON = require('../../assets/tab-icons/location-selected.png')
const START_MARKER_ICON = require('../../assets/tab-icons/device-icon.png')
const END_MARKER_ICON = require('../../assets/tab-icons/device-selected.png')
const POINT_MARKER_ICON = require('../../assets/tab-icons/location-icon.png')

const DEFAULT_COORDINATES = {
  latitude: 39.9042,
  longitude: 116.4074,
}

const MODE_OPTIONS: Array<{ key: TrajectoryMode; label: string }> = [
  { key: 'current', label: '当前位置' },
  { key: 'today', label: '今日轨迹' },
  { key: 'recent', label: '最近点位' },
]

function formatTime(value?: string | null): string {
  if (!value) return '--'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return value
  const month = `${date.getMonth() + 1}`.padStart(2, '0')
  const day = `${date.getDate()}`.padStart(2, '0')
  const hour = `${date.getHours()}`.padStart(2, '0')
  const minute = `${date.getMinutes()}`.padStart(2, '0')
  return `${month}-${day} ${hour}:${minute}`
}

function formatAccuracy(value?: number | null): string {
  if (value === undefined || value === null) return '未知'
  return `${value} 米`
}

function formatOptionalNumber(value?: number | null, digits = 1): string | null {
  if (value === undefined || value === null) return null
  return Number(value).toFixed(digits)
}

function getLocationAddress(point: DeviceLocation | DeviceTrajectoryPoint): string {
  const address = String(point.address || '').trim()
  if (address) return address
  return '地址解析中'
}

function buildLocationDetailLines(
  point: DeviceLocation | DeviceTrajectoryPoint,
  options?: { includeIdentity?: boolean }
): string[] {
  const lines: string[] = []

  if (options?.includeIdentity) {
    lines.push(`设备 ${point.device_id} · ${point.child_name || '未命名儿童'}`)
  }

  lines.push(`上报时间 ${formatTime(point.device_time)}`)

  if (point.server_time) {
    lines.push(`服务端时间 ${formatTime(point.server_time)}`)
  }
  if (point.coord_type) {
    lines.push(`坐标系 ${point.coord_type}`)
  }
  if (point.accuracy_m !== null && point.accuracy_m !== undefined) {
    lines.push(`定位精度 ${formatAccuracy(point.accuracy_m)}`)
  }

  const altitudeText = formatOptionalNumber(point.altitude_m)
  if (altitudeText) {
    lines.push(`海拔 ${altitudeText} 米`)
  }

  const speedText = formatOptionalNumber(point.speed_mps)
  if (speedText) {
    lines.push(`速度 ${speedText} 米/秒`)
  }

  if (point.heading_deg !== null && point.heading_deg !== undefined) {
    lines.push(`方向 ${point.heading_deg}°`)
  }
  if (point.source !== null && point.source !== undefined && point.source > 0) {
    lines.push(`定位来源 ${point.source}`)
  }
  if (point.battery_pct !== null && point.battery_pct !== undefined) {
    lines.push(`设备电量 ${point.battery_pct}%`)
  }

  return lines
}

function getTodayStartISOString(): string {
  const now = new Date()
  now.setHours(0, 0, 0, 0)
  return now.toISOString()
}

function getRecentStartISOString(hours = 24): string {
  return new Date(Date.now() - hours * 60 * 60 * 1000).toISOString()
}

function getMarkerLabel(point: DeviceTrajectoryPoint | DeviceLocation | null): string {
  if (!point) return ''
  return point.child_name || point.device_id
}

function getTrajectoryMarkerId(index: number): number {
  return TRAJECTORY_MARKER_BASE_ID + index
}

export default function Location() {
  const systemBanner = useSystemBanner()
  const [loading, setLoading] = useState(true)
  const [deviceLocation, setDeviceLocation] = useState<DeviceLocation | null>(null)
  const [trajectory, setTrajectory] = useState<DeviceTrajectoryPoint[]>([])
  const [selectedPoint, setSelectedPoint] = useState<DeviceTrajectoryPoint | null>(null)
  const [trajectoryMode, setTrajectoryMode] = useState<TrajectoryMode>('current')
  const [coordinates, setCoordinates] = useState(DEFAULT_COORDINATES)
  const [locationNotice, setLocationNotice] = useState<string | null>(null)
  const [emptyState, setEmptyState] = useState<{ title: string; desc: string; actionText: string; actionUrl: string } | null>(
    null
  )

  useDidShow(() => {
    void loadLocation(true)
  })

  const loadLocation = async (showToast = false, nextMode?: TrajectoryMode) => {
    const targetMode = nextMode || trajectoryMode

    if (!getToken()) {
      Taro.reLaunch({ url: '/pages/login/index' })
      return
    }

    if (showToast) {
      Taro.showLoading({ title: '刷新中...' })
    }

    setLoading(true)
    setEmptyState(null)
    setLocationNotice(null)
    if (nextMode) {
      setTrajectoryMode(nextMode)
      setSelectedPoint(null)
    }

    try {
      const context = await loadCurrentChildBindingContext()
      if (!context.currentChild) {
        setDeviceLocation(null)
        setTrajectory([])
        setSelectedPoint(null)
        setCoordinates(DEFAULT_COORDINATES)
        setEmptyState({
          title: '还没有当前孩子',
          desc: '请先去设置与管理页创建或选择一个孩子，再查看定位。',
          actionText: '去设置与管理',
          actionUrl: '/pages/sleep/index',
        })
        return
      }

      const resolvedDeviceId = context.currentBinding?.device_id || ''
      if (!resolvedDeviceId) {
        setDeviceLocation(null)
        setTrajectory([])
        setSelectedPoint(null)
        setCoordinates(DEFAULT_COORDINATES)
        setEmptyState({
          title: '当前孩子还没有绑定设备',
          desc: '先给当前孩子绑定一台设备，定位和轨迹页才会有内容。',
          actionText: '去绑定设备',
          actionUrl: '/pages/bind/index',
        })
        return
      }

      const currentLocation = await getCurrentDeviceLocation(resolvedDeviceId)
      setDeviceLocation(currentLocation)
      if (currentLocation?.stale || currentLocation?.realtime === false) {
        setLocationNotice('已显示最近一次定位')
      }

      const nextCoordinates = currentLocation
        ? {
            latitude: currentLocation.lat,
            longitude: currentLocation.lng,
          }
        : DEFAULT_COORDINATES

      let points: DeviceTrajectoryPoint[] = []
      if (targetMode === 'today') {
        const response = await getDeviceTrajectory({
          deviceId: resolvedDeviceId,
          startAt: getTodayStartISOString(),
          limit: 200,
        })
        points = response?.items || []
      } else if (targetMode === 'recent') {
        const response = await getDeviceTrajectory({
          deviceId: resolvedDeviceId,
          startAt: getRecentStartISOString(72),
          limit: 100,
        })
        points = response?.items || []
      }

      setTrajectory(points)
      setSelectedPoint(points.length > 0 ? points[points.length - 1] : null)

      const focusPoint = points.length > 0 ? points[points.length - 1] : currentLocation
      if (focusPoint) {
        setCoordinates({
          latitude: focusPoint.lat,
          longitude: focusPoint.lng,
        })
      } else {
        setCoordinates(nextCoordinates)
      }

      if (showToast) {
        Taro.showToast({
          title: currentLocation || points.length > 0 ? '位置已更新' : '暂无设备位置',
          icon: currentLocation || points.length > 0 ? 'success' : 'none',
        })
      }
    } catch (error: any) {
      if (showToast) {
        Taro.hideLoading()
      }
      setLoading(false)
      console.error('[location] load failed:', error)
      const message = error?.status === 408 ? '暂时无法刷新定位' : error?.message || '位置更新失败'
      Taro.showToast({
        title: message,
        icon: 'none',
      })
    } finally {
      if (showToast) {
        Taro.hideLoading()
      }
      setLoading(false)
    }
  }

  const handleMarkerTap = (event: any) => {
    const markerId = Number(event?.detail?.markerId)
    if (markerId === DEVICE_MARKER_ID && deviceLocation) {
      setCoordinates({
        latitude: deviceLocation.lat,
        longitude: deviceLocation.lng,
      })
      return
    }

    const pointIndex = markerId - TRAJECTORY_MARKER_BASE_ID
    const point = trajectory[pointIndex]
    if (!point) return

    setSelectedPoint(point)
    setCoordinates({
      latitude: point.lat,
      longitude: point.lng,
    })
  }

  const currentMarker =
    deviceLocation && trajectoryMode === 'current'
      ? [
          {
            id: DEVICE_MARKER_ID,
            latitude: deviceLocation.lat,
            longitude: deviceLocation.lng,
            title: getMarkerLabel(deviceLocation),
            iconPath: DEVICE_MARKER_ICON,
            width: 40,
            height: 40,
            callout: {
              content: `当前位置\n${formatTime(deviceLocation.device_time)}`,
              color: '#1A1A1A',
              fontSize: 13,
              anchorX: 0,
              anchorY: -4,
              borderRadius: 8,
              borderWidth: 1,
              borderColor: '#FF8C42',
              bgColor: '#FFFFFF',
              padding: 8,
              display: 'BYCLICK' as const,
              textAlign: 'center' as const,
            },
          },
        ]
      : []

  const trajectoryMarkers =
    trajectory.length > 0
      ? trajectory.map((point, index) => {
          const isFirst = index === 0
          const isLast = index === trajectory.length - 1
          const isSelected = selectedPoint?.id === point.id
          return {
            id: getTrajectoryMarkerId(index),
            latitude: point.lat,
            longitude: point.lng,
            title: `${isFirst ? '起点' : isLast ? '终点' : '轨迹点'} ${formatTime(point.device_time)}`,
            iconPath: isFirst ? START_MARKER_ICON : isLast ? END_MARKER_ICON : POINT_MARKER_ICON,
            width: isSelected ? 36 : isFirst || isLast ? 32 : 22,
            height: isSelected ? 36 : isFirst || isLast ? 32 : 22,
            zIndex: isSelected ? 20 : isFirst || isLast ? 12 : 8,
            callout: {
              content: `${isFirst ? '起点' : isLast ? '终点' : '轨迹点'}\n${formatTime(point.device_time)}`,
              color: '#1A1A1A',
              fontSize: 13,
              anchorX: 0,
              anchorY: -4,
              borderRadius: 8,
              borderWidth: 1,
              borderColor: isSelected ? '#FF8C42' : '#E6E6E6',
              bgColor: '#FFFFFF',
              padding: 8,
              display: isSelected ? ('ALWAYS' as const) : ('BYCLICK' as const),
              textAlign: 'center' as const,
            },
          }
        })
      : []

  const markers = trajectoryMode === 'current' ? currentMarker : trajectoryMarkers

  const polyline =
    trajectory.length >= 2
      ? [
          {
            points: trajectory.map((item) => ({
              latitude: item.lat,
              longitude: item.lng,
            })),
            color: '#FF8C42',
            width: 6,
            dottedLine: false,
          },
        ]
      : []

  const summaryTitle =
    trajectoryMode === 'current'
      ? '当前设备坐标'
      : trajectoryMode === 'today'
        ? '今日轨迹'
        : '最近点位'

  return (
    <View className='location-page'>
      <View className='page-header'>
        <Text className='page-title'>设备定位</Text>
      </View>

      {emptyState ? (
        <View className='location-empty-shell'>
          <View className='location-empty-card'>
            <Text className='location-empty-title'>{emptyState.title}</Text>
            <Text className='location-empty-desc'>{emptyState.desc}</Text>
            <View
              className='location-empty-action'
              onClick={() => {
                if (emptyState.actionUrl === '/pages/sleep/index') {
                  Taro.switchTab({ url: emptyState.actionUrl })
                  return
                }
                Taro.navigateTo({ url: emptyState.actionUrl })
              }}
            >
              <Text className='location-empty-action-text'>{emptyState.actionText}</Text>
            </View>
          </View>
        </View>
      ) : (
        <>
          {/* <View className='mode-switch'>
            {MODE_OPTIONS.map((item) => (
              <View
                key={item.key}
                className={`mode-chip ${trajectoryMode === item.key ? 'active' : ''}`}
                onClick={() => {
                  if (trajectoryMode === item.key) return
                  void loadLocation(false, item.key)
                }}
              >
                <Text className='mode-chip-text'>{item.label}</Text>
              </View>
            ))}
          </View> */}

          <View className='map-section'>
            <Map
              className='map'
              latitude={coordinates.latitude}
              longitude={coordinates.longitude}
              scale={15}
              markers={markers}
              polyline={polyline}
              onMarkerTap={handleMarkerTap}
              onCalloutTap={handleMarkerTap}
              onError={(event) => {
                console.error('[location] map error:', event.detail)
              }}
            />
          </View>

          <View className='location-card'>
            <View className='card-header'>
              <View className='header-left'>
                <Text className='location-title'>{summaryTitle}</Text>
                <Text className='location-update'>
                  {locationNotice
                    ? locationNotice
                    : loading
                    ? '正在获取设备位置...'
                    : trajectoryMode === 'current'
                      ? `更新于 ${formatTime(deviceLocation?.updated_at)}`
                      : `轨迹点 ${trajectory.length} 个 · 最近更新 ${formatTime(trajectory[trajectory.length - 1]?.device_time)}`}
                </Text>
              </View>
              <View className='refresh-btn' onClick={() => loadLocation(true)}>
                <Text className='refresh-icon'>↻</Text>
              </View>
            </View>

            {trajectoryMode === 'current' ? (
              deviceLocation ? (
                <View className='location-detail'>
                  <View className='location-icon'>
                    <Text>📍</Text>
                  </View>
                  <View className='location-info'>
                    <Text className='location-address'>{getLocationAddress(deviceLocation)}</Text>
                    <Text className='location-coordinate'>
                      {deviceLocation.lat.toFixed(6)}, {deviceLocation.lng.toFixed(6)}
                    </Text>
                    {buildLocationDetailLines(deviceLocation, { includeIdentity: true }).map((line, index) => (
                      <Text key={`current-${index}`} className='location-desc'>
                        {line}
                      </Text>
                    ))}
                  </View>
                </View>
              ) : (
                <View className='location-empty'>
                  <Text className='location-empty-title'>{locationNotice || '当前孩子暂无设备位置'}</Text>
                  {locationNotice && <Text className='location-empty-desc'>请确认设备已开机并保持网络可用。</Text>}
                </View>
              )
            ) : trajectory.length > 0 ? (
              <View className='location-stack'>
                {selectedPoint && (
                  <View className='location-detail selected-point-card'>
                    <View className='location-icon selected'>
                      <Text>●</Text>
                    </View>
                    <View className='location-info'>
                      <Text className='location-coordinate'>
                        {selectedPoint.lat.toFixed(6)}, {selectedPoint.lng.toFixed(6)}
                      </Text>
                      {buildLocationDetailLines(selectedPoint).map((line, index) => (
                        <Text key={`selected-${index}`} className='location-desc'>
                          {line}
                        </Text>
                      ))}
                    </View>
                  </View>
                )}

                <View className='location-detail'>
                  <View className='location-icon'>
                    <Text>🛣️</Text>
                  </View>
                  <View className='location-info'>
                    <Text className='location-coordinate'>共 {trajectory.length} 个轨迹点</Text>
                    <Text className='location-desc'>
                      起点 {formatTime(trajectory[0].device_time)} · {trajectory[0].lat.toFixed(6)}, {trajectory[0].lng.toFixed(6)}
                    </Text>
                    <Text className='location-desc'>
                      终点 {formatTime(trajectory[trajectory.length - 1].device_time)} ·{' '}
                      {trajectory[trajectory.length - 1].lat.toFixed(6)}, {trajectory[trajectory.length - 1].lng.toFixed(6)}
                    </Text>
                  </View>
                </View>
              </View>
            ) : (
              <View className='location-empty'>
                <Text className='location-empty-title'>暂无轨迹</Text>
                <Text className='location-empty-desc'>
                  {trajectoryMode === 'today' ? '当前孩子今天还没有新的历史点位。' : '当前孩子最近没有新的历史点位。'}
                </Text>
              </View>
            )}
          </View>
        </>
      )}
      {systemBanner}
    </View>
  )
}
