import { useEffect, useMemo, useRef, useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import {
  Button,
  Cell,
  CellGroup,
  ConfigProvider,
  DatePicker,
  Input,
  InputNumber,
  Popup,
  Space
} from '@nutui/nutui-react-taro'
import { ArrowRight, Location, Shop, Ticket } from '@nutui/icons-react-taro'
import dayjs from 'dayjs'
import type { ShopGoods } from '@/api/shop/shopGoods/model'
import { getShopGoods } from '@/api/shop/shopGoods'
import { listShopUserAddress } from '@/api/shop/shopUserAddress'
import type { ShopUserAddress } from '@/api/shop/shopUserAddress/model'
import './use.scss'
import Gap from "@/components/Gap";
import OrderConfirmSkeleton from "@/components/OrderConfirmSkeleton";
import type {ShopStore} from "@/api/shop/shopStore/model";
import {getShopStore, listShopStore} from "@/api/shop/shopStore";
import {getSelectedStoreFromStorage, saveSelectedStoreToStorage} from "@/utils/storeSelection";
import type { GltUserTicket } from '@/api/glt/gltUserTicket/model'
import { listGltUserTicket } from '@/api/glt/gltUserTicket'
import { addGltTicketOrder } from '@/api/glt/gltTicketOrder'

const MIN_START_QTY = 10

const OrderConfirm = () => {
  const [goods, setGoods] = useState<ShopGoods | null>(null);
  const [address, setAddress] = useState<ShopUserAddress>()
  const [quantity, setQuantity] = useState<number>(MIN_START_QTY)
  const [orderRemark, setOrderRemark] = useState<string>('')
  const [sendTime, setSendTime] = useState<Date>(new Date())
  const [sendTimePickerVisible, setSendTimePickerVisible] = useState(false)
  const [loading, setLoading] = useState<boolean>(true)
  const [error, setError] = useState<string>('')
  const [submitLoading, setSubmitLoading] = useState<boolean>(false)
  const loadAllDataLoadingRef = useRef(false)
  const hasInitialLoadedRef = useRef(false)

  // InputNumber 主题配置
  const customTheme = {
    nutuiInputnumberButtonWidth: '28px',
    nutuiInputnumberButtonHeight: '28px',
    nutuiInputnumberInputWidth: '40px',
    nutuiInputnumberInputHeight: '28px',
    nutuiInputnumberInputBorderRadius: '4px',
    nutuiInputnumberButtonBorderRadius: '4px',
  }

  // 门店选择：用于在下单页展示当前“已选门店”，并允许用户切换（写入 SelectedStore Storage）
  const [storePopupVisible, setStorePopupVisible] = useState(false)
  const [stores, setStores] = useState<ShopStore[]>([])
  const [storeLoading, setStoreLoading] = useState(false)
  const [selectedStore, setSelectedStore] = useState<ShopStore | null>(getSelectedStoreFromStorage())

  // 水票：用于“立即送水”下单（用水票抵扣，无需支付）
  const [tickets, setTickets] = useState<GltUserTicket[]>([])
  const [selectedTicketId, setSelectedTicketId] = useState<number | undefined>(undefined)
  const [ticketPopupVisible, setTicketPopupVisible] = useState(false)
  const [ticketLoading, setTicketLoading] = useState(false)

  const router = Taro.getCurrentInstance().router;
  const goodsId = router?.params?.goodsId;
  const numericGoodsId = useMemo(() => {
    const n = goodsId ? Number(goodsId) : undefined
    return typeof n === 'number' && Number.isFinite(n) ? n : undefined
  }, [goodsId])

  const userId = useMemo(() => {
    const raw = Taro.getStorageSync('UserId')
    const id = Number(raw)
    return Number.isFinite(id) && id > 0 ? id : undefined
  }, [])

  const usableTickets = useMemo(() => {
    const list = (tickets || [])
      .filter(t => t?.deleted !== 1)
      .filter(t => t?.status !== 1)
      .filter(t => Number.isFinite(Number(t?.id)) && Number(t.id) > 0)
      .filter(t => (t.availableQty ?? 0) > 0)
      // Some tenants don't fill goodsId on ticket; allow it as a fallback.
      .filter(t => (numericGoodsId ? (!t.goodsId || t.goodsId === numericGoodsId) : true))
    // FIFO: use older tickets first (reduce disputes).
    return list.sort((a, b) => {
      const ta = new Date(a.createTime || 0).getTime() || 0
      const tb = new Date(b.createTime || 0).getTime() || 0
      if (ta !== tb) return ta - tb
      return (a.id || 0) - (b.id || 0)
    })
  }, [tickets, numericGoodsId])

  const selectedTicket = useMemo(() => {
    if (!selectedTicketId) return undefined
    return usableTickets.find(t => Number(t.id) === Number(selectedTicketId))
  }, [usableTickets, selectedTicketId])

  const availableTicketTotal = useMemo(() => {
    return Number(selectedTicket?.availableQty || 0)
  }, [selectedTicket?.availableQty])

  const maxQuantity = useMemo(() => {
    const stockMax = goods?.stock ?? 999
    return Math.max(0, Math.min(stockMax, availableTicketTotal))
  }, [availableTicketTotal, goods?.stock])

  const canStartOrder = useMemo(() => {
    return maxQuantity >= MIN_START_QTY
  }, [maxQuantity])

  const displayQty = useMemo(() => {
    if (!canStartOrder) return 0
    return Math.max(MIN_START_QTY, Math.min(quantity, maxQuantity))
  }, [quantity, maxQuantity, canStartOrder])

  const sendTimeText = useMemo(() => {
    return dayjs(sendTime).format('YYYY-MM-DD HH:mm')
  }, [sendTime])

  const loadStores = async () => {
    if (storeLoading) return
    try {
      setStoreLoading(true)
      const list = await listShopStore()
      setStores((list || []).filter(s => s?.isDelete !== 1))
    } catch (e) {
      console.error('获取门店列表失败:', e)
      setStores([])
      Taro.showToast({title: '获取门店列表失败', icon: 'none'})
    } finally {
      setStoreLoading(false)
    }
  }

  const openStorePopup = async () => {
    setStorePopupVisible(true)
    if (!stores.length) {
      await loadStores()
    }
  }

  // 处理数量变化
  const handleQuantityChange = (value: string | number) => {
    const parsed = typeof value === 'string' ? parseInt(value) : value
    const newQuantity = Number.isFinite(parsed) ? Number(parsed) : 0
    const upper = maxQuantity
    if (!canStartOrder || upper <= 0) {
      setQuantity(0)
      return
    }
    setQuantity(Math.max(MIN_START_QTY, Math.min(newQuantity || MIN_START_QTY, upper)))
  }

  const loadUserTickets = async () => {
    if (ticketLoading) return
    if (!userId) {
      setTickets([])
      return
    }
    try {
      setTicketLoading(true)
      const list = await listGltUserTicket({ userId, status: 0 })
      setTickets(list || [])
    } catch (e) {
      console.error('获取水票失败:', e)
      setTickets([])
      Taro.showToast({ title: '获取水票失败', icon: 'none' })
    } finally {
      setTicketLoading(false)
    }
  }

  const onSubmit = async () => {
    if (submitLoading) return
    if (!goods?.goodsId) return

    // 基础校验
    if (!userId) {
      Taro.showToast({ title: '请先登录', icon: 'none' })
      return
    }
    if (!selectedStore?.id) {
      Taro.showToast({ title: '请选择门店', icon: 'none' })
      return
    }
    if (!address?.id) {
      Taro.showToast({ title: '请选择收货地址', icon: 'none' })
      return
    }
    if (!selectedTicket?.id) {
      Taro.showToast({ title: '请选择水票', icon: 'none' })
      return
    }
    if (availableTicketTotal <= 0) {
      Taro.showToast({ title: '暂无可用水票', icon: 'none' })
      return
    }

    const finalQty = displayQty
    if (finalQty <= 0) {
      Taro.showToast({ title: '请选择送水数量', icon: 'none' })
      return
    }
    if (finalQty > availableTicketTotal) {
      Taro.showToast({ title: '水票可用次数不足', icon: 'none' })
      return
    }
    if (goods.stock !== undefined && finalQty > goods.stock) {
      Taro.showToast({ title: '商品库存不足', icon: 'none' })
      return
    }
    if (finalQty < MIN_START_QTY) {
      Taro.showToast({ title: `最低起送 ${MIN_START_QTY} 桶`, icon: 'none' })
      return
    }
    if (!sendTime) {
      Taro.showToast({ title: '请选择配送时间', icon: 'none' })
      return
    }

    const confirmRes = await Taro.showModal({
      title: '确认下单',
      content: `配送时间：${sendTimeText}\n将使用 ${finalQty} 张水票下单，送水 ${finalQty} 桶，是否确认？`
    })
    if (!confirmRes.confirm) return

    try {
      setSubmitLoading(true)
      Taro.showLoading({ title: '提交中...' })

      await addGltTicketOrder({
        userTicketId: selectedTicket.id,
        storeId: selectedStore.id,
        addressId: address.id,
        totalNum: finalQty,
        buyerRemarks: orderRemark,
        sendTime: dayjs(sendTime).format('YYYY-MM-DD HH:mm:ss'),
        // Backend may take userId from token; pass-through is harmless if backend ignores it.
        userId,
        comments: goods.name ? `立即送水：${goods.name}` : '立即送水'
      })

      await loadUserTickets()

      Taro.showToast({ title: '下单成功', icon: 'success' })
      setTimeout(() => {
        // 跳转到“我的送水订单”
        Taro.redirectTo({ url: '/user/ticket/index?tab=order' })
      }, 800)
    } catch (e: any) {
      console.error('水票下单失败:', e)
      Taro.showToast({ title: e?.message || '下单失败', icon: 'none' })
    } finally {
      Taro.hideLoading()
      setSubmitLoading(false)
    }
  }

  // 统一的数据加载函数
  const loadAllData = async (opts?: { silent?: boolean }) => {
    if (loadAllDataLoadingRef.current) return
    loadAllDataLoadingRef.current = true
    try {
      if (!opts?.silent) setLoading(true)
      setError('')

      const [goodsRes, addressRes] = await Promise.all([
        numericGoodsId ? getShopGoods(numericGoodsId) : Promise.resolve(null),
        listShopUserAddress({ isDefault: true })
      ])

      // 设置商品信息
      if (goodsRes) {
        setGoods(goodsRes)
        hasInitialLoadedRef.current = true
      }

      // 设置默认收货地址
      if (addressRes && addressRes.length > 0) {
        setAddress(addressRes[0])
      }
      // Tickets are non-blocking for first paint; load in background.
      loadUserTickets()
    } catch (err) {
      console.error('加载数据失败:', err)
      if (opts?.silent) {
        Taro.showToast({ title: '刷新失败，请稍后重试', icon: 'none' })
      } else {
        setError('加载数据失败，请重试')
      }
    } finally {
      if (!opts?.silent) setLoading(false)
      loadAllDataLoadingRef.current = false
    }
  }

  useDidShow(() => {
    // 返回/切换到该页面时，刷新一下当前已选门店
    setSelectedStore(getSelectedStoreFromStorage())
    loadAllData({ silent: hasInitialLoadedRef.current })
  })

  // When tickets/stock change, clamp quantity into [0..maxQuantity].
  useEffect(() => {
    setQuantity(prev => {
      if (maxQuantity <= 0) return 0
      if (maxQuantity < MIN_START_QTY) return 0
      if (!prev || prev < MIN_START_QTY) return MIN_START_QTY
      return Math.min(prev, maxQuantity)
    })
  }, [maxQuantity])

  // Auto-pick a default ticket (first usable) when ticket list changes.
  useEffect(() => {
    if (!usableTickets.length) {
      setSelectedTicketId(undefined)
      return
    }
    const currentValid = selectedTicketId && usableTickets.some(t => Number(t.id) === Number(selectedTicketId))
    if (!currentValid) {
      setSelectedTicketId(Number(usableTickets[0].id))
    }
  }, [usableTickets, selectedTicketId])

  // 重新加载数据
  const handleRetry = () => {
    loadAllData()
  }

  // 错误状态
  if (error) {
    return (
      <View className="order-confirm-page">
        <View className="error-state">
          <Text className="error-text">{error}</Text>
          <Button onClick={handleRetry}>重新加载</Button>
        </View>
      </View>
    )
  }

  // 加载状态
  if (loading || !goods) {
    return <OrderConfirmSkeleton/>
  }

  return (
    <div className={'order-confirm-page'}>
      <CellGroup>
        <Cell
          title={(
            <View className="flex items-center gap-2">
              <Shop className={'text-gray-500'}/>
              <Text>选择门店</Text>
            </View>
          )}
          extra={(
            <View className={'flex items-center gap-2'}>
              <View className={'text-gray-900'}>
                {selectedStore?.name || '请选择门店'}
              </View>
              <ArrowRight className={'text-gray-400'} size={14}/>
            </View>
          )}
          onClick={openStorePopup}
        />
      </CellGroup>
      <CellGroup>
        {
          address && (
            <Cell className={'address-bottom-line'} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
              <Space>
                <Location className={'text-gray-500'}/>
                <View className={'flex flex-col w-full justify-between items-start'}>
                  <Space className={'flex flex-row w-full'}>
                    <View className={'flex-wrap text-nowrap whitespace-nowrap text-gray-500'}>送至</View>
                    <View className={'font-medium text-sm flex items-center w-full'}>
                      <View
                        style={{width: '64%'}}>{address.province} {address.city} {address.region} {address.address}</View>
                      <ArrowRight className={'text-gray-400'} size={14}/>
                    </View>
                  </Space>
                  <View className={'pt-1 pb-3 text-gray-500'}>{address.name} {address.phone}</View>
                </View>
              </Space>
            </Cell>
          )
        }
        {!address && (
          <Cell className={''} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
            <Space>
              <Location/>
              添加收货地址
            </Space>
          </Cell>
        )}
      </CellGroup>

      <CellGroup>
        <Cell
          title={'配送时间'}
          extra={(
            <View className={'flex items-center gap-2'}>
              <View className={'text-gray-900'}>{sendTimeText}</View>
              <ArrowRight className={'text-gray-400'} size={14}/>
            </View>
          )}
          onClick={() => setSendTimePickerVisible(true)}
        />
      </CellGroup>

      <CellGroup>
        <Cell
          title={'送水数量'}
          description={
            canStartOrder
              ? `最低起送 ${MIN_START_QTY} 桶`
              : `最低起送 ${MIN_START_QTY} 桶（当前最多 ${maxQuantity} 桶）`
          }
          extra={(
            <ConfigProvider theme={customTheme}>
              <InputNumber
                value={displayQty}
                min={canStartOrder ? MIN_START_QTY : 0}
                max={canStartOrder ? maxQuantity : 0}
                disabled={!canStartOrder}
                onChange={handleQuantityChange}
              />
            </ConfigProvider>
          )}
        />
      </CellGroup>

      <CellGroup>
        <Cell
          title={(
            <View className="flex items-center gap-2">
              <Ticket className={'text-gray-500'}/>
              <Text>选择水票</Text>
            </View>
          )}
          extra={(
            <View className={'flex items-center gap-2'}>
              <View className={'text-gray-900'}>
                {ticketLoading
                  ? '加载中...'
                  : (selectedTicket
                    ? `${selectedTicket.templateName || '水票'}（可用${selectedTicket.availableQty ?? 0}）`
                    : '请选择'
                  )
                }
              </View>
              <ArrowRight className={'text-gray-400'} size={14}/>
            </View>
          )}
          onClick={() => !ticketLoading && setTicketPopupVisible(true)}
        />
        <Cell
          title={'本次使用'}
          extra={<View className={'font-medium'}>{displayQty} 张</View>}
        />
      </CellGroup>

      <CellGroup>
        <Cell title={'备注'} extra={(
          <Input
            placeholder={'(选填)请填写备注'}
            style={{padding: '0'}}
            value={orderRemark}
            onChange={(value) => setOrderRemark(value)}
            maxLength={100}
          />
        )}/>
      </CellGroup>

      {/* 水票明细弹窗 */}
      <Popup
        visible={ticketPopupVisible}
        position="bottom"
        style={{ height: '70vh' }}
        onClose={() => setTicketPopupVisible(false)}
      >
        <View className="p-4">
          <View className="flex justify-between items-center mb-3">
            <Text className="text-base font-medium">水票明细</Text>
            <Text
              className="text-sm text-gray-500"
              onClick={() => setTicketPopupVisible(false)}
            >
              关闭
            </Text>
          </View>

          {ticketLoading ? (
            <View className="py-10 text-center text-gray-500">
              <Text>加载中...</Text>
            </View>
          ) : (
            <CellGroup>
              {usableTickets.map((t) => {
                const active = selectedTicket?.id && Number(selectedTicket.id) === Number(t.id)
                return (
                <Cell
                  key={t.id}
                  title={<Text className={active ? 'text-green-600' : ''}>{t.templateName || '水票'}</Text>}
                  description={t.orderNo ? `来源订单：${t.orderNo}` : ''}
                  extra={<Text className="text-gray-700">可用 {t.availableQty ?? 0}</Text>}
                  onClick={() => {
                    setSelectedTicketId(Number(t.id))
                    setTicketPopupVisible(false)
                    Taro.showToast({ title: '水票已选择', icon: 'success' })
                  }}
                />
              )})}
              {!usableTickets.length && (
                <Cell title={<Text className="text-gray-500">暂无可用水票</Text>} />
              )}
            </CellGroup>
          )}
        </View>
      </Popup>

      {/* 门店选择弹窗 */}
      <Popup
        visible={storePopupVisible}
        position="bottom"
        style={{height: '70vh'}}
        onClose={() => setStorePopupVisible(false)}
      >
        <View className="p-4">
          <View className="flex justify-between items-center mb-3">
            <Text className="text-base font-medium">选择门店</Text>
            <Text
              className="text-sm text-gray-500"
              onClick={() => setStorePopupVisible(false)}
            >
              关闭
            </Text>
          </View>

          {storeLoading ? (
            <View className="py-10 text-center text-gray-500">
              <Text>加载中...</Text>
            </View>
          ) : (
            <CellGroup>
              {stores.map((s) => {
                const isActive = !!selectedStore?.id && selectedStore.id === s.id
                return (
                  <Cell
                    key={s.id}
                    title={<Text className={isActive ? 'text-green-600' : ''}>{s.name || `门店${s.id}`}</Text>}
                    description={s.address || ''}
                    onClick={async () => {
                      let storeToSave: ShopStore = s
                      if (s?.id) {
                        try {
                          const full = await getShopStore(s.id)
                          if (full) storeToSave = full
                        } catch (_e) {
                          // keep base item
                        }
                      }
                      setSelectedStore(storeToSave)
                      saveSelectedStoreToStorage(storeToSave)
                      setStorePopupVisible(false)
                      Taro.showToast({title: '门店已切换', icon: 'success'})
                    }}
                  />
                )
              })}
              {!stores.length && (
                <Cell title={<Text className="text-gray-500">暂无门店数据</Text>} />
              )}
            </CellGroup>
          )}
        </View>
      </Popup>

      <Gap height={50}/>

      <DatePicker
        visible={sendTimePickerVisible}
        title="选择配送时间"
        type="datetime"
        startDate={new Date()}
        endDate={dayjs().add(30, 'day').toDate()}
        value={sendTime}
        onClose={() => setSendTimePickerVisible(false)}
        onCancel={() => setSendTimePickerVisible(false)}
        onConfirm={(_options, selectedValue) => {
          const [y, m, d, hh, mm] = (selectedValue || []).map(v => Number(v))
          const next = new Date(y, (m || 1) - 1, d || 1, hh || 0, mm || 0)
          setSendTime(next)
          setSendTimePickerVisible(false)
        }}
      />

      <div className={'fixed z-50 bg-white w-full bottom-0 left-0 pt-4 pb-10 border-t border-gray-200'}>
        <View className={'btn-bar flex justify-between items-center'}>
          <div className={'flex flex-col justify-center items-start mx-4'}>
            <View className={'flex items-center gap-2'}>
              <span className={'total-price text-sm text-gray-500'}>使用水票：</span>
              <span className={'text-red-500 text-xl font-bold'}>
                {displayQty}
              </span>
              <span className={'text-sm text-gray-500'}>张</span>
            </View>
          </div>
          <div className={'buy-btn mx-4'}>
            <Button
              type="success"
              size="large"
              loading={submitLoading}
              disabled={!selectedTicket?.id || availableTicketTotal <= 0 || !canStartOrder}
              onClick={onSubmit}
            >
              {submitLoading ? '提交中...' : '立即提交'}
            </Button>
          </div>
        </View>
      </div>
    </div>
  );
};

export default OrderConfirm;
