// ---------- 模拟的外部服务 ----------
interface UserInfo { userId: string; email: string; vipLevel: 'VIP' | 'Normal'; }
interface ProductInfo { productId: string; price: number; stock: number; }
interface Order { orderId: string; userId: string; productId: string; finalPrice: number; status: 'Created' | 'Failed'; }

// 模拟用户服务 (可能失败)
async function fetchUserService(userId: string): Promise<UserInfo> {
  console.log(`[服务] 获取用户 ${userId} 信息...`);
  await new Promise(res => setTimeout(res, 50)); // 模拟网络延迟
  if (Math.random() < 0.1) { // 10% 概率失败
    throw new Error('用户服务暂时不可用');
  }
  return { userId, email: `${userId}@test.com`, vipLevel: Math.random() > 0.5 ? 'VIP' : 'Normal' };
}

// 模拟商品服务 (可能失败)
async function fetchProductService(productId: string): Promise<ProductInfo> {
  console.log(`[服务] 获取商品 ${productId} 信息...`);
  await new Promise(res => setTimeout(res, 60)); // 模拟网络延迟
  if (Math.random() < 0.1) { // 10% 概率失败
    throw new Error('商品服务暂时不可用');
  }
  const stock = Math.floor(Math.random() * 5); // 0-4 的随机库存
  return { productId, price: 100, stock };
}

// 模拟订单服务 (可能失败)
async function createOrderService(userId: string, productId: string, price: number): Promise<{ orderId: string }> {
  console.log(`[服务] 正在为用户 ${userId} 创建商品 ${productId} 的订单，价格: ${price}...`);
  await new Promise(res => setTimeout(res, 70));
  if (Math.random() < 0.05) { // 5% 概率失败
    throw new Error('订单服务创建失败');
  }
  return { orderId: `order-${Date.now()}` };
}

// 模拟邮件服务
async function sendEmailService(email: string, subject: string, body: string): Promise<void> {
  console.log(`[服务] 发送邮件给 ${email} | 主题: ${subject} | 内容: ${body}`);
  await new Promise(res => setTimeout(res, 40));
  // 假设邮件发送总能成功
}

// ---------- 带重试的辅助函数 ----------
async function retry<T>(fn: () => Promise<T>, retries = 2, delayMs = 100): Promise<T> {
  let lastError: Error | undefined;
  for (let i = 0; i <= retries; i++) {
    try {
      return await fn(); // 尝试执行
    } catch (error: any) {
      lastError = error; // 记录错误
      console.warn(`[重试] 第 ${i + 1} 次尝试失败: ${error.message}`);
      if (i < retries) {
        await new Promise(res => setTimeout(res, delayMs * Math.pow(2, i))); // 指数退避等待
      }
    }
  }
  console.error(`[重试] 达到最大重试次数后仍然失败。`);
  throw lastError; // 抛出最后一次的错误
}


// ---------- 主要业务流程函数 ----------
async function processOrderRequest(request: { userId: string; productId: string }) {
  console.log(`\n--- 开始处理订单请求: 用户 ${request.userId}, 商品 ${request.productId} ---`);
  let userInfo: UserInfo | undefined;
  let productInfo: ProductInfo | undefined;
  let finalPrice = 0;
  let orderResult: { orderId: string } | undefined;
  let orderStatus: 'Success' | 'Failed' = 'Failed'; // 默认失败
  let failureReason = '';

  try {
    // 1 & 2: 并行获取用户信息和商品信息 (带重试)
    // 注意：实际项目中可能需要更健壮的并行控制和错误处理库 (如 Promise.allSettled)
    [userInfo, productInfo] = await Promise.all([
      retry(() => fetchUserService(request.userId)),
      retry(() => fetchProductService(request.productId))
    ]);
    console.log('[流程] 用户和商品信息获取成功。');

    // 3. 检查库存
    if (productInfo.stock <= 0) {
      failureReason = '商品库存不足';
      console.warn(`[流程] ${failureReason}`);
      throw new Error(failureReason); // 中断流程
    }
    console.log(`[流程] 库存检查通过 (${productInfo.stock})。`);

    // 4. 计算价格
    finalPrice = productInfo.price;
    if (userInfo.vipLevel === 'VIP') {
      finalPrice = finalPrice * 0.9; // VIP 九折
      console.log(`[流程] 用户是 VIP，应用折扣。最终价格: ${finalPrice}`);
    } else {
      console.log(`[流程] 用户非 VIP。最终价格: ${finalPrice}`);
    }

    // 5. 创建订单 (带重试)
    orderResult = await retry(() => createOrderService(userInfo!.userId, productInfo!.productId, finalPrice), 1, 200); // 重试1次
    orderStatus = 'Success';
    console.log(`[流程] 订单创建成功: ${orderResult.orderId}`);

  } catch (error: any) {
    console.error(`[流程] 处理订单时发生错误: ${error.message}`);
    if (!failureReason) { // 如果没有指定具体业务失败原因，则使用捕获到的错误
        failureReason = error.message;
    }
    // 即使失败，也需要尝试发送通知，所以错误在这里被捕获
  }

  // 6. 发送通知 (无论成功失败都尝试发送)
  if (userInfo) { // 只有获取到用户信息才能发送邮件
    const subject = orderStatus === 'Success' ? '订单创建成功' : '订单创建失败';
    const body = orderStatus === 'Success'
      ? `您的订单 ${orderResult?.orderId} 已成功创建，商品 ${request.productId}，价格 ${finalPrice}。`
      : `抱歉，您的订单 (商品 ${request.productId}) 创建失败。原因: ${failureReason}`;
    try {
      await sendEmailService(userInfo.email, subject, body);
      console.log('[流程] 通知邮件已发送。');
    } catch (emailError: any) {
      console.error(`[流程] 发送通知邮件失败: ${emailError.message}`);
      // 记录发送邮件失败，但通常不影响主流程结果
    }
  } else {
      console.warn('[流程] 未能获取用户信息，无法发送通知邮件。');
  }

  console.log(`--- 订单请求处理结束，最终状态: ${orderStatus} ---`);
  // 返回一个包含最终状态和相关信息的结果对象
  return {
    success: orderStatus === 'Success',
    orderId: orderResult?.orderId,
    userId: request.userId,
    productId: request.productId,
    finalPrice: orderStatus === 'Success' ? finalPrice : undefined,
    reason: orderStatus !== 'Success' ? failureReason : undefined,
  };
}

// ---------- 执行示例 ----------
async function runExample() {
    await processOrderRequest({ userId: 'user1', productId: 'productA' });
    // 可以再调用几次，观察随机失败和库存不足的情况
    // await processOrderRequest({ userId: 'user2', productId: 'productB' });
}

runExample();