import { Input, Text, View } from '@tarojs/components'
import { useLoad } from '@tarojs/taro'
import { useEffect, useMemo, useState } from 'react'
import { Page, ProductImage } from '@/components/ui'
import { backend, mapAgentProduct, mapCourseProduct, mapDataProduct, mapEventProduct, mapNewsArticle } from '@/api/backend'
import { consultingProduct } from '@/constants/services'
import type { NewsArticle, ServiceProduct } from '@/types'
import { go, toProduct, toast } from '@/utils/nav'

function includesKeyword(...values: Array<string | undefined>) {
  return (keyword: string) => values.some((value) => (value || '').toLowerCase().includes(keyword))
}

function decodeSearchPlaceholder(value: unknown) {
  let text = String(value || '').trim()
  for (let index = 0; index < 2 && /%[0-9a-f]{2}/i.test(text); index += 1) {
    try {
      const decoded = decodeURIComponent(text)
      if (decoded === text) break
      text = decoded
    } catch {
      break
    }
  }
  return text || '请输入关键词'
}

export default function SearchPage() {
  const [placeholder, setPlaceholder] = useState('请输入关键词')
  const [keyword, setKeyword] = useState('')
  const [submittedKeyword, setSubmittedKeyword] = useState('')
  const [products, setProducts] = useState<ServiceProduct[]>([])
  const [articles, setArticles] = useState<NewsArticle[]>([])
  const [loading, setLoading] = useState(true)

  useLoad((query) => {
    if (query.placeholder) setPlaceholder(decodeSearchPlaceholder(query.placeholder))
  })

  useEffect(() => {
    Promise.all([
      backend.courseCatalog(),
      backend.eventCatalog(),
      backend.dataCatalog(),
      backend.agentCatalog(),
      backend.news()
    ])
      .then(([courseData, eventData, dataData, agentData, newsData]) => {
        setProducts([
          consultingProduct,
          ...courseData.items.map(mapCourseProduct),
          ...eventData.items.map(mapEventProduct),
          ...dataData.items.map(mapDataProduct),
          ...agentData.items.map(mapAgentProduct)
        ])
        setArticles(newsData.items.map(mapNewsArticle))
      })
      .catch((error) => toast(error instanceof Error ? error.message : '搜索数据加载失败'))
      .finally(() => setLoading(false))
  }, [])

  function clearSearch() {
    setKeyword('')
    setSubmittedKeyword('')
  }

  function updateKeyword(value: string) {
    setKeyword(value)
    setSubmittedKeyword(value.trim())
  }

  const normalizedKeyword = submittedKeyword.trim().toLowerCase()
  const hasKeyword = normalizedKeyword.length > 0
  const serviceResults = useMemo(() => {
    if (!normalizedKeyword) return []
    return products.filter((item) => includesKeyword(item.title, item.subtitle, item.summary, item.category, ...(item.tags || []))(normalizedKeyword))
  }, [normalizedKeyword, products])
  const newsResults = useMemo(() => {
    if (!normalizedKeyword) return []
    return articles.filter((item) => includesKeyword(item.title, item.summary, item.category, item.authorName)(normalizedKeyword))
  }, [normalizedKeyword, articles])
  const hasResults = serviceResults.length > 0 || newsResults.length > 0
  const empty = hasKeyword && !loading && !hasResults

  return (
    <Page>
      <View className="search-page-head">
        <View className="search-shell">
          <Input
            className="search-input"
            value={keyword}
            focus
            confirmType="search"
            placeholder={placeholder}
            onConfirm={(event) => updateKeyword(String(event.detail.value))}
            onInput={(event) => updateKeyword(String(event.detail.value))}
          />
          {keyword ? <Text className="search-clear" onClick={clearSearch}>清空</Text> : null}
        </View>
      </View>

      {!hasKeyword ? <Text className="search-inline-hint">输入关键词，搜索课程、活动、数据服务、智能体和资讯。</Text> : null}
      {loading && hasKeyword ? <Text className="search-inline-hint">正在搜索...</Text> : null}
      {empty ? <Text className="search-inline-empty">没有找到“{submittedKeyword}”相关内容</Text> : null}

      {hasKeyword && serviceResults.length > 0 ? (
        <View className="search-group">
          <Text className="search-group-title">服务</Text>
          {serviceResults.map((item) => (
            <View key={item.id} className="search-result-row" onClick={() => toProduct(item.id)}>
              <ProductImage className="search-thumb" src={item.cover} />
              <View style={{ flex: 1, minWidth: 0 }}>
                <Text className="row-title">{item.title}</Text>
                <Text className="row-sub">{item.subtitle}</Text>
              </View>
              <Text className="arrow">›</Text>
            </View>
          ))}
        </View>
      ) : null}

      {hasKeyword && newsResults.length > 0 ? (
        <View className="search-group">
          <Text className="search-group-title">资讯</Text>
          {newsResults.map((item) => (
            <View key={item.id} className="search-result-row" onClick={() => go(`/pages/news/detail/index?id=${item.id}`)}>
              {item.coverUrl ? <ProductImage className="search-thumb" src={item.coverUrl} /> : <View className="search-thumb visual-card visual-platform"><Text className="visual-label">资讯</Text></View>}
              <View style={{ flex: 1, minWidth: 0 }}>
                <Text className="row-title">{item.title}</Text>
                <Text className="row-sub">{item.summary}</Text>
              </View>
              <Text className="arrow">›</Text>
            </View>
          ))}
        </View>
      ) : null}
    </Page>
  )
}
