import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import {
  Tabs,
  TabPane,
  Cell,
  Space,
  Button,
  Dialog,
  Radio,
  RadioGroup,
  Image,
  Empty,
  InfiniteLoading,
  PullToRefresh,
  Loading
} from '@nutui/nutui-react-taro'
import dayjs from 'dayjs'

import { pageGltTicketOrder, updateGltTicketOrder } from '@/api/glt/gltTicketOrder'
import type { GltTicketOrder, GltTicketOrderParam } from '@/api/glt/gltTicketOrder/model'
import { uploadFile } from '@/api/system/file'
import { listShopStoreRider, updateShopStoreRider } from '@/api/shop/shopStoreRider'
import { getCurrentLngLat } from '@/utils/location'

const PAGE_SIZE = 10

type DeliverConfirmMode = 'photoComplete' | 'waitCustomerConfirm'

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

  const pageRef = useRef(1)
  const listRef = useRef<GltTicketOrder[]>([])

  const [tabIndex, setTabIndex] = useState(0)
  const [list, setList] = useState<GltTicketOrder[]>([])
  const [hasMore, setHasMore] = useState(true)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const [deliverDialogVisible, setDeliverDialogVisible] = useState(false)
  const [deliverSubmitting, setDeliverSubmitting] = useState(false)
  const [deliverOrder, setDeliverOrder] = useState<GltTicketOrder | null>(null)
  const [deliverImg, setDeliverImg] = useState<string | undefined>(undefined)
  const [deliverConfirmMode, setDeliverConfirmMode] = useState<DeliverConfirmMode>('photoComplete')

  const riderTabs = useMemo(
    () => [
      { index: 0, title: '全部' },
      { index: 1, title: '待配送', deliveryStatus: 10 },
      { index: 2, title: '配送中', deliveryStatus: 20 },
      { index: 3, title: '待确认', deliveryStatus: 30 },
      { index: 4, title: '已完成', deliveryStatus: 40 }
    ],
    []
  )

  const getOrderStatusText = (order: GltTicketOrder) => {
    if (order.status === 1) return '已冻结'

    const deliveryStatus = order.deliveryStatus
    if (deliveryStatus === 40) return '已完成'
    if (deliveryStatus === 30) return '待客户确认'
    if (deliveryStatus === 20) return '配送中'
    if (deliveryStatus === 10) return '待配送'

    // 兼容：如果后端暂未下发 deliveryStatus，就用时间字段推断
    if (order.receiveConfirmTime) return '已完成'
    if (order.sendEndTime) return '待客户确认'
    if (order.sendStartTime) return '配送中'
    if (order.riderId) return '待配送'
    return '待派单'
  }

  const getOrderStatusColor = (order: GltTicketOrder) => {
    const text = getOrderStatusText(order)
    if (text === '已完成') return 'text-green-600'
    if (text === '待客户确认') return 'text-purple-600'
    if (text === '配送中') return 'text-blue-600'
    if (text === '待配送') return 'text-amber-600'
    if (text === '已冻结') return 'text-orange-600'
    return 'text-gray-500'
  }

  const canStartDeliver = (order: GltTicketOrder) => {
    if (!order.id) return false
    if (order.status === 1) return false
    if (!riderId || order.riderId !== riderId) return false
    if (order.deliveryStatus && order.deliveryStatus !== 10) return false
    return !order.sendStartTime && !order.sendEndTime
  }

  const canConfirmDelivered = (order: GltTicketOrder) => {
    if (!order.id) return false
    if (order.status === 1) return false
    if (!riderId || order.riderId !== riderId) return false
    if (order.receiveConfirmTime) return false
    if (order.deliveryStatus === 40) return false
    if (order.sendEndTime) return false

    // 只允许在“配送中”阶段确认送达
    if (typeof order.deliveryStatus === 'number') return order.deliveryStatus === 20
    return !!order.sendStartTime
  }

  const canCompleteByPhoto = (order: GltTicketOrder) => {
    if (!order.id) return false
    if (order.status === 1) return false
    if (!riderId || order.riderId !== riderId) return false
    if (order.receiveConfirmTime) return false
    if (order.deliveryStatus === 40) return false
    // 已送达但未完成：允许补传照片并直接完成
    return !!order.sendEndTime
  }

  const filterByTab = useCallback(
    (orders: GltTicketOrder[]) => {
      if (tabIndex === 0) return orders

      const current = riderTabs.find(t => t.index === tabIndex)
      const status = current?.deliveryStatus
      if (!status) return orders

      // 如果后端已实现 deliveryStatus 筛选，这里基本不会再过滤；否则用兼容逻辑兜底。
      return orders.filter(o => {
        const ds = o.deliveryStatus
        if (typeof ds === 'number') return ds === status
        if (status === 10) return !!o.riderId && !o.sendStartTime && !o.sendEndTime
        if (status === 20) return !!o.sendStartTime && !o.sendEndTime
        if (status === 30) return !!o.sendEndTime && !o.receiveConfirmTime
        if (status === 40) return !!o.receiveConfirmTime
        return true
      })
    },
    [riderTabs, tabIndex]
  )

  const reload = useCallback(
    async (resetPage = false) => {
      if (!riderId) return
      if (loading) return
      setLoading(true)
      setError(null)

      const currentPage = resetPage ? 1 : pageRef.current
      const currentTab = riderTabs.find(t => t.index === tabIndex)

      const params: GltTicketOrderParam = {
        page: currentPage,
        limit: PAGE_SIZE,
        riderId,
        deliveryStatus: currentTab?.deliveryStatus
      }

      try {
        const res = await pageGltTicketOrder(params as any)
        const incomingAll = (res?.list || []) as GltTicketOrder[]
        // 兼容：后端若暂未实现 riderId 过滤，前端兜底过滤掉非本人的订单
        const incoming = incomingAll.filter(o => o?.deleted !== 1 && o?.riderId === riderId)

        const prev = resetPage ? [] : listRef.current
        const next = resetPage ? incoming : prev.concat(incoming)
        listRef.current = next
        setList(next)

        const total = typeof res?.count === 'number' ? res.count : undefined
        const filteredOut = incomingAll.length - incoming.length
        if (typeof total === 'number' && filteredOut === 0) {
          setHasMore(next.length < total)
        } else {
          setHasMore(incomingAll.length >= PAGE_SIZE)
        }

        pageRef.current = currentPage + 1
      } catch (e) {
        console.error('加载配送订单失败:', e)
        setError('加载失败，请重试')
        setHasMore(false)
      } finally {
        setLoading(false)
      }
    },
    [loading, riderId, riderTabs, tabIndex]
  )

  const reloadMore = useCallback(async () => {
    if (loading || !hasMore) return
    await reload(false)
  }, [hasMore, loading, reload])

  const openDeliverDialog = (order: GltTicketOrder, opts?: { mode?: DeliverConfirmMode }) => {
    setDeliverOrder(order)
    setDeliverImg(order.sendEndImg)
    setDeliverConfirmMode(opts?.mode || (order.sendEndImg ? 'photoComplete' : 'waitCustomerConfirm'))
    setDeliverDialogVisible(true)
  }

  const handleChooseDeliverImg = async () => {
    try {
      const file = await uploadFile()
      setDeliverImg(file?.url)
    } catch (e) {
      console.error('上传送达照片失败:', e)
      Taro.showToast({ title: '上传失败，请重试', icon: 'none' })
    }
  }

  const handleStartDeliver = async (order: GltTicketOrder) => {
    if (!order?.id) return
    if (!canStartDeliver(order)) return
    try {
      await updateGltTicketOrder({
        id: order.id,
        deliveryStatus: 20,
        sendStartTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
      })
      Taro.showToast({ title: '已开始配送', icon: 'success' })
      pageRef.current = 1
      await reload(true)
    } catch (e) {
      console.error('开始配送失败:', e)
      Taro.showToast({ title: '开始配送失败', icon: 'none' })
    }
  }

  const handleConfirmDelivered = async () => {
    if (!deliverOrder?.id) return
    if (deliverSubmitting) return
    if (deliverConfirmMode === 'photoComplete' && !deliverImg) {
      Taro.showToast({ title: '请先拍照/上传送达照片', icon: 'none' })
      return
    }
    setDeliverSubmitting(true)
    try {
      // 送达时同步记录配送员当前位置（用于门店/后台跟踪骑手位置）
      const loc = await getCurrentLngLat('确认送达需要记录您的当前位置，请在设置中开启定位权限后重试。')
      if (!loc) return

      try {
        // 优先按 userId 精确查找；后端若未支持该字段，会自动忽略，我们再做兜底。
        let riderRow =
          (await listShopStoreRider({ userId: riderId, storeId: deliverOrder.storeId, status: 1 } as any))
            ?.find(r => String(r?.userId || '') === String(riderId || '')) ||
          null

        // 兜底：按门店筛选后再匹配 userId
        if (!riderRow && deliverOrder.storeId) {
          const list = await listShopStoreRider({ storeId: deliverOrder.storeId, status: 1 } as any)
          riderRow = list?.find(r => String(r?.userId || '') === String(riderId || '')) || null
        }

        if (riderRow?.id) {
          await updateShopStoreRider({
            id: riderRow.id,
            longitude: loc.lng,
            latitude: loc.lat
          } as any)
        } else {
          console.warn('未找到 ShopStoreRider 记录，无法更新骑手经纬度:', { riderId, storeId: deliverOrder.storeId })
        }
      } catch (e) {
        // 不阻塞送达流程，但记录日志便于排查。
        console.warn('更新 ShopStoreRider 经纬度失败:', e)
      }

      const now = dayjs().format('YYYY-MM-DD HH:mm:ss')
      // 送达时间：首次“确认送达”写入；补传照片时不要覆盖原送达时间
      const deliveredAt = deliverOrder.sendEndTime || now
      // 说明：
      // - waitCustomerConfirm：只标记“已送达”，进入待客户确认（客户点击确认收货后完成）
      // - photoComplete：拍照留档后可直接完成（由后端策略决定是否允许）
      const payload: GltTicketOrder =
        deliverConfirmMode === 'photoComplete'
          ? {
              id: deliverOrder.id,
              deliveryStatus: 40,
              sendEndTime: deliveredAt,
              sendEndImg: deliverImg,
              receiveConfirmTime: now,
              receiveConfirmType: 20
            }
          : {
              id: deliverOrder.id,
              deliveryStatus: 30,
              sendEndTime: deliveredAt,
              sendEndImg: deliverImg
            }

      await updateGltTicketOrder(payload)
      Taro.showToast({ title: '已确认送达', icon: 'success' })
      setDeliverDialogVisible(false)
      setDeliverOrder(null)
      setDeliverImg(undefined)
      setDeliverConfirmMode('photoComplete')
      pageRef.current = 1
      await reload(true)
    } catch (e) {
      console.error('确认送达失败:', e)
      Taro.showToast({ title: '确认送达失败', icon: 'none' })
    } finally {
      setDeliverSubmitting(false)
    }
  }

  useEffect(() => {
    listRef.current = list
  }, [list])

  useDidShow(() => {
    pageRef.current = 1
    listRef.current = []
    setList([])
    setHasMore(true)
    void reload(true)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  })

  useEffect(() => {
    pageRef.current = 1
    listRef.current = []
    setList([])
    setHasMore(true)
    void reload(true)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tabIndex, riderId])

  if (!riderId) {
    return (
      <View className="bg-gray-50 min-h-screen p-4">
        <Text>请先登录</Text>
      </View>
    )
  }

  const displayList = filterByTab(list)

  return (
    <View className="bg-gray-50 min-h-screen">
      <Tabs value={tabIndex} onChange={paneKey => setTabIndex(Number(paneKey))} align="left">
        {riderTabs.map(t => (
          <TabPane key={t.index} title={loading && tabIndex === t.index ? `${t.title}...` : t.title} />
        ))}
      </Tabs>

      <View className="px-3 pb-4">
        <PullToRefresh
          onRefresh={async () => {
            pageRef.current = 1
            listRef.current = []
            setList([])
            setHasMore(true)
            await reload(true)
          }}
        >
          {error ? (
            <View className="bg-white rounded-lg p-6">
              <View className="flex flex-col items-center justify-center">
                <Text className="text-gray-500 mb-3">{error}</Text>
                <Button size="small" type="primary" onClick={() => reload(true)}>
                  重新加载
                </Button>
              </View>
            </View>
          ) : (
            <InfiniteLoading
              hasMore={hasMore}
              onLoadMore={reloadMore}
              loadingText={
                <View className="flex justify-center items-center py-4">
                  <Loading />
                  <View className="ml-2">加载中...</View>
                </View>
              }
              loadMoreText={
                displayList.length === 0 ? (
                  <View className="bg-white rounded-lg p-6">
                    <Empty description="暂无配送订单" />
                  </View>
                ) : (
                  <View className="text-center py-4 text-gray-500">没有更多了</View>
                )
              }
            >
              {displayList.map(o => {
                const qty = Number(o.totalNum || 0)
                const timeText = o.createTime ? dayjs(o.createTime).format('YYYY-MM-DD HH:mm') : '-'
                const addr = o.address || (o.addressId ? `地址ID：${o.addressId}` : '-')
                const remark = o.buyerRemarks || o.comments || ''
                const ticketNo = o.userTicketId || '-'

                const flow1Done = !!o.riderId
                const flow2Done =
                  !!o.sendStartTime || (typeof o.deliveryStatus === 'number' && o.deliveryStatus >= 20)
                const flow3Done =
                  !!o.sendEndTime || (typeof o.deliveryStatus === 'number' && o.deliveryStatus >= 30)
                const flow4Done = !!o.receiveConfirmTime || o.deliveryStatus === 40

                const phoneToCall = o.phone
                const storePhone = o.storePhone
                const pickupName = o.warehouseName || o.storeName
                const pickupAddr = o.warehouseAddress || o.storeAddress

                return (
                  <Cell key={String(o.id)} style={{ padding: '16px' }}>
                    <View className="w-full">
                      <View className="flex justify-between items-center">
                        <Text className="text-gray-800 font-bold text-sm">{`订单#${o.id}`}</Text>
                        <Text className={`${getOrderStatusColor(o)} text-sm font-medium`}>{getOrderStatusText(o)}</Text>
                      </View>

                      <View className="text-gray-400 text-xs mt-1">下单时间：{timeText}</View>
                      <View className="text-gray-400 text-xs mt-1">票号：{ticketNo}</View>

                      <View className="mt-3 bg-white rounded-lg">
                        <View className="text-sm text-gray-700">
                          <Text className="text-gray-500">收货地址：</Text>
                          <Text>{addr}</Text>
                        </View>
                        <View className="text-sm text-gray-700 mt-1">
                          <Text className="text-gray-500">客户：</Text>
                          <Text>
                            {o.nickname || '-'} {o.phone ? `(${o.phone})` : ''}
                          </Text>
                        </View>
                        <View className="text-sm text-gray-700 mt-1">
                          <Text className="text-gray-500">取货点：</Text>
                          <Text>{pickupName || '-'}</Text>
                        </View>
                        {pickupAddr ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">取货地址：</Text>
                            <Text>{pickupAddr}</Text>
                          </View>
                        ) : null}
                        <View className="text-sm text-gray-700 mt-1">
                          <Text className="text-gray-500">预约配送：</Text>
                          <Text>{o.sendTime ? dayjs(o.sendTime).format('YYYY-MM-DD HH:mm') : '-'}</Text>
                        </View>
                        <View className="text-sm text-gray-700 mt-1">
                          <Text className="text-gray-500">数量：</Text>
                          <Text>{qty || '-'}</Text>
                          <Text className="text-gray-500 ml-3">门店：</Text>
                          <Text>{o.storeName || '-'}</Text>
                        </View>
                        {o.storePhone ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">门店电话：</Text>
                            <Text>{o.storePhone}</Text>
                          </View>
                        ) : null}
                        {remark ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">备注：</Text>
                            <Text>{remark}</Text>
                          </View>
                        ) : null}
                        {o.sendStartTime ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">开始配送：</Text>
                            <Text>{dayjs(o.sendStartTime).format('YYYY-MM-DD HH:mm')}</Text>
                          </View>
                        ) : null}
                        {o.sendEndTime ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">送达时间：</Text>
                            <Text>{dayjs(o.sendEndTime).format('YYYY-MM-DD HH:mm')}</Text>
                          </View>
                        ) : null}
                        {o.receiveConfirmTime ? (
                          <View className="text-sm text-gray-700 mt-1">
                            <Text className="text-gray-500">确认收货：</Text>
                            <Text>{dayjs(o.receiveConfirmTime).format('YYYY-MM-DD HH:mm')}</Text>
                          </View>
                        ) : null}
                        {o.sendEndImg ? (
                          <View className="text-sm text-gray-700 mt-2">
                            <Text className="text-gray-500">送达照片：</Text>
                            <View className="mt-2">
                              <Image src={o.sendEndImg} width="100%" height="120" />
                            </View>
                          </View>
                        ) : null}
                      </View>

                      {/* 配送流程 */}
                      <View className="mt-3 bg-gray-50 rounded-lg p-2 text-xs">
                        <Text className="text-gray-600">流程：</Text>
                        <Text className={flow1Done ? 'text-green-600 font-medium' : 'text-gray-400'}>1 派单</Text>
                        <Text className="mx-1 text-gray-400">{'>'}</Text>
                        <Text className={flow2Done ? 'text-blue-600 font-medium' : 'text-gray-400'}>2 配送中</Text>
                        <Text className="mx-1 text-gray-400">{'>'}</Text>
                        <Text className={flow3Done ? 'text-purple-600 font-medium' : 'text-gray-400'}>3 送达留档</Text>
                        <Text className="mx-1 text-gray-400">{'>'}</Text>
                        <Text className={flow4Done ? 'text-green-600 font-medium' : 'text-gray-400'}>4 完成</Text>
                      </View>

                      <View className="mt-3 flex justify-end">
                        <Space>
                          {!!phoneToCall && (
                            <Button
                              size="small"
                              onClick={e => {
                                e.stopPropagation()
                                Taro.makePhoneCall({ phoneNumber: phoneToCall })
                              }}
                            >
                              联系客户
                            </Button>
                          )}
                          {!!addr && addr !== '-' && (
                            <Button
                              size="small"
                              onClick={e => {
                                e.stopPropagation()
                                void Taro.setClipboardData({ data: addr })
                                Taro.showToast({ title: '地址已复制', icon: 'none' })
                              }}
                            >
                              复制地址
                            </Button>
                          )}
                          {!!storePhone && (
                            <Button
                              size="small"
                              onClick={e => {
                                e.stopPropagation()
                                Taro.makePhoneCall({ phoneNumber: storePhone })
                              }}
                            >
                              联系门店
                            </Button>
                          )}
                          {canStartDeliver(o) && (
                            <Button
                              size="small"
                              onClick={e => {
                                e.stopPropagation()
                                void handleStartDeliver(o)
                              }}
                            >
                              开始配送
                            </Button>
                          )}
                          {canConfirmDelivered(o) && (
                            <Button
                              size="small"
                              type="primary"
                              onClick={e => {
                                e.stopPropagation()
                                openDeliverDialog(o, { mode: 'waitCustomerConfirm' })
                              }}
                            >
                              确认送达
                            </Button>
                          )}
                          {canCompleteByPhoto(o) && (
                            <Button
                              size="small"
                              type="primary"
                              onClick={e => {
                                e.stopPropagation()
                                openDeliverDialog(o, { mode: 'photoComplete' })
                              }}
                            >
                              补传照片完成
                            </Button>
                          )}
                        </Space>
                      </View>
                    </View>
                  </Cell>
                )
              })}
            </InfiniteLoading>
          )}
        </PullToRefresh>
      </View>

      <Dialog
        title="确认送达"
        visible={deliverDialogVisible}
        confirmText={
          deliverSubmitting
            ? '提交中...'
            : deliverConfirmMode === 'photoComplete'
              ? '拍照完成'
              : '确认送达'
        }
        cancelText="取消"
        onConfirm={handleConfirmDelivered}
        onCancel={() => {
          if (deliverSubmitting) return
          setDeliverDialogVisible(false)
          setDeliverOrder(null)
          setDeliverImg(undefined)
          setDeliverConfirmMode('photoComplete')
        }}
      >
        <View className="text-sm text-gray-700">
          <View>到达收货点后，可选择“拍照留档直接完成”或“等待客户确认收货”。</View>

          <View className="mt-3">
            <RadioGroup value={deliverConfirmMode} onChange={v => setDeliverConfirmMode(v as DeliverConfirmMode)}>
              <Radio value="photoComplete">拍照留档（直接完成）</Radio>
              <Radio value="waitCustomerConfirm">客户确认收货（可不拍照）</Radio>
            </RadioGroup>
          </View>
          <View className="mt-3">
            <Button size="small" onClick={handleChooseDeliverImg}>
              {deliverImg ? '重新拍照/上传' : '拍照/上传'}
            </Button>
          </View>
          {deliverImg && (
            <View className="mt-3">
              <Image src={deliverImg} width="100%" height="120" />
              <View className="mt-2 flex justify-end">
                <Button size="small" onClick={() => setDeliverImg(undefined)}>
                  移除照片
                </Button>
              </View>
            </View>
          )}
          <View className="mt-3 text-xs text-gray-500">
            说明：如选择“客户确认收货”，订单进入“待客户确认”；客户在用户端确认收货或超时自动确认（需后端支持）。
          </View>
        </View>
      </Dialog>
    </View>
  )
}
