<!-- eslint-disable vue/no-v-html -->
<template>
  <div class="container">
    <a-typography-title style="text-align: center">
      订单明细查询
    </a-typography-title>
    <a-row>
      <a-input-search
        size="large"
        :loading="loading"
        :disabled="loading"
        placeholder="输入待查询的商户订单号"
        search-button
        @search="search"
      >
        <template #button-icon>
          <icon-search />
        </template>
        <template #button-default>查询</template>
      </a-input-search>
    </a-row>
    <div class="body">
      <a-space direction="vertical" fill>
        <a-typography-title
          v-show="renderData?.list?.length"
          :heading="5"
          style="text-align: center"
        >
          查询结果
        </a-typography-title>
        <a-descriptions
          v-show="renderData.createTime || loading"
          title="订单信息"
          :column="isMobile ? 1 : 2"
          layout="horizontal"
          :label-style="{ width: '100px' }"
          :size="isMobile ? 'small' : 'medium'"
        >
          <a-descriptions-item label="平台订单号">
            <a-skeleton v-if="loading" :animation="true">
              <a-skeleton-shape />
            </a-skeleton>
            <a-tag v-else>{{ state.value }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="系统订单号">
            <a-skeleton v-if="loading" :animation="true">
              <a-skeleton-shape />
            </a-skeleton>
            <a-tag v-else>{{ renderData.bankOrderId }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="订单时间">
            <a-skeleton v-if="loading" :animation="true">
              <a-skeleton-shape />
            </a-skeleton>
            <a-tag v-else>{{ renderData.createTime }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="订单金额">
            <a-skeleton v-if="loading" :animation="true">
              <a-skeleton-shape />
            </a-skeleton>
            <a-tag v-else>{{ renderData.amount }}</a-tag>
          </a-descriptions-item>
        </a-descriptions>

        <!-- 总结区域 -->
        <div v-show="renderData?.list?.length || summaryLoading">
          <a-divider />
          <a-space direction="vertical" fill>
            <a-typography-title :heading="5" style="text-align: center">
              订单总结
            </a-typography-title>

            <!-- 总结加载状态 -->
            <div
              v-if="summaryLoading"
              style="text-align: center; padding: 20px 0"
            >
              <a-space direction="vertical" align="center" size="large">
                <a-spin size="large" />
                <a-typography-text type="secondary">
                  正在生成订单总结，请稍候...
                </a-typography-text>
                <a-typography-text type="secondary" class="loading-hint">
                  此过程可能需要较长时间，感谢您的耐心等待
                </a-typography-text>
              </a-space>
            </div>

            <!-- 总结内容 -->
            <a-card
              v-else-if="summaryData?.message"
              :bordered="false"
              style="background-color: var(--color-fill-2)"
            >
              <!-- 实时生成状态提示 -->
              <div
                v-if="isTyping"
                style="text-align: right; margin-bottom: 8px"
              >
                <a-tag color="green" size="small">
                  <icon-sync />
                  实时生成中
                </a-tag>
              </div>

              <div
                class="summary-content"
                style="margin: 0; line-height: 1.6"
                v-html="formattedSummaryHtml"
              ></div>
              <span v-if="isTyping" class="typing-cursor">|</span>
            </a-card>
          </a-space>
        </div>

        <!-- 详细记录分割线 -->
        <a-divider v-show="renderData?.list?.length">详细记录</a-divider>

        <template v-if="loading && renderData?.list?.length">
          <a-skeleton v-for="n in 3" :key="`skeleton-${n}`" :animation="true">
            <a-skeleton-line :line-height="24" />
          </a-skeleton>
        </template>
        <a-typography-paragraph
          v-for="(item, index) in renderData?.list"
          v-else
          :key="index"
        >
          【{{ item.createdAt }}】{{ item.operation }} {{ item.remark }}
        </a-typography-paragraph>
        <a-typography-paragraph
          v-show="!renderData?.list?.length && !loading"
          style="text-align: center"
        >
          {{ state.value ? '没有查询到结果' : '请输入查询条件' }}
        </a-typography-paragraph>
        <a-space
          v-show="loading && !renderData?.list?.length"
          direction="vertical"
          align="center"
          size="large"
        >
          <a-spin size="large" />
          <a-typography-text type="secondary">正在查询</a-typography-text>
        </a-space>
      </a-space>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { apiClient } from '@/api';
import { KamiApiMerchantV1OrderQueryRes } from '@/api/generated';

// 定义总结数据的类型
interface OrderSummaryRes {
  message?: string;
}
import useLoading from '@/hooks/loading';
import { Message } from '@arco-design/web-vue';
import DOMPurify from 'dompurify';
import { marked } from 'marked';
import { onUnmounted, reactive, ref, computed } from 'vue';

const renderData = ref<KamiApiMerchantV1OrderQueryRes>({});
const summaryData = ref<OrderSummaryRes | null>(null);
const { loading, setLoading } = useLoading(false);
const { loading: summaryLoading, setLoading: setSummaryLoading } =
  useLoading(false);
const state = reactive({
  value: ''
});

// 响应式检测移动端
const isMobile = computed(() => {
  if (typeof window === 'undefined') return false;
  return window.innerWidth <= 768;
});

// 存储 SSE 连接实例，用于清理
const currentEventSource = ref<EventSource | null>(null);

// 打字机状态管理
const isTyping = ref(false); // 是否正在流式接收数据
const hasStartedTyping = ref(false); // 是否已经开始打字机效果

// 配置 marked 选项
marked.setOptions({
  breaks: true, // 支持换行
  gfm: true // 启用 GitHub Flavored Markdown
});

// 同步版本的格式化函数（用于流式显示）
const formatSummaryTextSync = (text: string): string => {
  if (!text) return '';

  try {
    // 使用同步版本的 marked
    const html = marked.parse(text) as string;
    // 使用 DOMPurify 清理 HTML，只允许安全的标签
    return DOMPurify.sanitize(html, {
      ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'b', 'i', 'ul', 'ol', 'li'],
      ALLOWED_ATTR: []
    });
  } catch (error) {
    console.error('Markdown 解析错误:', error);
    // 降级处理：返回纯文本，只处理基本格式并清理
    const basicHtml = text
      .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // 粗体
      .replace(/\*(.*?)\*/g, '<em>$1</em>') // 斜体
      .replace(/\n/g, '<br>'); // 换行

    return DOMPurify.sanitize(basicHtml, {
      ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'b', 'i'],
      ALLOWED_ATTR: []
    });
  }
};

// 计算属性：格式化后的总结内容
// 使用 DOMPurify 清理后的 HTML，确保安全
const formattedSummaryHtml = computed(() => {
  return summaryData.value?.message
    ? formatSummaryTextSync(summaryData.value.message)
    : '';
});

const fetchSummary = async (merchantOrderNo: string) => {
  if (!merchantOrderNo) return;

  // 清理之前的连接
  if (currentEventSource.value) {
    currentEventSource.value.close();
    currentEventSource.value = null;
  }

  try {
    setSummaryLoading(true);
    summaryData.value = null;
    isTyping.value = false;
    hasStartedTyping.value = false;

    // 创建 SSE 连接
    const baseUrl = import.meta.env.VITE_API_BASE_URL;
    const sseUrl = `${baseUrl}/api/merchant/order/summary?merchantOrderNo=${encodeURIComponent(merchantOrderNo)}`;

    const eventSource = new EventSource(sseUrl);
    currentEventSource.value = eventSource;

    eventSource.onopen = () => {
      console.log('SSE 连接已建立');
    };

    eventSource.onmessage = event => {
      try {
        console.log('收到 SSE 数据:', event.data);

        // EventSource 会自动处理 "data: " 前缀，event.data 已经是解析后的内容
        // 直接解析 JSON
        const data = JSON.parse(event.data);

        if (data.content) {
          // 第一次接收到数据，开始打字机效果
          if (!hasStartedTyping.value) {
            hasStartedTyping.value = true;
            isTyping.value = true;
            setSummaryLoading(false); // 结束 loading 状态
            summaryData.value = { message: data.content };
          } else {
            // 累积流式数据
            summaryData.value.message += data.content;
          }
        }

        // 检查是否完成 - 根据新的格式可能需要调整
        if (data.complete || data.finished || data.done) {
          eventSource.close();
          currentEventSource.value = null;
          isTyping.value = false; // 停止打字机效果
        }
      } catch (parseError) {
        console.error(
          '解析 SSE 数据失败:',
          parseError,
          '原始数据:',
          event.data
        );
      }
    };

    eventSource.onerror = error => {
      console.error('SSE 连接错误:', error);
      eventSource.close();
      currentEventSource.value = null;
      setSummaryLoading(false);
      isTyping.value = false;
      hasStartedTyping.value = false;

      // 如果没有收到任何数据，显示错误提示
      if (!summaryData.value?.message) {
        Message.warning('订单总结获取失败，请稍后重试');
      }
    };

    // 设置超时
    setTimeout(() => {
      if (eventSource.readyState !== EventSource.CLOSED) {
        eventSource.close();
        currentEventSource.value = null;
        setSummaryLoading(false);
        isTyping.value = false;
        hasStartedTyping.value = false;
        console.log('SSE 连接超时');
        if (!summaryData.value?.message) {
          Message.warning('订单总结获取超时，请稍后重试');
        }
      }
    }, 30000); // 30秒超时
  } catch (error) {
    console.error('建立 SSE 连接失败:', error);
    setSummaryLoading(false);
    currentEventSource.value = null;
    isTyping.value = false;
    hasStartedTyping.value = false;
    Message.warning('订单总结获取失败，请稍后重试');
  }
};

// 组件卸载时清理 SSE 连接
onUnmounted(() => {
  if (currentEventSource.value) {
    currentEventSource.value.close();
    currentEventSource.value = null;
  }
});

const search = async (value: string) => {
  try {
    state.value = value;
    setLoading(true);

    // 重置总结数据
    summaryData.value = null;

    // 只查询订单详情
    const data = await apiClient.apiMerchantOrderQueryGet({
      merchantOrderNo: value
    });

    renderData.value = data.data;

    // 如果有订单数据，异步获取总结
    if (data.data?.list?.length) {
      fetchSummary(value);
    }
  } catch (error) {
    Message.error('查询失败，请重试');
  } finally {
    setLoading(false);
  }
};
</script>

<style lang="less" scoped>
.container {
  @keyframes blink {
    0%,
    50% {
      opacity: 1;
    }

    51%,
    100% {
      opacity: 0;
    }
  }

  max-width: 800px;
  padding: 200px 20px;
  margin: 0 auto;

  // 手机端优化
  @media (width <= 768px) {
    padding: 120px 16px;

    .body {
      padding: 16px;
      margin-top: 16px;
      min-height: calc(100vh - 400px);
    }

    // 优化描述列表在手机端的显示
    :deep(.arco-descriptions) {
      .arco-descriptions-title {
        font-size: 16px;
        margin-bottom: 16px;
      }

      .arco-descriptions-item {
        padding: 8px 0;

        &-label {
          width: 80px !important;
          font-size: 13px;
        }

        &-value {
          font-size: 13px;
        }
      }

      // 强制手机端使用单列布局
      &.arco-descriptions-layout-horizontal {
        .arco-descriptions-item {
          display: block;
          margin-bottom: 12px;
          width: 100% !important;
          flex-basis: 100% !important;
        }

        // 覆盖两列布局的 grid 样式
        &.arco-descriptions-size-medium .arco-descriptions-item,
        &.arco-descriptions-size-small .arco-descriptions-item {
          grid-column: 1 / -1;
          width: 100% !important;
        }
      }

      // 确保手机端始终是一列
      &.arco-descriptions-column-2 {
        .arco-descriptions-item {
          grid-column: 1 / -1;
          width: 100% !important;
        }
      }
    }

    // 总结区域手机端优化
    :deep(.arco-card) {
      .arco-card-body {
        padding: 16px;
      }

      .arco-typography {
        font-size: 14px;
        line-height: 1.6;
      }
    }

    // 分割线间距优化
    :deep(.arco-divider) {
      margin: 16px 0;
    }

    // 标题字体大小优化
    :deep(.arco-typography) {
      &.arco-typography-title-h5 {
        font-size: 16px;
        margin: 16px 0;
      }

      &.arco-typography-title {
        font-size: 20px;
        margin: 24px 0 16px;
      }
    }

    // 记录列表手机端优化
    :deep(.arco-typography-paragraph) {
      margin: 8px 0;
      font-size: 14px;
      line-height: 1.5;
      word-break: break-all;
    }

    // 加载动画区域手机端优化
    :deep(.arco-spin) {
      .arco-spin-icon {
        font-size: 20px;
      }
    }

    // 输入框手机端优化
    :deep(.arco-input-search) {
      .arco-input-wrapper {
        height: 44px;
        font-size: 16px; // iOS 防止缩放
      }

      .arco-input-search-btn {
        height: 44px;
        padding: 0 16px;
      }
    }

    // 加载提示文字响应式样式
    .loading-hint {
      font-size: 12px;
      line-height: 1.4;
    }
  }

  // 超小屏手机优化
  @media (width <= 480px) {
    padding: 100px 12px;

    .body {
      padding: 12px;
    }

    :deep(.arco-descriptions) {
      .arco-descriptions-item-label {
        width: 70px !important;
        font-size: 12px;
      }

      .arco-descriptions-item-value {
        font-size: 12px;
      }
    }

    :deep(.arco-typography-paragraph) {
      font-size: 13px;
    }
  }

  // 流式输入光标动画
  .typing-cursor {
    display: inline-block;
    width: 2px;
    height: 1.2em;
    background-color: var(--color-primary);
    margin-left: 2px;
    animation: blink 1s infinite;
    vertical-align: text-bottom;
  }

  // 格式化总结内容样式
  .summary-content {
    p {
      margin: 0 0 8px;

      &:last-child {
        margin-bottom: 0;
      }
    }

    strong {
      font-weight: 600;
      color: var(--color-text-1);
    }
  }

  :deep(.arco-input-wrapper) {
    background-color: var(--color-white);

    .arco-input {
      background-color: var(--color-white);
    }
  }

  .body {
    min-height: calc(100vh - 600px);
    padding: 20px;
    margin-top: 20px;
    background-color: var(--color-white);
  }
}
</style>
