<template>
	<view class="page-result">
		<view class="result-header" @click="onReSearch">
			<!-- <u-icon name="arrow-left" size="20" color="#333" @click.stop="onBack" /> -->
			<view class="result-header__keyword">
				<u-icon name="search" color="#999" size="16" />
				<text class="result-header__text">{{ keyword }}</text>
			</view>
		</view>

		<search-result-tabs
			:model-value="activeTab"
			:price-order="priceOrder"
			@update:model-value="activeTab = $event"
			@update:price-order="priceOrder = $event"
			@change="onTabChange"
			@price-change="onPriceOrderChange"
		/>

		<scroll-view
			class="result-scroll"
			scroll-y
			:style="{ height: scrollHeight }"
			:scroll-top="listScrollTop"
			@scrolltolower="onLoadMore"
		>
			<view v-if="loading && !displayList.length" class="result-loading">
				<u-loading-icon mode="circle" />
			</view>

			<template v-else-if="isShopTab">
				<shop-list v-if="shopList.length" :list="shopList" @item-click="onShopClick" />
				<view v-else class="result-empty">
					<u-empty mode="search" :text="emptyText" icon-size="80" />
					<text v-if="loadFailed" class="result-retry" @click="reloadAll">点击重试</text>
				</view>
			</template>

			<template v-else>
				<goods-grid v-if="goodsList.length" :list="goodsList" @item-click="onGoodsClick" />
				<view v-else class="result-empty">
					<u-empty mode="search" :text="emptyText" icon-size="80" />
					<text v-if="loadFailed" class="result-retry" @click="reloadAll">点击重试</text>
				</view>
			</template>

			<view v-if="displayList.length" class="result-footer">
				<text v-if="loadingMore">加载中...</text>
				<text v-else-if="finished">没有更多了</text>
			</view>
		</scroll-view>
	</view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { searchAll } from '@/api/search'
import { mapGoodsCardList } from '@/utils/goodsDisplay'
import { mapShopCardList } from '@/utils/shopDisplay'
import { addSearchHistory } from '@/utils/searchHistory'
import { goSearchInput } from '@/utils/searchNav'
import { goGoodsDetail } from '@/utils/goodsDetail'
import { goShopHome } from '@/utils/shopNav'
import {
  SEARCH_TAB_SALES,
  SEARCH_TAB_PRICE,
  SEARCH_TAB_SHOP,
  DEFAULT_GOODS_SORT,
  PRICE_ORDER_ASC,
  SEARCH_PAGE_SIZE
} from '@/constants/search'
import SearchResultTabs from '@/components/search/SearchResultTabs.vue'
import GoodsGrid from '@/components/mall/GoodsGrid.vue'
import ShopList from '@/components/search/ShopList.vue'

const keyword = ref('')
const activeTab = ref(SEARCH_TAB_SALES)
const priceOrder = ref(PRICE_ORDER_ASC)

const goodsList = ref([])
const shopList = ref([])
const goodsTotal = ref(0)
const shopTotal = ref(0)
const goodsPageNum = ref(1)
const shopPageNum = ref(1)

const loading = ref(false)
const loadingMore = ref(false)
const finished = ref(false)
const loadFailed = ref(false)
const listScrollTop = ref(0)
const scrollHeight = ref('600px')

const emptyText = '暂无相关'

const isShopTab = computed(() => activeTab.value === SEARCH_TAB_SHOP)

const displayList = computed(() => (isShopTab.value ? shopList.value : goodsList.value))

const goodsSortBy = computed(() => {
  if (activeTab.value === SEARCH_TAB_SALES) {
    return DEFAULT_GOODS_SORT
  }
  if (activeTab.value === SEARCH_TAB_PRICE) {
    return priceOrder.value
  }
  return DEFAULT_GOODS_SORT
})

function calcScrollHeight() {
  try {
    const sys = uni.getSystemInfoSync()
    const h = sys.windowHeight || 600
    scrollHeight.value = `${h - 120}px`
  } catch (e) {
    scrollHeight.value = '500px'
  }
}

function resetScrollTop() {
  listScrollTop.value = listScrollTop.value === 0 ? 0.1 : 0
}

async function fetchSearch(reset) {
  const kw = (keyword.value || '').trim()
  if (!kw) return

  if (reset) {
    loading.value = true
    loadFailed.value = false
    finished.value = false
    if (isShopTab.value) {
      shopPageNum.value = 1
    } else {
      goodsPageNum.value = 1
    }
  } else {
    if (finished.value || loadingMore.value) return
    loadingMore.value = true
  }

  try {
    const params = {
      keyword: kw,
      sortBy: goodsSortBy.value,
      goodsPageNum: goodsPageNum.value,
      goodsPageSize: SEARCH_PAGE_SIZE,
      shopPageNum: shopPageNum.value,
      shopPageSize: SEARCH_PAGE_SIZE
    }
    const data = await searchAll(params)
    const goodsRows = mapGoodsCardList((data.goods && data.goods.rows) || [])
    const shopRows = mapShopCardList((data.shops && data.shops.rows) || [])
    const gTotal = Number((data.goods && data.goods.total) || 0)
    const sTotal = Number((data.shops && data.shops.total) || 0)

    if (isShopTab.value) {
      if (reset) {
        shopList.value = shopRows
      } else {
        shopList.value = shopList.value.concat(shopRows)
      }
      shopTotal.value = sTotal
      finished.value =
        shopRows.length < SEARCH_PAGE_SIZE || (sTotal > 0 && shopList.value.length >= sTotal)
      if (!finished.value) {
        shopPageNum.value += 1
      }
    } else {
      if (reset) {
        goodsList.value = goodsRows
      } else {
        goodsList.value = goodsList.value.concat(goodsRows)
      }
      goodsTotal.value = gTotal
      finished.value =
        goodsRows.length < SEARCH_PAGE_SIZE || (gTotal > 0 && goodsList.value.length >= gTotal)
      if (!finished.value) {
        goodsPageNum.value += 1
      }
      // 同一次请求顺带更新店铺缓存，切「店铺」Tab 可直接展示
      if (reset && shopPageNum.value === 1) {
        shopList.value = shopRows
        shopTotal.value = sTotal
        if (shopRows.length > 0) {
          shopPageNum.value = 2
        }
      }
    }
  } catch (e) {
    loadFailed.value = true
    if (reset) {
      if (isShopTab.value) {
        shopList.value = []
      } else {
        goodsList.value = []
      }
    }
  } finally {
    loading.value = false
    loadingMore.value = false
  }
}

function reloadAll() {
  resetScrollTop()
  if (isShopTab.value) {
    shopPageNum.value = 1
  } else {
    goodsPageNum.value = 1
  }
  fetchSearch(true)
}

function onTabChange() {
  resetScrollTop()
  finished.value = false
  if (isShopTab.value) {
    if (shopList.value.length > 0) {
      finished.value = shopTotal.value > 0 && shopList.value.length >= shopTotal.value
      return
    }
    shopPageNum.value = 1
    fetchSearch(true)
  } else {
    goodsPageNum.value = 1
    fetchSearch(true)
  }
}

function onPriceOrderChange() {
  if (activeTab.value !== SEARCH_TAB_PRICE) return
  resetScrollTop()
  goodsPageNum.value = 1
  fetchSearch(true)
}

function onLoadMore() {
  if (!loading.value && !loadingMore.value && !finished.value) {
    fetchSearch(false)
  }
}

function onBack() {
  uni.navigateBack()
}

function onReSearch() {
  goSearchInput(keyword.value)
}

function onGoodsClick(item) {
  if (item && item.goodsId) {
    goGoodsDetail(item.goodsId)
  }
}

function onShopClick(item) {
  if (item && item.shopId) {
    goShopHome(item.shopId)
  }
}

onLoad((options) => {
  calcScrollHeight()
  const kw = options && options.keyword ? decodeURIComponent(options.keyword) : ''
  keyword.value = (kw || '').trim()
  if (!keyword.value) {
    uni.showToast({ title: '请输入搜索内容', icon: 'none' })
    setTimeout(() => uni.navigateBack(), 500)
    return
  }
  addSearchHistory(keyword.value)
  fetchSearch(true)
})
</script>

<style lang="scss" scoped>
.page-result {
	display: flex;
	flex-direction: column;
	height: calc(100vh - 100rpx);
	background: #f5f6f8;
}
.result-header {
	display: flex;
	align-items: center;
	padding: 16rpx 24rpx;
	background: #e8f5e9;
	border-bottom: 1rpx solid #c8e6c9;
}
.result-header__keyword {
	flex: 1;
	display: flex;
	align-items: center;
	height: 64rpx;
	margin-left: 16rpx;
	padding: 0 20rpx;
	background: #fff;
	border: 1rpx solid #a5d6a7;
	border-radius: 32rpx;
}
.result-header__text {
	margin-left: 12rpx;
	font-size: 28rpx;
	color: #333;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.result-scroll {
	flex: 1;
  box-sizing: border-box;
  padding: 10rpx;
}
.result-loading {
	padding: 80rpx 0;
	display: flex;
	justify-content: center;
}
.result-empty {
	padding: 60rpx 0;
	display: flex;
	flex-direction: column;
	align-items: center;
}
.result-retry {
	margin-top: 24rpx;
	font-size: 28rpx;
	color: #2e7d32;
}
.result-footer {
	padding: 24rpx;
	text-align: center;
	font-size: 24rpx;
	color: #999;
}
</style>
