import { ScrollView, Text, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro'
import { useCallback, useMemo, useRef, useState } from 'react'
import { backend, type BackendNotification, type BackendNotificationPreferences } from '@/api/backend'
import { EmptyState, Page } from '@/components/ui'
import { ensureLoggedIn, getToken } from '@/stores/storage'
import { tapLight } from '@/utils/feedback'

type ReadFilter = 'all' | 'unread' | 'read'

const filters: Array<{ key: ReadFilter; label: string }> = [
  { key: 'all', label: '全部' },
  { key: 'unread', label: '未读' },
  { key: 'read', label: '已读' }
]

const categoryFilters = [
  { key: 'all', label: '全部分类' },
  { key: 'platform', label: '平台' },
  { key: 'account', label: '账号' },
  { key: 'order', label: '订单' },
  { key: 'membership', label: '会员' },
  { key: 'service', label: '服务' },
  { key: 'learning', label: '学习活动' },
  { key: 'expert', label: '专家' },
  { key: 'invoice', label: '发票' },
  { key: 'manual', label: '人工' }
]

const categoryText = Object.fromEntries(categoryFilters.map((item) => [item.key, item.label]))
const priorityText: Record<string, string> = { low: '低', normal: '普通', high: '重要', urgent: '紧急' }

definePageConfig({
  enablePullDownRefresh: true,
  backgroundTextStyle: 'dark',
  backgroundColor: '#f7f8fb'
})

function routeFromActionUrl(actionUrl: string) {
  if (!actionUrl) return ''
  if (actionUrl.startsWith('/pages/')) return actionUrl
  if (actionUrl.startsWith('/account/orders')) return '/pages/account/orders/index'
  if (actionUrl.startsWith('/account/invoices')) return '/pages/account/invoices/index'
  if (actionUrl.startsWith('/account/consulting')) return '/pages/account/consulting/index'
  if (actionUrl.startsWith('/account/data')) return '/pages/account/reports/index'
  if (actionUrl.startsWith('/account/expert-home')) return '/pages/account/expert-home/index'
  if (actionUrl.startsWith('/account/expert-bookings')) return '/pages/account/expert-bookings/index'
  if (actionUrl.startsWith('/account/courses')) return '/pages/account/courses/index'
  if (actionUrl.startsWith('/account/events')) return '/pages/account/events/index'
  if (actionUrl.startsWith('/account/membership')) return '/pages/account/membership/index'
  if (actionUrl.startsWith('/account/settings')) return '/pages/account/settings/index'
  return ''
}

function formatDate(value?: string | null) {
  if (!value) return '-'
  return new Date(value).toLocaleString('zh-CN')
}

function preferenceRows(prefs: BackendNotificationPreferences) {
  return [
    { key: 'inAppEnabled' as const, label: '站内信', enabled: prefs.inAppEnabled },
    { key: 'wechatSubscribeEnabled' as const, label: '微信订阅', enabled: prefs.wechatSubscribeEnabled },
    { key: 'smsEnabled' as const, label: '短信', enabled: prefs.smsEnabled },
    { key: 'emailEnabled' as const, label: '邮件', enabled: prefs.emailEnabled }
  ]
}

export default function AccountNotificationsPage() {
  const [items, setItems] = useState<BackendNotification[]>([])
  const [prefs, setPrefs] = useState<BackendNotificationPreferences | null>(null)
  const [filter, setFilter] = useState<ReadFilter>('all')
  const [category, setCategory] = useState('all')
  const [unreadCount, setUnreadCount] = useState(0)
  const [loading, setLoading] = useState(false)
  const [message, setMessage] = useState('')
  const [saving, setSaving] = useState(false)
  const filterRef = useRef<ReadFilter>('all')
  const categoryRef = useRef('all')
  const requestSeqRef = useRef(0)
  const hasLoadedRef = useRef(false)

  const loadNotifications = useCallback(async (nextFilter: ReadFilter = filterRef.current, nextCategory = categoryRef.current, light = false) => {
    const user = ensureLoggedIn('/pages/account/notifications/index')
    const token = getToken()
    if (!user || !token) return
    const seq = ++requestSeqRef.current
    if (!light) {
      setLoading(true)
      setMessage('')
    }
    try {
      const noticeResult = await backend.accountNotifications(token, {
        readState: nextFilter === 'all' ? '' : nextFilter,
        category: nextCategory === 'all' ? '' : nextCategory,
        pageSize: 80
      })
      if (seq !== requestSeqRef.current) return
      setItems(noticeResult.items || [])
      setUnreadCount(noticeResult.unreadCount || 0)
      setMessage('')
    } catch (error) {
      if (!light) setMessage(error instanceof Error ? error.message : '消息暂时加载失败')
    } finally {
      if (!light) setLoading(false)
    }
  }, [])

  async function loadPreferences() {
    const token = getToken()
    if (!token) return
    try {
      setPrefs(await backend.accountNotificationPreferences(token))
    } catch {
      // 通知列表优先展示；授权偏好暂时失败时不阻断消息阅读。
    }
  }

  useDidShow(() => {
    if (hasLoadedRef.current) return
    hasLoadedRef.current = true
    void loadNotifications(filterRef.current, categoryRef.current)
    void loadPreferences()
  })

  usePullDownRefresh(() => {
    void Promise.all([
      loadNotifications(filterRef.current, categoryRef.current, true),
      loadPreferences()
    ]).finally(() => {
      Taro.stopPullDownRefresh()
    })
  })

  const emptyText = useMemo(() => {
    if (filter === 'unread') return '当前没有未读消息。'
    if (filter === 'read') return '当前没有已读消息。'
    return '平台消息会展示在这里。'
  }, [filter])

  async function markRead(item: BackendNotification) {
    const token = getToken()
    if (!token || item.readAt) return
    await backend.markAccountNotificationRead(token, item.id).catch(() => undefined)
    await loadNotifications(filterRef.current, categoryRef.current, true)
  }

  async function openNotice(item: BackendNotification) {
    tapLight()
    await markRead(item)
    const url = routeFromActionUrl(item.actionUrl)
    if (url) Taro.navigateTo({ url })
  }

  function togglePreference(key: keyof Pick<BackendNotificationPreferences, 'inAppEnabled' | 'wechatSubscribeEnabled' | 'smsEnabled' | 'emailEnabled'>) {
    setPrefs((current) => current ? { ...current, [key]: !current[key] } : current)
  }

  async function savePreferences() {
    const token = getToken()
    if (!token || !prefs) return
    setSaving(true)
    try {
      const updated = await backend.updateAccountNotificationPreferences(token, prefs)
      setPrefs(updated)
      Taro.showToast({ title: '通知授权已保存', icon: 'none' })
    } catch (error) {
      Taro.showToast({ title: error instanceof Error ? error.message : '保存失败', icon: 'none' })
    } finally {
      setSaving(false)
    }
  }

  return (
    <Page title="消息通知" subtle={`未读 ${unreadCount} 条`}>
      <ScrollView scrollX className="account-tab-scroll" showScrollbar={false}>
        {filters.map((item) => (
          <View
            key={item.key}
            className={filter === item.key ? 'account-filter active' : 'account-filter'}
            onClick={() => {
              filterRef.current = item.key
              setFilter(item.key)
              void loadNotifications(item.key, categoryRef.current)
            }}
          >
            <Text>{item.label}</Text>
          </View>
        ))}
      </ScrollView>

      <ScrollView scrollX className="account-tab-scroll notify-category-scroll" showScrollbar={false}>
        {categoryFilters.map((item) => (
          <View
            key={item.key}
            className={category === item.key ? 'account-filter active' : 'account-filter'}
            onClick={() => {
              categoryRef.current = item.key
              setCategory(item.key)
              void loadNotifications(filterRef.current, item.key)
            }}
          >
            <Text>{item.label}</Text>
          </View>
        ))}
      </ScrollView>

      {message ? <Text className="form-error">{message}</Text> : null}
      {loading ? <EmptyState title="正在加载消息" compact /> : null}
      {!loading && items.length === 0 ? <EmptyState title="暂无消息" text={emptyText} compact /> : null}

      <View className="notify-list">
        {items.map((item) => (
          <View key={item.id} className={item.readAt ? 'notify-card' : 'notify-card unread'} onClick={() => void openNotice(item)}>
            <View className="notify-card-head">
              <Text className="notify-title">{item.title || '消息通知'}</Text>
              {!item.readAt ? <Text className="notify-dot">未读</Text> : null}
            </View>
            <Text className="notify-body">{item.body}</Text>
            <View className="notify-meta">
              <Text>{categoryText[item.category || ''] || item.category || item.scene}</Text>
              <Text>{priorityText[item.priority || 'normal'] || item.priority || '普通'}</Text>
              <Text>{formatDate(item.sentAt || item.createdAt)}</Text>
            </View>
          </View>
        ))}
      </View>

      {prefs ? (
        <View className="notify-pref-card">
          <Text className="notify-section-title">通知授权</Text>
          {preferenceRows(prefs).map((item) => (
            <View key={item.key} className="notify-pref-row" onClick={() => togglePreference(item.key)}>
              <Text>{item.label}</Text>
              <View className={item.enabled ? 'notify-switch active' : 'notify-switch'}>
                <View className="notify-switch-dot" />
              </View>
            </View>
          ))}
          <View className={saving ? 'inline-action disabled' : 'inline-action'} onClick={() => void savePreferences()}>
            {saving ? '保存中' : '保存授权'}
          </View>
        </View>
      ) : null}
    </Page>
  )
}
