import { View, Text, Slider, Image } from '@tarojs/components'
import { useRef, useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { getToken } from '@/services/auth'
import { DEVICE_UNAVAILABLE_MESSAGE } from '@/services/api'
import { Binding, loadCurrentChildBindingContext } from '@/services/binding'
import { Child } from '@/services/child'
import { DeviceAlarmItem, DeviceStatus, getDeviceAlarms, getDeviceStatus, getDeviceVolumeCommandStatus, setDeviceRemoteSleepWake, setDeviceVolume } from '@/services/device'
import { useSystemBanner } from '@/components/system-banner/use-system-banner'
import './index.scss'

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 formatCoordinates(status: DeviceStatus | null): string {
  if (!status || status.lat === null || status.lat === undefined || status.lng === null || status.lng === undefined) {
    return '--'
  }
  return `${status.lat.toFixed(6)}, ${status.lng.toFixed(6)}`
}

function getSignalLabel(value?: number | null): string {
  if (value === null || value === undefined) return '--'
  const normalized = Number(value)
  if (!Number.isFinite(normalized)) return '--'
  if (normalized <= 4) {
    if (normalized >= 3) return '强'
    if (normalized >= 2) return '中'
    return '弱'
  }
  if (normalized >= 67) return '强'
  if (normalized >= 34) return '中'
  return '弱'
}

function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

function formatBatteryDisplay(value?: number | null): { text: string; showPercent: boolean } {
  if (value === null || value === undefined) return { text: '--', showPercent: false }
  const normalized = Number(value)
  if (!Number.isFinite(normalized)) return { text: '--', showPercent: false }
  if (normalized === 0) return { text: '*', showPercent: false }
  return { text: String(normalized), showPercent: true }
}

function formatSleepRange(status: DeviceStatus | null): string {
  const start = status?.disable_time_start?.trim()
  const end = status?.disable_time_end?.trim()
  if (!start || !end) return '未设置'
  return `${start}-${end}`
}

function goLoginWithRedirect(url = '/pages/device/index') {
  Taro.setStorageSync('postLoginRedirect', url)
  Taro.navigateTo({ url: '/pages/login/index' })
}

function formatAlarmTime(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')
  const second = `${date.getSeconds()}`.padStart(2, '0')
  return `${month}-${day} ${hour}:${minute}:${second}`
}

function getAlarmTypeLabel(value?: string | null): string {
  const normalized = String(value || '').trim()
  if (!normalized) return '--'
  if (normalized === '010') return '紧急告警'
  return normalized
}

function getAlarmChildLabel(alarm: DeviceAlarmItem | null, fallbackChildName?: string | null): string {
  const alarmChildName = String(alarm?.child_name || '').trim()
  if (alarmChildName) return alarmChildName

  const fallbackName = String(fallbackChildName || '').trim()
  if (fallbackName) return fallbackName

  if (alarm?.child_id) return `儿童 ${alarm.child_id}`
  return '未关联儿童'
}

function formatAlarmCoordinates(alarm: DeviceAlarmItem | null): string {
  if (!alarm || alarm.lat === null || alarm.lat === undefined || alarm.lng === null || alarm.lng === undefined) {
    return ''
  }
  return `${Number(alarm.lat).toFixed(6)}, ${Number(alarm.lng).toFixed(6)}`
}

function getAlarmLocationLabel(alarm: DeviceAlarmItem | null): string {
  const address = String(alarm?.address || '').trim()
  if (address) return address

  const coordinates = formatAlarmCoordinates(alarm)
  if (coordinates) return coordinates

  return '暂无告警位置'
}

function getAlarmLocationHint(alarm: DeviceAlarmItem | null): string {
  if (!alarm?.location_updated_at) return '设备还没有可关联的位置上报'
  const prefix = `位置更新于 ${formatAlarmTime(alarm.location_updated_at)}`
  if (alarm.location_stale) return `${prefix}，可能不是告警发生时的位置`
  if (!String(alarm.address || '').trim() && alarm.address_resolve_status === 0) return `${prefix}，地址解析中`
  if (!String(alarm.address || '').trim() && alarm.address_resolve_status === 2) return `${prefix}，地址解析失败`
  return prefix
}

export default function Device() {
  const systemBanner = useSystemBanner()
  const [binding, setBinding] = useState<Binding | null>(null)
  const [child, setChild] = useState<Child | null>(null)
  const [deviceStatus, setDeviceStatus] = useState<DeviceStatus | null>(null)
  const [deviceAlarms, setDeviceAlarms] = useState<DeviceAlarmItem[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [isDetailExpanded, setIsDetailExpanded] = useState(false)
  const [isSavingVolume, setIsSavingVolume] = useState(false)
  const [sleepWakePending, setSleepWakePending] = useState<'on' | 'off' | null>(null)
  const [volumeValue, setVolumeValue] = useState(0)
  const [isGuest, setIsGuest] = useState(false)
  const volumeCommandInFlightRef = useRef(false)

  useDidShow(() => {
    void loadDeviceInfo()
  })

  const loadDeviceInfo = async () => {
    if (!getToken()) {
      setBinding(null)
      setChild(null)
      setDeviceStatus(null)
      setDeviceAlarms([])
      setVolumeValue(0)
      setIsGuest(true)
      setIsLoading(false)
      return
    }

    setIsLoading(true)
    setIsGuest(false)
    try {
      const context = await loadCurrentChildBindingContext()
      setChild(context.currentChild)
      setBinding(context.currentBinding)

      if (context.currentBinding?.device_id) {
        const [nextStatus, nextAlarms] = await Promise.all([
          getDeviceStatus(context.currentBinding.device_id),
          getDeviceAlarms(context.currentBinding.device_id, 20),
        ])
        setDeviceStatus(nextStatus)
        setDeviceAlarms(nextAlarms.items || [])
        setVolumeValue(nextStatus?.volume ?? 0)
      } else {
        setDeviceStatus(null)
        setDeviceAlarms([])
        setVolumeValue(0)
      }
    } catch (error: any) {
      console.error('[device] load failed:', error)
      Taro.showToast({
        title: error?.message || '加载失败，请稍后重试',
        icon: 'none',
      })
    } finally {
      setIsLoading(false)
    }
  }

  const handleOpenSleepSchedule = () => {
    Taro.navigateTo({ url: '/pages/sleep-schedule/index' })
  }

  const handleToggleDetail = () => {
    setIsDetailExpanded((current) => !current)
  }

  const handleVolumeChanging = (e: any) => {
    if (volumeCommandInFlightRef.current) return
    setVolumeValue(Number(e.detail?.value || 0))
  }

  const handleVolumeCommit = async (e: any) => {
    if (!binding?.device_id) return
    if (volumeCommandInFlightRef.current) return
    const nextLevel = Number(e.detail?.value || 0)
    const fallbackLevel = deviceStatus?.volume ?? volumeValue ?? 0
    volumeCommandInFlightRef.current = true
    setVolumeValue(nextLevel)
    setIsSavingVolume(true)

    try {
      const command = await setDeviceVolume(nextLevel, binding.device_id)
      let completedLevel: number | null = null
      let failedMessage = ''
      for (let attempt = 0; attempt < 13; attempt += 1) {
        await sleep(800)
        const status = await getDeviceVolumeCommandStatus(binding.device_id, command.time)
        if (status.status === 'completed') {
          completedLevel = status.current_level ?? nextLevel
          break
        }
        if (status.status === 'failed' || status.status === 'timeout') {
          failedMessage = status.error || (status.status === 'timeout' ? '设备未确认音量调整，请稍后查看设备状态' : '设备音量调整失败')
          break
        }
      }
      if (completedLevel === null) {
        throw new Error(failedMessage || '设备未确认音量调整，请稍后查看设备状态')
      }
      setVolumeValue(completedLevel)
      setDeviceStatus((current) => (current ? { ...current, volume: completedLevel } : current))
      Taro.showToast({
        title: '音量已成功调整',
        icon: 'success',
      })
    } catch (error: any) {
      setVolumeValue(deviceStatus?.volume ?? fallbackLevel)
      const message = error?.message === DEVICE_UNAVAILABLE_MESSAGE
        ? '设备不在线或处于休眠中，暂时无法调节音量'
        : error?.message || '音量设置失败'
      Taro.showToast({
        title: message,
        icon: 'none',
      })
    } finally {
      volumeCommandInFlightRef.current = false
      setIsSavingVolume(false)
    }
  }

  const handleRemoteSleepWake = async (switchValue: 'on' | 'off') => {
    if (!binding?.device_id || sleepWakePending) return

    setSleepWakePending(switchValue)
    try {
      await setDeviceRemoteSleepWake(switchValue, binding.device_id)
      Taro.showToast({
        title: switchValue === 'off' ? '休眠指令已发送' : '唤醒指令已发送',
        icon: 'success',
      })
    } catch (error: any) {
      Taro.showToast({
        title: error?.message || '操作失败，请重试',
        icon: 'none',
      })
    } finally {
      setSleepWakePending(null)
    }
  }

  if (isLoading) {
    return (
      <View className='device-page'>
        <View className='loading'>
          <Text>加载中...</Text>
        </View>
        {systemBanner}
      </View>
    )
  }

  if (isGuest) {
    return (
      <View className='device-page'>
        <View className='guest-hero'>
          <View className='guest-device-icon'>
            <Image className='robot-img' src={require('../../assets/tab-icons/robot.png')} mode='aspectFit' />
          </View>
          <Text className='guest-title'>伴伴儿童陪伴设备</Text>
          <Text className='guest-subtitle'>查看设备状态、定位轨迹、亲子消息和休眠管理。浏览功能后，可在需要绑定设备时登录。</Text>
        </View>

        <View className='guest-feature-grid'>
          <View className='guest-feature-card'>
            <Image className='guest-feature-icon' src={require('../../assets/tab-icons/device-icon.png')} mode='aspectFit' />
            <Text className='guest-feature-title'>设备状态</Text>
            <Text className='guest-feature-desc'>查看电量、信号、版本和告警记录。</Text>
          </View>
          <View className='guest-feature-card'>
            <Image className='guest-feature-icon' src={require('../../assets/tab-icons/location-icon.png')} mode='aspectFit' />
            <Text className='guest-feature-title'>定位展示</Text>
            <Text className='guest-feature-desc'>绑定后可查看设备当前位置。</Text>
          </View>
          <View className='guest-feature-card'>
            <Image className='guest-feature-icon' src={require('../../assets/tab-icons/chat-icon.png')} mode='aspectFit' />
            <Text className='guest-feature-title'>亲子互动</Text>
            <Text className='guest-feature-desc'>查看孩子和设备的消息会话。</Text>
          </View>
          <View className='guest-feature-card'>
            <Image className='guest-feature-icon' src={require('../../assets/tab-icons/manage-icon.png')} mode='aspectFit' />
            <Text className='guest-feature-title'>设备管理</Text>
            <Text className='guest-feature-desc'>管理孩子资料、绑定设备和休眠设置。</Text>
          </View>
        </View>

        <View className='guest-action-card'>
          <Text className='guest-action-title'>准备绑定或管理设备</Text>
          <Text className='guest-action-desc'>登录后可绑定设备，并在绑定流程中创建或选择孩子资料。</Text>
          <View className='guest-primary-btn' onClick={() => goLoginWithRedirect('/pages/device/index')}>
            <Text className='guest-primary-btn-text'>登录后继续</Text>
          </View>
        </View>
        {systemBanner}
      </View>
    )
  }

  if (!child) {
    return (
      <View className='device-page'>
        <View className='page-header'>
          <Text className='page-title'>设备首页</Text>
        </View>

        <View className='empty-card'>
          <View className='empty-robot'>
            <Image className='robot-img' src={require('../../assets/tab-icons/robot.png')} mode='aspectFit' />
          </View>
          <Text className='empty-title'>先绑定一台伴伴设备</Text>
          <Text className='empty-subtitle'>绑定时可以选择已有孩子，或直接新建孩子昵称</Text>
          <View className='empty-btn' onClick={() => Taro.navigateTo({ url: '/pages/bind/index' })}>
            <Text className='empty-btn-text'>添加设备</Text>
          </View>
        </View>
        {systemBanner}
      </View>
    )
  }

  if (!binding) {
    return (
      <View className='device-page'>
        <View className='page-header'>
          <Text className='page-title'>{child.child_name} 的伴伴</Text>
        </View>

        <View className='child-focus-card'>
          <View className='child-focus-avatar'>
            <Text className='child-focus-icon'>🧒</Text>
          </View>
          <View className='child-focus-info'>
            <Text className='child-focus-name'>{child.child_name}</Text>
            <Text className='child-focus-desc'>当前孩子已选中，还没有绑定设备</Text>
          </View>
        </View>

        <View className='empty-card'>
          <View className='empty-robot'>
            <Image className='robot-img' src={require('../../assets/tab-icons/robot.png')} mode='aspectFit' />
          </View>
          <Text className='empty-title'>给当前孩子绑定一台设备</Text>
          <Text className='empty-subtitle'>绑定后，这个孩子的聊天记录、定位和设备状态都会显示在首页</Text>
          <View className='empty-btn' onClick={() => Taro.navigateTo({ url: '/pages/bind/index' })}>
            <Text className='empty-btn-text'>去绑定设备</Text>
          </View>
        </View>
        {systemBanner}
      </View>
    )
  }

  const childName = child.child_name || '未设置'
  const pageTitle = `${childName} 的伴伴`
  const batteryValue = deviceStatus?.power ?? deviceStatus?.battery_pct ?? null
  const batteryDisplay = formatBatteryDisplay(batteryValue)
  const signalLabel = getSignalLabel(deviceStatus?.signal)
  const versionLabel = deviceStatus?.version || '--'
  const coordinateLabel = formatCoordinates(deviceStatus)
  const volumeLabel = `${volumeValue}%`
  const sleepRangeLabel = formatSleepRange(deviceStatus)
  const latestAlarm = deviceAlarms[0] || null
  const historyAlarms = latestAlarm ? deviceAlarms.slice(1) : []
  const latestAlarmChildName = getAlarmChildLabel(latestAlarm, childName)

  return (
    <View className='device-page'>
      <View className='page-header'>
        <Text className='page-title'>{pageTitle}</Text>
      </View>

      <View className='status-card'>
        <View className='status-badge'>
          <View className='status-dot'></View>
          <Text className='status-text'>已完成绑定</Text>
        </View>
        <View className='battery-section'>
          <Text className='battery-percent'>
            {batteryDisplay.text}
            {batteryDisplay.showPercent && <Text className='percent'>%</Text>}
          </Text>
          <Text className='battery-label'>当前电量</Text>
        </View>
        <View className='status-meta'>
          <View className='status-pill'>
            <Text className='status-pill-label'>信号</Text>
            <Text className='status-pill-value'>{signalLabel}</Text>
          </View>
          <View className='status-pill'>
            <Text className='status-pill-label'>版本</Text>
            <Text className='status-pill-value'>{versionLabel}</Text>
          </View>
        </View>
        <View className='device-avatar'>
          <View className='robot-icon'>
            <Image className='robot-img' src={require('../../assets/tab-icons/robot.png')} mode='aspectFit' />
          </View>
        </View>
      </View>

      <View className='section-title'>设备控制</View>
      <View className='control-card'>
        <View className='control-item sleep-item' onClick={handleOpenSleepSchedule}>
          <View className='control-left'>
            <View className='icon-bg purple'>
              <Image className='control-icon-img' src={require('../../assets/tab-icons/moon.png')} mode='aspectFit' />
            </View>
            <View className='control-info'>
              <Text className='control-name'>定时休眠</Text>
              <Text className='control-detail'>{sleepRangeLabel}</Text>
            </View>
          </View>
          <Text className='control-link'>设置</Text>
        </View>

        <View className='divider'></View>

        <View className='control-item quick-sleep-item'>
          <View className='quick-sleep-header'>
            <View className='control-left'>
              <View className='icon-bg purple'>
                <Image className='control-icon-img' src={require('../../assets/tab-icons/moon.png')} mode='aspectFit' />
              </View>
              <View className='control-info'>
                <Text className='control-name'>立即休眠/唤醒</Text>
                <Text className='control-detail'>
                  {sleepWakePending === 'off'
                    ? '正在发送休眠指令...'
                    : sleepWakePending === 'on'
                      ? '正在发送唤醒指令...'
                      : '立即控制当前设备'}
                </Text>
              </View>
            </View>
          </View>
          <View className='quick-sleep-actions'>
            <View
              className={`quick-sleep-btn sleep ${sleepWakePending ? 'disabled' : ''}`}
              onClick={sleepWakePending ? undefined : () => handleRemoteSleepWake('off')}
            >
              <Text className='quick-sleep-btn-text'>立即休眠</Text>
            </View>
            <View
              className={`quick-sleep-btn wake ${sleepWakePending ? 'disabled' : ''}`}
              onClick={sleepWakePending ? undefined : () => handleRemoteSleepWake('on')}
            >
              <Text className='quick-sleep-btn-text'>立即唤醒</Text>
            </View>
          </View>
        </View>

        <View className='divider'></View>

        <View className='control-item volume-item'>
          <View className='volume-header'>
            <View className='control-left'>
              <View className='icon-bg orange'>
                <Image
                  className='control-icon-img'
                  src={require('../../assets/tab-icons/orange-speaker.png')}
                  mode='aspectFit'
                />
              </View>
              <View className='control-info'>
                <Text className='control-name'>外放音量</Text>
                <Text className='control-detail'>{isSavingVolume ? '调整中...' : `当前 ${volumeLabel}`}</Text>
              </View>
            </View>
          </View>
          <View className='volume-slider'>
            <Image
              className='volume-icon'
              src={require('../../assets/tab-icons/unspeaker.png')}
              mode='aspectFit'
            />
            <Slider
              className='slider'
              min={0}
              max={100}
              value={volumeValue}
              disabled={isSavingVolume}
              onChanging={handleVolumeChanging}
              onChange={handleVolumeCommit}
              activeColor='#FF8C42'
              backgroundColor='#E5E5E5'
              blockColor='#FF8C42'
            />
            <Image
              className='volume-icon'
              src={require('../../assets/tab-icons/orange-speaker.png')}
              mode='aspectFit'
            />
          </View>
        </View>
      </View>

      <View className='alarm-card'>
        <View className='alarm-header'>
          <Text className='alarm-title'>最近告警</Text>
          <Text className='alarm-subtitle'>
            {latestAlarm ? '已收到设备主动上报的告警，可继续查看以往记录' : '暂时没有收到新的设备告警'}
          </Text>
        </View>

        {latestAlarm ? (
          <View>
            <View className='alarm-body'>
              <View className='alarm-row'>
                <Text className='alarm-label'>告警时间</Text>
                <Text className='alarm-value'>{formatAlarmTime(latestAlarm.created_at)}</Text>
              </View>
              <View className='alarm-row'>
                <Text className='alarm-label'>来源儿童</Text>
                <Text className='alarm-value'>{latestAlarmChildName}</Text>
              </View>
              <View className='alarm-row'>
                <Text className='alarm-label'>来源设备</Text>
                <Text className='alarm-value'>{latestAlarm.device_id}</Text>
              </View>
              <View className='alarm-row'>
                <Text className='alarm-label'>上报类型</Text>
                <Text className='alarm-value'>{getAlarmTypeLabel(latestAlarm.source_msg_id)}</Text>
              </View>
              <View className='alarm-row alarm-row-vertical'>
                <Text className='alarm-label'>告警位置</Text>
                <View className='alarm-location-value'>
                  <Text className='alarm-location-main'>{getAlarmLocationLabel(latestAlarm)}</Text>
                  <Text className='alarm-location-hint'>{getAlarmLocationHint(latestAlarm)}</Text>
                </View>
              </View>
            </View>

            <View className='alarm-history'>
              <View className='alarm-history-header'>
                <Text className='alarm-history-title'>以往告警</Text>
                <Text className='alarm-history-count'>最近 {historyAlarms.length} 条</Text>
              </View>

              {historyAlarms.length > 0 ? (
                historyAlarms.map((alarm) => (
                  <View className='alarm-history-item' key={alarm.alarm_id}>
                    <View className='alarm-history-main'>
                      <Text className='alarm-history-time'>{formatAlarmTime(alarm.created_at)}</Text>
                      <Text className='alarm-history-type'>{getAlarmTypeLabel(alarm.source_msg_id)}</Text>
                    </View>
                    <View className='alarm-history-meta'>
                      <Text className='alarm-history-child'>
                        来源儿童：{getAlarmChildLabel(alarm, childName)}
                      </Text>
                      <Text className='alarm-history-device'>{alarm.device_id}</Text>
                    </View>
                    <Text className='alarm-history-location'>{getAlarmLocationLabel(alarm)}</Text>
                    {alarm.location_stale ? (
                      <Text className='alarm-history-location-hint'>位置可能不是告警发生时的位置</Text>
                    ) : null}
                  </View>
                ))
              ) : (
                <View className='alarm-history-empty'>
                  <Text className='alarm-history-empty-text'>还没有更早的告警记录。</Text>
                </View>
              )}
            </View>
          </View>
        ) : (
          <View className='alarm-empty'>
            <Text className='alarm-empty-text'>设备触发长按告警后，会在这里显示最近一条记录。</Text>
          </View>
        )}
      </View>

      <View className='fold-card'>
        <View className='fold-header' onClick={handleToggleDetail}>
          <View className='fold-heading'>
            <Text className='fold-title'>设备详情</Text>
            <Text className='fold-subtitle'>{binding.device_id}</Text>
          </View>
          <Text className='fold-action'>{isDetailExpanded ? '收起' : '展开'}</Text>
        </View>

        {isDetailExpanded && (
          <View className='detail-body'>
            <View className='detail-row'>
              <Text className='detail-label'>当前儿童</Text>
              <Text className='detail-value'>{childName}</Text>
            </View>
            <View className='detail-row'>
              <Text className='detail-label'>当前设备</Text>
              <Text className='detail-value'>{binding.device_id}</Text>
            </View>
            <View className='detail-row'>
              <Text className='detail-label'>绑定时间</Text>
              <Text className='detail-value'>{formatTime(binding.bound_at)}</Text>
            </View>
            <View className='detail-row'>
              <Text className='detail-label'>当前坐标</Text>
              <Text className='detail-value'>{coordinateLabel}</Text>
            </View>
            <View className='detail-row'>
              <Text className='detail-label'>状态更新时间</Text>
              <Text className='detail-value'>{formatTime(deviceStatus?.settings_updated_at)}</Text>
            </View>
            <View className='detail-row'>
              <Text className='detail-label'>定位更新时间</Text>
              <Text className='detail-value'>{formatTime(deviceStatus?.location_updated_at)}</Text>
            </View>
          </View>
        )}
      </View>
      {systemBanner}
    </View>
  )
}
