import { useRef, useState } from 'react';
import Taro, { useDidShow } from '@tarojs/taro';
import {
  Button,
  ConfigProvider,
  Empty,
  InfiniteLoading,
  Loading,
  Popup,
  PullToRefresh,
  SearchBar,
  Tabs,
  TabPane,
  Tag
} from '@nutui/nutui-react-taro';
import { View, Text, Image } from '@tarojs/components';
import { pageGltUserTicket } from '@/api/glt/gltUserTicket';
import type { GltUserTicket } from '@/api/glt/gltUserTicket/model';
import { pageGltTicketOrder, updateGltTicketOrder } from '@/api/glt/gltTicketOrder';
import type { GltTicketOrder } from '@/api/glt/gltTicketOrder/model';
import { getShopUserAddress } from '@/api/shop/shopUserAddress';
import { BaseUrl } from '@/config/app';
import dayjs from "dayjs";

const PAGE_SIZE = 10;

const UserTicketList = () => {
  const [ticketList, setTicketList] = useState<GltUserTicket[]>([]);
  const [ticketLoading, setTicketLoading] = useState(false);
  const [ticketHasMore, setTicketHasMore] = useState(true);
  const [searchValue, setSearchValue] = useState('');
  const [ticketPage, setTicketPage] = useState(1);
  const [ticketTotal, setTicketTotal] = useState(0);

  const [orderList, setOrderList] = useState<GltTicketOrder[]>([]);
  const [orderLoading, setOrderLoading] = useState(false);
  const [orderHasMore, setOrderHasMore] = useState(true);
  const [orderPage, setOrderPage] = useState(1);
  const [orderTotal, setOrderTotal] = useState(0);

  const [activeTab, setActiveTab] = useState<'ticket' | 'order'>(() => {
    const tab = Taro.getCurrentInstance().router?.params?.tab
    return tab === 'order' ? 'order' : 'ticket'
  });

  const [qrVisible, setQrVisible] = useState(false);
  const [qrTicket, setQrTicket] = useState<GltUserTicket | null>(null);
  const [qrImageUrl, setQrImageUrl] = useState('');

  const addressCacheRef = useRef<Record<number, { lng: number; lat: number; fullAddress?: string } | null>>({});

  const getUserId = () => {
    const raw = Taro.getStorageSync('UserId');
    const id = Number(raw);
    return Number.isFinite(id) && id > 0 ? id : undefined;
  };

  const buildTicketQrContent = (ticket: GltUserTicket) => {
    // QR will be encrypted by `/qr-code/create-encrypted-qr-image`,
    // and decrypted on verifier side to get this payload.
    return JSON.stringify({
      userTicketId: ticket.id,
      qty: 1,
      userId: ticket.userId,
      t: Date.now()
    });
  };

  const buildEncryptedQrImageUrl = (businessType: string, data: string) => {
    const size = '300x300';
    const expireMinutes = 30;
    const base = BaseUrl?.replace(/\/+$/, '');
    return `${base}/qr-code/create-encrypted-qr-image?size=${encodeURIComponent(
      size
    )}&expireMinutes=${encodeURIComponent(String(expireMinutes))}&businessType=${encodeURIComponent(
      businessType
    )}&data=${encodeURIComponent(data)}`;
  };

  const openTicketQr = (ticket: GltUserTicket) => {
    if (!ticket?.id) {
      Taro.showToast({ title: '水票信息不完整', icon: 'none' });
      return;
    }
    if (ticket.status === 1) {
      Taro.showToast({ title: '该水票已冻结，无法核销', icon: 'none' });
      return;
    }
    if ((ticket.availableQty ?? 0) <= 0) {
      Taro.showToast({ title: '可用次数不足', icon: 'none' });
      return;
    }

    const content = buildTicketQrContent(ticket);
    setQrTicket(ticket);
    setQrImageUrl(buildEncryptedQrImageUrl('ticket', content));
    setQrVisible(true);
  };

  const showTicketDetail = (ticket: GltUserTicket) => {
    const lines: string[] = [];
    if (ticket.templateName) lines.push(`水票：${ticket.templateName}`);
    lines.push(`可用：${ticket.availableQty ?? 0}`);
    lines.push(`总量：${ticket.totalQty ?? 0}`);
    lines.push(`已用：${ticket.usedQty ?? 0}`);
    lines.push(`冻结：${ticket.frozenQty ?? 0}`);
    lines.push(`已释放：${ticket.releasedQty ?? 0}`);
    if (ticket.orderNo) lines.push(`订单号：${ticket.orderNo}`);
    // Taro.showModal({
    //   title: '水票详情',
    //   content: lines.join('\n'),
    //   showCancel: false
    // });
  };

  const reloadTickets = async (isRefresh = true, keywords?: string) => {
    if (ticketLoading) return;

    const userId = getUserId();
    if (!userId) {
      setTicketList([]);
      setTicketTotal(0);
      setTicketHasMore(false);
      return;
    }

    if (isRefresh) {
      setTicketPage(1);
      setTicketList([]);
      setTicketHasMore(true);
    }

    setTicketLoading(true);
    try {
      const currentPage = isRefresh ? 1 : ticketPage;
      const res = await pageGltUserTicket({
        page: currentPage,
        limit: PAGE_SIZE,
        userId,
        keywords: (keywords ?? searchValue) || undefined
      });

      const nextList = isRefresh ? res.list : [...ticketList, ...res.list];
      setTicketList(nextList);
      const count = typeof res.count === 'number' ? res.count : nextList.length;
      setTicketTotal(count);
      setTicketHasMore(nextList.length < count);

      if (res.list.length > 0) {
        setTicketPage(currentPage + 1);
      } else {
        setTicketHasMore(false);
      }
    } catch (error) {
      console.error('获取水票列表失败:', error);
      Taro.showToast({ title: '获取水票失败', icon: 'error' });
      setTicketHasMore(false);
    } finally {
      setTicketLoading(false);
    }
  };

  const reloadOrders = async (isRefresh = true, keywords?: string) => {
    if (orderLoading) return;

    const userId = getUserId();
    if (!userId) {
      setOrderList([]);
      setOrderTotal(0);
      setOrderHasMore(false);
      return;
    }

    if (isRefresh) {
      setOrderPage(1);
      setOrderList([]);
      setOrderHasMore(true);
    }

    setOrderLoading(true);
    try {
      const currentPage = isRefresh ? 1 : orderPage;
      const res = await pageGltTicketOrder({
        page: currentPage,
        limit: PAGE_SIZE,
        userId,
        keywords: (keywords ?? searchValue) || undefined
      });

      const resList = res?.list || [];
      const nextList = isRefresh ? resList : [...orderList, ...resList];
      setOrderList(nextList);
      const count = typeof res?.count === 'number' ? res.count : nextList.length;
      setOrderTotal(count);
      setOrderHasMore(nextList.length < count);

      if (resList.length > 0) {
        setOrderPage(currentPage + 1);
      } else {
        setOrderHasMore(false);
      }
    } catch (error) {
      console.error('获取送水订单失败:', error);
      Taro.showToast({ title: '获取送水订单失败', icon: 'error' });
      setOrderHasMore(false);
    } finally {
      setOrderLoading(false);
    }
  };

  const handleSearch = (value: string) => {
    setSearchValue(value);
    if (activeTab === 'ticket') {
      reloadTickets(true, value);
    } else {
      reloadOrders(true, value);
    }
  };

  const handleRefresh = async () => {
    if (activeTab === 'ticket') {
      await reloadTickets(true);
    } else {
      await reloadOrders(true);
    }
  };

  const handleTabChange = (value: string | number) => {
    const tab = String(value) as 'ticket' | 'order';
    setActiveTab(tab);
    if (tab === 'ticket') {
      setTicketPage(1);
      setTicketList([]);
      setTicketHasMore(true);
      reloadTickets(true);
    } else {
      setOrderPage(1);
      setOrderList([]);
      setOrderHasMore(true);
      reloadOrders(true);
    }
  };

  const loadMoreTickets = async () => {
    if (!ticketLoading && ticketHasMore) {
      await reloadTickets(false);
    }
  };

  const loadMoreOrders = async () => {
    if (!orderLoading && orderHasMore) {
      await reloadOrders(false);
    }
  };

  const formatDateTime = (v?: string) => {
    if (!v) return '-';
    const d = dayjs(v);
    return d.isValid() ? d.format('YYYY年MM月DD日 HH:mm:ss') : v;
  };

  const formatDate = (v?: string) => {
    if (!v) return '-';
    const d = dayjs(v);
    return d.isValid() ? d.format('YYYY年MM月DD日') : v;
  };

  const parseLatLng = (latRaw?: unknown, lngRaw?: unknown) => {
    const lat = typeof latRaw === 'number' ? latRaw : parseFloat(String(latRaw ?? ''));
    const lng = typeof lngRaw === 'number' ? lngRaw : parseFloat(String(lngRaw ?? ''));
    if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;
    if (Math.abs(lat) > 90 || Math.abs(lng) > 180) return null;
    return { lat, lng };
  };

  const handleNavigateToAddress = async (order: GltTicketOrder) => {
    try {
      // Prefer coordinates from backend if present (non-typed fields), otherwise fetch by addressId.
      const anyOrder = order as any;
      const direct =
        parseLatLng(anyOrder?.addressLat ?? anyOrder?.lat, anyOrder?.addressLng ?? anyOrder?.lng) ||
        parseLatLng(anyOrder?.receiverLat, anyOrder?.receiverLng);

      let coords = direct;
      let fullAddress: string | undefined = order.address || undefined;

      if (!coords && order.addressId) {
        const cached = addressCacheRef.current[order.addressId];
        if (cached) {
          coords = { lat: cached.lat, lng: cached.lng };
          fullAddress = fullAddress || cached.fullAddress;
        } else if (cached === null) {
          coords = null;
        } else {
          const addr = await getShopUserAddress(order.addressId);
          const parsed = parseLatLng(addr?.lat, addr?.lng);
          if (parsed) {
            coords = parsed;
            fullAddress = fullAddress || addr?.fullAddress || addr?.address || undefined;
            addressCacheRef.current[order.addressId] = { ...parsed, fullAddress };
          } else {
            addressCacheRef.current[order.addressId] = null;
          }
        }
      }

      if (!coords) {
        if (fullAddress) {
          await Taro.setClipboardData({ data: fullAddress });
          Taro.showToast({ title: '未配置定位，地址已复制', icon: 'none' });
        } else {
          Taro.showToast({ title: '暂无可导航的地址', icon: 'none' });
        }
        return;
      }

      Taro.openLocation({
        latitude: coords.lat,
        longitude: coords.lng,
        name: '收货地址',
        address: fullAddress || ''
      });
    } catch (e) {
      console.error('一键导航失败:', e);
      Taro.showToast({ title: '导航失败，请重试', icon: 'none' });
    }
  };

  const handleOneClickCall = async (order: GltTicketOrder) => {
    const phone = (order.riderPhone || order.storePhone || '').trim();
    if (!phone) {
      Taro.showToast({ title: '暂无可呼叫的电话', icon: 'none' });
      return;
    }
    try {
      await Taro.makePhoneCall({ phoneNumber: phone });
    } catch (e) {
      console.error('一键呼叫失败:', e);
      Taro.showToast({ title: '呼叫失败，请手动拨打', icon: 'none' });
    }
  };

  const getTicketOrderStatusMeta = (order: GltTicketOrder) => {
    if (order.status === 1) return { text: '已冻结', type: 'warning' as const };

    const ds = order.deliveryStatus
    if (ds === 40 || order.receiveConfirmTime) return { text: '已完成', type: 'success' as const };
    if (ds === 30 || order.sendEndTime) return { text: '待确认收货', type: 'primary' as const };
    if (ds === 20 || order.sendStartTime) return { text: '配送中', type: 'primary' as const };
    if (ds === 10 || order.riderId) return { text: '待配送', type: 'warning' as const };
    return { text: '待派单', type: 'primary' as const };
  };

  const canUserConfirmReceive = (order: GltTicketOrder) => {
    if (!order?.id) return false
    if (order.status === 1) return false
    if (order.deliveryStatus === 40) return false
    if (order.receiveConfirmTime) return false
    // 必须是“已送达”后才能确认收货
    return !!order.sendEndTime || order.deliveryStatus === 30
  }

  const handleUserConfirmReceive = async (order: GltTicketOrder) => {
    if (!order?.id) return
    if (!canUserConfirmReceive(order)) return

    const modal = await Taro.showModal({
      title: '确认收货',
      content: '请确认已收到本次送水，确认后将无法撤销。',
      confirmText: '确认收货'
    })
    if (!modal.confirm) return

    try {
      Taro.showLoading({ title: '提交中...' })
      const now = dayjs().format('YYYY-MM-DD HH:mm:ss')
      await updateGltTicketOrder({
        id: order.id,
        deliveryStatus: 40,
        receiveConfirmTime: now,
        receiveConfirmType: 10
      })
      Taro.showToast({ title: '已确认收货', icon: 'success' })
      await reloadOrders(true)
    } catch (e) {
      console.error('确认收货失败:', e)
      Taro.showToast({ title: '确认失败，请重试', icon: 'none' })
    } finally {
      Taro.hideLoading()
    }
  }

  useDidShow(() => {
    if (activeTab === 'ticket') {
      reloadTickets(true).then();
    } else {
      reloadOrders(true).then();
    }
  });

  return (
    <ConfigProvider>
      {/* 搜索栏 */}
      <View className="bg-white px-4 py-3 hidden">
        <SearchBar
          placeholder="搜索水票"
          value={searchValue}
          onChange={setSearchValue}
          onSearch={handleSearch}
        />
      </View>

      {/* Tab切换 */}
      <View className="bg-white">
        <Tabs value={activeTab} onChange={handleTabChange}>
          <TabPane title="我的水票" value="ticket"></TabPane>
          <TabPane title="送水订单" value="order"></TabPane>
        </Tabs>
      </View>

      {activeTab === 'ticket' && ticketTotal > 0 && (
        <View className="px-4 py-2 text-sm text-gray-500 bg-gray-50 hidden">
          共 {ticketTotal} 条水票记录
        </View>
      )}

      {activeTab === 'order' && orderTotal > 0 && (
        <View className="px-4 py-2 text-sm text-gray-500 bg-gray-50 hidden">
          共 {orderTotal} 条送水订单
        </View>
      )}

      {/* 列表 */}
      <PullToRefresh onRefresh={handleRefresh} headHeight={60}>
        <View style={{ height: 'calc(100vh)', overflowY: 'auto' }} id="ticket-scroll">
          {activeTab === 'ticket' && ticketList.length === 0 && !ticketLoading ? (
            <View
              className="flex flex-col justify-center items-center"
              style={{ height: 'calc(100vh - 160px)' }}
            >
              <Empty
                description="暂无水票"
                style={{ backgroundColor: 'transparent' }}
              />
            </View>
          ) : activeTab === 'order' && orderList.length === 0 && !orderLoading ? (
            <View
              className="flex flex-col justify-center items-center"
              style={{ height: 'calc(100vh - 160px)' }}
            >
              <Empty description="暂无送水订单" style={{ backgroundColor: 'transparent' }} />
            </View>
          ) : activeTab === 'ticket' ? (
            <InfiniteLoading
              target="ticket-scroll"
              hasMore={ticketHasMore}
              onLoadMore={loadMoreTickets}
              loadingText={
                <View className="flex justify-center items-center py-4">
                  <Loading />
                  <View className="ml-2">加载中...</View>
                </View>
              }
              loadMoreText={
                <View className="text-center py-4 text-gray-500">
                  {ticketList.length === 0 ? '暂无数据' : '没有更多了'}
                </View>
              }
            >
              <View className="px-4 py-3">
                {ticketList.map((item, index) => (
                  <View
                    key={String(item.id ?? `${item.templateId ?? 't'}-${index}`)}
                    className="bg-white rounded-xl p-4 mb-3"
                    onClick={() => showTicketDetail(item)}
                  >
                    <View className="flex items-start justify-between">
                      <View className="flex-1 pr-3">
                        <Text className="text-base font-semibold text-gray-900">
                          票号：{item.id}
                        </Text>
                        {item.orderNo && (
                          <View className="mt-1">
                            <Text className="text-xs text-gray-500">订单编号：{item.orderNo}</Text>
                          </View>
                        )}
                        {item.createTime && (
                          <View className="mt-1">
                            <Text className="text-xs text-gray-400">下单时间：{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</Text>
                          </View>
                        )}
                      </View>
                      <View className="flex flex-col items-end gap-2 hidden">
                        {/*<Tag type={item.status === 1 ? 'danger' : 'success'}>*/}
                        {/*  {item.status === 1 ? '冻结' : '正常'}*/}
                        {/*</Tag>*/}
                        <Button
                          size="small"
                          type="primary"
                          disabled={(item.availableQty ?? 0) <= 0 || item.status === 1}
                          onClick={(e) => {
                            // Avoid triggering card click.
                            e.stopPropagation();
                            openTicketQr(item);
                          }}
                        >
                          出示核销码
                        </Button>
                      </View>
                    </View>

                    <View className="mt-3 flex justify-between">
                      <View className="flex flex-col items-center">
                        <Text className="text-lg font-bold text-blue-600 text-center">{item.availableQty ?? 0}</Text>
                        <Text className="text-xs text-gray-500">可用水票</Text>
                      </View>
                      <View className="flex flex-col items-center">
                        <Text className="text-lg text-gray-900 text-center">{item.usedQty ?? 0}</Text>
                        <Text className="text-xs text-gray-500">已用水票</Text>
                      </View>
                      <View className="flex flex-col items-center">
                        <Text className="text-lg text-gray-900 text-center">{item.frozenQty ?? 0}</Text>
                        <Text className="text-xs text-gray-500">剩余赠票</Text>
                      </View>
                    </View>
                  </View>
                ))}
              </View>
            </InfiniteLoading>
          ) : (
            <InfiniteLoading
              target="ticket-scroll"
              hasMore={orderHasMore}
              onLoadMore={loadMoreOrders}
              loadingText={
                <View className="flex justify-center items-center py-4">
                  <Loading />
                  <View className="ml-2">加载中...</View>
                </View>
              }
              loadMoreText={
                <View className="text-center py-4 text-gray-500">
                  {orderList.length === 0 ? '暂无数据' : '没有更多了'}
                </View>
              }
            >
              <View className="px-4 py-3">
                {orderList.map((item, index) => (
                  <View
                    key={String(item.id ?? `order-${index}`)}
                    className="bg-white rounded-xl p-4 mb-3"
                  >
                    <View className="flex items-start justify-between">
                      <View className="flex-1 pr-3">
                        <Text className="text-base font-semibold text-gray-900">
                          票号：{item.userTicketId ?? '-'}
                        </Text>
                        <View className="mt-1">
                          <Text className="text-xs text-gray-500">送水数量：{item.totalNum ?? 0}</Text>
                        </View>
                        <View className="mt-1">
                          <Text className="text-xs text-gray-500">配送时间：{formatDate(item.sendTime)}</Text>
                        </View>
                      </View>
                      {(() => {
                        const meta = getTicketOrderStatusMeta(item);
                        return <Tag type={meta.type}>{meta.text}</Tag>;
                      })()}
                    </View>
                    <View className="mt-2 text-xs text-gray-500">
                      <Text>订单号：{item.id ?? '-'}</Text>
                    </View>
                    <View className="mt-1 text-xs text-gray-500">
                      <Text>收货地址：{item.address || '-'}</Text>
                    </View>
                    <View className="mt-1">
                      <Text className="text-xs text-gray-500">下单时间：{formatDateTime(item.createTime)}</Text>
                    </View>
                    {(!!item.addressId || !!item.address || !!item.riderPhone || !!item.storePhone) ? (
                      <View className="mt-3 flex justify-end gap-2">
                        {(!!item.addressId || !!item.address) ? (
                          <Button
                            size="small"
                            onClick={(e) => {
                              e.stopPropagation();
                              void handleNavigateToAddress(item);
                            }}
                          >
                            一键导航
                          </Button>
                        ) : null}
                        {(!!item.riderPhone || !!item.storePhone) ? (
                          <Button
                            size="small"
                            onClick={(e) => {
                              e.stopPropagation();
                              void handleOneClickCall(item);
                            }}
                          >
                            一键呼叫
                          </Button>
                        ) : null}
                      </View>
                    ) : null}
                    {/*{item.storeName ? (*/}
                    {/*  <View className="mt-1 text-xs text-gray-500">*/}
                    {/*    <Text>门店：{item.storeName}</Text>*/}
                    {/*  </View>*/}
                    {/*) : null}*/}
                    {item.sendStartTime ? (
                      <View className="mt-1 text-xs text-gray-500">
                        <Text>开始配送：{formatDateTime(item.sendStartTime)}</Text>
                      </View>
                    ) : null}
                    {item.sendEndTime ? (
                      <View className="mt-1 text-xs text-gray-500">
                        <Text>送达时间：{formatDateTime(item.sendEndTime)}</Text>
                      </View>
                    ) : null}
                    {item.receiveConfirmTime ? (
                      <View className="mt-1 text-xs text-gray-500">
                        <Text>确认收货：{formatDateTime(item.receiveConfirmTime)}</Text>
                      </View>
                    ) : null}
                    {item.sendEndImg ? (
                      <View className="mt-3">
                        <Image src={item.sendEndImg} mode="aspectFill" style={{ width: '100%', height: '160px', borderRadius: '8px' }} />
                      </View>
                    ) : null}
                    {canUserConfirmReceive(item) ? (
                      <View className="mt-3 flex justify-end">
                        <Button
                          type="primary"
                          size="small"
                          onClick={() => handleUserConfirmReceive(item)}
                        >
                          确认收货
                        </Button>
                      </View>
                    ) : null}
                  </View>
                ))}
              </View>
            </InfiniteLoading>
          )}
        </View>
      </PullToRefresh>

      {/* 核销二维码 */}
      <Popup
        visible={qrVisible}
        position="center"
        closeable
        onClose={() => setQrVisible(false)}
        style={{ width: '90%' }}
      >
        <View className="p-6">
          <View className="mb-4">
            <Text className="text-lg font-bold">水票核销码</Text>
          </View>

          {qrTicket && (
            <View className="bg-gray-50 rounded-lg p-3 mb-4">
              <View className="flex justify-between mb-2">
                <Text className="text-sm text-gray-600">票号</Text>
                <Text className="text-sm text-gray-900">{qrTicket.id}</Text>
              </View>
              <View className="flex justify-between">
                <Text className="text-sm text-gray-600">可用次数</Text>
                <Text className="text-sm text-gray-900">{qrTicket.availableQty ?? 0}</Text>
              </View>
            </View>
          )}

          <View className="text-center mb-4">
            <View className="p-4 bg-white border border-gray-200 rounded-lg">
              {qrImageUrl ? (
                <View className="flex flex-col justify-center items-center">
                  <Image
                    src={qrImageUrl}
                    mode="aspectFit"
                    style={{ width: '200px', height: '200px' }}
                  />
                  <Text className="text-sm text-gray-400 mt-2 px-2">
                    请向配送员出示此二维码
                  </Text>
                </View>
              ) : (
                <View
                  className="bg-gray-100 rounded flex items-center justify-center mx-auto"
                  style={{ width: '200px', height: '200px' }}
                >
                  <Text className="text-gray-500 text-sm">生成中...</Text>
                </View>
              )}
            </View>
          </View>

          <Button
            type="primary"
            block
            onClick={() => {
              if (!qrTicket) return;
              const content = buildTicketQrContent(qrTicket);
              setQrImageUrl(buildEncryptedQrImageUrl('ticket', content));
            }}
          >
            刷新二维码
          </Button>
        </View>
      </Popup>
    </ConfigProvider>
  );
};

export default UserTicketList;
