'use client'

import Link from 'next/link'
import { useEffect, useMemo, useState } from 'react'
import { Bell, CheckCheck, ExternalLink, RefreshCw, Save } from 'lucide-react'
import { AccountAuthPrompt } from '@/components/account/AccountAuthPrompt'
import { useApp } from '@/components/providers/AppProvider'
import { backend, type BackendNotification, type BackendNotificationPreferences } from '@/lib/backend'

const readFilters = [
  { label: '全部', value: '' },
  { label: '未读', value: 'unread' },
  { label: '已读', value: 'read' },
]

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

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

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

function statusText(item: BackendNotification) {
  if (item.readAt) return `已读 · ${formatDate(item.readAt)}`
  return item.sentAt ? `未读 · ${formatDate(item.sentAt)}` : `待发送 · ${formatDate(item.scheduledAt)}`
}

function safeHref(actionUrl: string) {
  if (!actionUrl || !actionUrl.startsWith('/')) return ''
  return actionUrl
}

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 { user, token } = useApp()
  const [items, setItems] = useState<BackendNotification[]>([])
  const [prefs, setPrefs] = useState<BackendNotificationPreferences | null>(null)
  const [readState, setReadState] = useState('')
  const [category, setCategory] = useState('')
  const [unreadCount, setUnreadCount] = useState(0)
  const [loading, setLoading] = useState(false)
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState('')
  const [error, setError] = useState('')

  async function reload(nextReadState = readState, nextCategory = category) {
    if (!token) return
    setLoading(true)
    try {
      const [noticeResult, preferenceResult] = await Promise.all([
        backend.accountNotifications(token, { readState: nextReadState, category: nextCategory, pageSize: 80 }),
        backend.accountNotificationPreferences(token),
      ])
      setItems(noticeResult.items)
      setUnreadCount(noticeResult.unreadCount || 0)
      setPrefs(preferenceResult)
      setError('')
    } catch (err) {
      setError(err instanceof Error ? err.message : '消息加载失败')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void reload('', '')
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token])

  async function markRead(item: BackendNotification) {
    if (!token || item.readAt) return
    try {
      await backend.markAccountNotificationRead(token, item.id)
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : '标记已读失败')
    }
  }

  async function markAllRead() {
    if (!token) return
    try {
      const result = await backend.markAllAccountNotificationsRead(token, category ? { category } : {})
      setMessage(`已标记 ${result.readCount} 条消息`)
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : '全部已读失败')
    }
  }

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

  const visibleEmpty = useMemo(() => !loading && items.length === 0, [items.length, loading])

  if (!user) return <AccountAuthPrompt message="登录后可查看消息通知。" />

  return (
    <div className="mx-auto max-w-[1080px]">
      <nav className="mb-5 flex items-center gap-2 text-sm font-bold text-muted">
        <Link href="/account/membership" className="hover:text-brand">我的</Link>
        <span>/</span>
        <span className="text-ink">消息通知</span>
      </nav>

      {(message || error) && (
        <div className={`mb-4 rounded-[4px] px-4 py-3 text-sm font-bold ${error ? 'bg-red-50 text-red-700' : 'bg-green-50 text-green'}`}>
          {error || message}
        </div>
      )}

      <div className="grid gap-4 xl:grid-cols-[minmax(0,1fr)_320px]">
        <section className="border border-line bg-white">
          <div className="flex flex-col gap-3 border-b border-line px-4 py-4 lg:flex-row lg:items-center lg:justify-between">
            <div>
              <h1 className="flex items-center gap-2 text-2xl font-extrabold text-ink">
                <Bell className="h-5 w-5 text-brand" />
                消息通知
              </h1>
              <div className="mt-1 text-sm font-bold text-muted">未读 {unreadCount} 条</div>
            </div>
            <div className="flex flex-wrap gap-2">
              <button type="button" onClick={() => void reload()} className="inline-flex h-9 items-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-muted hover:border-brand hover:text-brand">
                <RefreshCw className="h-3.5 w-3.5" />
                刷新
              </button>
              <button type="button" onClick={() => void markAllRead()} className="inline-flex h-9 items-center gap-1.5 rounded-[4px] bg-ink px-3 text-xs font-extrabold text-white">
                <CheckCheck className="h-3.5 w-3.5" />
                全部已读
              </button>
            </div>
          </div>

          <div className="flex flex-col gap-2 border-b border-line px-4 py-3 lg:flex-row lg:items-center">
            <div className="flex flex-wrap gap-2">
              {readFilters.map((item) => (
                <button
                  type="button"
                  key={item.value}
                  onClick={() => { setReadState(item.value); void reload(item.value, category) }}
                  className={`h-8 rounded-[4px] px-3 text-xs font-extrabold ${readState === item.value ? 'bg-brand text-white' : 'border border-line text-muted hover:border-brand hover:text-brand'}`}
                >
                  {item.label}
                </button>
              ))}
            </div>
            <select
              value={category}
              onChange={(event) => { setCategory(event.target.value); void reload(readState, event.target.value) }}
              className="h-8 rounded-[4px] border border-line px-2 text-xs font-bold outline-none focus:border-brand"
            >
              {categoryFilters.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
            </select>
          </div>

          {loading && <div className="px-5 py-10 text-sm font-bold text-muted">正在加载消息...</div>}
          {visibleEmpty && <div className="px-5 py-10 text-sm font-bold text-muted">暂无消息</div>}
          {!loading && items.map((item) => {
            const href = safeHref(item.actionUrl)
            return (
              <article key={item.id} className={`border-b border-line px-4 py-4 last:border-b-0 ${item.readAt ? 'bg-white' : 'bg-[#f8fbff]'}`}>
                <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="text-base font-extrabold text-ink">{item.title || '消息通知'}</span>
                      {!item.readAt && <span className="h-5 rounded-[4px] bg-brand px-2 text-[11px] font-extrabold leading-5 text-white">未读</span>}
                      <span className="h-5 rounded-[4px] bg-bg px-2 text-[11px] font-bold text-muted">{categoryLabel[item.category || ''] || item.category || '其他'}</span>
                      <span className="h-5 rounded-[4px] bg-bg px-2 text-[11px] font-bold text-muted">{priorityLabel[item.priority || 'normal'] || item.priority || '普通'}</span>
                    </div>
                    <p className="mt-2 text-sm leading-6 text-muted">{item.body}</p>
                    <div className="mt-2 text-xs font-bold text-soft">{statusText(item)}</div>
                  </div>
                  <div className="flex shrink-0 flex-wrap gap-2">
                    {!item.readAt && (
                      <button type="button" onClick={() => void markRead(item)} className="h-8 rounded-[4px] border border-line px-3 text-xs font-extrabold text-muted hover:border-brand hover:text-brand">
                        标记已读
                      </button>
                    )}
                    {href && (
                      <Link href={href} onClick={() => void markRead(item)} className="inline-flex h-8 items-center gap-1.5 rounded-[4px] bg-brand px-3 text-xs font-extrabold text-white hover:bg-brand-dark">
                        查看
                        <ExternalLink className="h-3.5 w-3.5" />
                      </Link>
                    )}
                  </div>
                </div>
              </article>
            )
          })}
        </section>

        <aside className="border border-line bg-white">
          <div className="border-b border-line px-4 py-4">
            <h2 className="text-base font-extrabold text-ink">通知授权</h2>
            <div className="mt-1 text-xs font-bold text-muted">紧急系统消息会保留审计记录。</div>
          </div>
          {prefs ? (
            <div className="space-y-4 px-4 py-4">
              {preferenceRows(prefs).map((item) => (
                <label key={item.key} className="flex items-center justify-between gap-3">
                  <span className="text-sm font-extrabold text-ink">{item.label}</span>
                  <input
                    type="checkbox"
                    checked={item.enabled}
                    onChange={(event) => setPrefs((current) => current ? { ...current, [item.key]: event.target.checked } : current)}
                    className="h-4 w-4 accent-brand"
                  />
                </label>
              ))}
              <div className="grid grid-cols-2 gap-3">
                <label>
                  <span className="mb-1 block text-xs font-bold text-muted">免打扰开始</span>
                  <input value={prefs.quietHoursStart} onChange={(event) => setPrefs({ ...prefs, quietHoursStart: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-2 text-xs font-bold outline-none focus:border-brand" />
                </label>
                <label>
                  <span className="mb-1 block text-xs font-bold text-muted">免打扰结束</span>
                  <input value={prefs.quietHoursEnd} onChange={(event) => setPrefs({ ...prefs, quietHoursEnd: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-2 text-xs font-bold outline-none focus:border-brand" />
                </label>
              </div>
              <button type="button" disabled={saving} onClick={() => void savePreferences()} className="inline-flex h-9 w-full items-center justify-center gap-1.5 rounded-[4px] bg-brand text-xs font-extrabold text-white hover:bg-brand-dark disabled:opacity-60">
                <Save className="h-3.5 w-3.5" />
                {saving ? '保存中...' : '保存授权'}
              </button>
            </div>
          ) : (
            <div className="px-4 py-8 text-sm font-bold text-muted">正在加载授权...</div>
          )}
        </aside>
      </div>
    </div>
  )
}
