import { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Alert,
  Button,
  Descriptions,
  Drawer,
  Empty,
  Image,
  Space,
  Spin,
  Timeline,
  Typography,
  message,
} from 'antd';
import type { OrderTrackDto, OrderTrackNodeDto } from '@dukang/shared-types';
import { isXfxProviderCode } from '@dukang/shared-types';
import { request } from '../lib/api';
import { DELIVERY_PROVIDER_LABELS, fmtTime } from '../lib/constants';

type Props = {
  open: boolean;
  orderId: string | null;
  orderNo?: string | null;
  orderStatus?: string | null;
  onClose: () => void;
};

function providerLabel(provider?: string | null, company?: string | null) {
  if (company) return company;
  if (!provider) return '—';
  if (DELIVERY_PROVIDER_LABELS[provider]) return DELIVERY_PROVIDER_LABELS[provider];
  if (isXfxProviderCode(provider)) return '小飞侠';
  return provider;
}

function sortOldestFirst(nodes: OrderTrackNodeDto[]) {
  return [...nodes].sort((a, b) => {
    const ta = new Date(a.createTime).getTime();
    const tb = new Date(b.createTime).getTime();
    if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;
    if (Number.isNaN(ta)) return 1;
    if (Number.isNaN(tb)) return -1;
    return ta - tb;
  });
}

export default function OrderTrackDrawer({
  open,
  orderId,
  orderNo,
  orderStatus,
  onClose,
}: Props) {
  const [loading, setLoading] = useState(false);
  const [track, setTrack] = useState<OrderTrackDto | null>(null);

  const load = useCallback(async () => {
    if (!orderId) return;
    setLoading(true);
    try {
      const data = await request<OrderTrackDto>(`/admin/orders/${orderId}/track`);
      setTrack(data);
    } catch (e) {
      setTrack(null);
      message.error(e instanceof Error ? e.message : '加载路由失败');
    } finally {
      setLoading(false);
    }
  }, [orderId]);

  useEffect(() => {
    if (!open || !orderId) {
      setTrack(null);
      return;
    }
    void load();
  }, [open, orderId, load]);

  const nodes = useMemo(
    () => (track?.nodes?.length ? sortOldestFirst(track.nodes) : []),
    [track?.nodes],
  );
  const timelineComplete = ['PENDING_RECEIVE', 'DELIVERED', 'COMPLETED'].includes(
    orderStatus || '',
  );

  return (
    <Drawer
      title="物流路由"
      width={520}
      open={open}
      onClose={onClose}
      extra={
        <Button onClick={() => void load()} loading={loading} disabled={!orderId}>
          刷新
        </Button>
      }
    >
      <Spin spinning={loading}>
        {(orderNo || track?.trackingNo || track?.provider) && (
          <Descriptions column={1} bordered size="small" style={{ marginBottom: 16 }}>
            {orderNo ? <Descriptions.Item label="订单号">{orderNo}</Descriptions.Item> : null}
            <Descriptions.Item label="配送方式">
              {providerLabel(track?.provider, track?.logisticsCompany)}
            </Descriptions.Item>
            <Descriptions.Item label="运单号">{track?.trackingNo || '—'}</Descriptions.Item>
            {track?.manualQueryUrl ? (
              <Descriptions.Item label="物流查询">
                <a href={track.manualQueryUrl} target="_blank" rel="noreferrer">
                  打开物流查询
                </a>
              </Descriptions.Item>
            ) : null}
            {track?.estimatedArrival?.arriveTime ? (
              <Descriptions.Item label="预计送达">
                {fmtTime(track.estimatedArrival.arriveTime)}
                {track.estimatedArrival.siteName
                  ? `（${track.estimatedArrival.siteName}）`
                  : ''}
              </Descriptions.Item>
            ) : null}
          </Descriptions>
        )}

        {track?.signPhotoUrls && track.signPhotoUrls.length > 0 ? (
          <div style={{ marginBottom: 16 }}>
            <Typography.Title level={5} style={{ marginTop: 0 }}>
              签收照片
            </Typography.Title>
            <Image.PreviewGroup>
              <Space wrap>
                {track.signPhotoUrls.map((url) => (
                  <Image
                    key={url}
                    src={url}
                    width={96}
                    height={96}
                    style={{ objectFit: 'cover', borderRadius: 6 }}
                  />
                ))}
              </Space>
            </Image.PreviewGroup>
          </div>
        ) : nodes.some((n) => n.statusName?.includes('签收') || n.trackInfo?.includes('签收')) ? (
          <Alert
            type="info"
            showIcon
            style={{ marginBottom: 16 }}
            message="暂无签收照片"
            description="小飞侠 100108 未返回图片（可能是本人签收未拍照，或照片已过期）。可在「小飞侠联调」用运单号复测。"
          />
        ) : null}

        <Typography.Title level={5} style={{ marginTop: 0 }}>
          物流动态
        </Typography.Title>
        {nodes.length > 0 ? (
          <Timeline
            items={nodes.map((node, index) => {
              const isLatest = index === nodes.length - 1;
              return {
                color: isLatest ? (timelineComplete ? 'green' : 'blue') : 'gray',
                children: (
                  <div>
                    {node.statusName ? (
                      <Typography.Text strong style={{ display: 'block' }}>
                        {node.statusName}
                      </Typography.Text>
                    ) : null}
                    <Typography.Text style={{ display: 'block', whiteSpace: 'pre-wrap' }}>
                      {node.trackInfo || '—'}
                    </Typography.Text>
                    <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                      {fmtTime(node.createTime)}
                    </Typography.Text>
                  </div>
                ),
              };
            })}
          />
        ) : (
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description={
              track?.queryError
                ? track.queryError
                : track?.manualQueryUrl
                ? '暂无实时路由节点，可使用上方物流查询链接'
                : '暂无路由信息，请稍后刷新'
            }
          />
        )}
      </Spin>
    </Drawer>
  );
}
