/**
 * 小程序原生拉起支付（P1）
 * ========================
 * 让小程序内的支付走微信原生 wx.requestPayment()，而非 H5 webview。
 * 复用共享 paymentSdk.createPayment：传入 openid 即走 JSAPI，返回 jsParams。
 *
 * 行为（按环境优雅降级）：
 *   - 模拟模式(payment_test_mode=1)      → {mode:'simulate', pay_url}  前端跳 H5 mock
 *   - 生产 + 微信支付已配置 + openid     → {mode:'jsapi',  params:{timeStamp,nonceStr,package,signType,paySign}}  前端 wx.requestPayment
 *   - 生产 + 未配置/无 openid            → {mode:'h5', pay_url}        前端回退 H5 webview
 *
 * 校验：订单归属用户 + pending_pay 才允许创建支付。
 */
const express = require('express');
const router = express.Router();
const { get, run, transaction } = require('../utils/db');
const { success, fail } = require('../utils/response');
const { authUser } = require('../middleware/auth');
const paymentSdk = require('../lib/payment');

// 订单号生成：前缀+日期+随机（与 bargain/group-bulk 一致）
function genOrderNo(prefix) {
  const d = new Date();
  const p = (x) => String(x).padStart(2, '0');
  return (prefix || 'OD') + d.getFullYear() + p(d.getMonth() + 1) + p(d.getDate())
    + p(d.getHours()) + p(d.getMinutes()) + p(d.getSeconds()) + String(Math.floor(Math.random() * 10000)).padStart(4, '0');
}

const safeSubject = (s) => String(s || '').slice(0, 32) || '商品订单';
const clientIp = (req) => (req.headers['x-forwarded-for'] || req.socket.remoteAddress || '127.0.0.1').toString().split(',')[0].trim();

/**
 * POST /api/miniapp-pay/order
 * body: { order_no, amount, subject, openid }
 */
router.post('/order', authUser, async (req, res) => {
  try {
    const { order_no, amount, subject, openid } = req.body || {};
    if (!order_no || amount === undefined || Number(amount) <= 0) return res.json(fail('参数错误'));

    // 校验订单归属 + 状态
    const order = get('SELECT * FROM orders WHERE order_no=? AND user_id=?', [order_no, req.userId]);
    if (!order) return res.json(fail('订单不存在'));
    if (order.status === 'pending_pay' || order.status === 'deposit_pending') {
      // 允许
    } else {
      return res.json(fail('订单当前状态不可支付'));
    }

    // 幂等：同一订单已存在成功支付则拒绝
    const paid = get("SELECT id FROM payment_records WHERE order_id=? AND status='success' LIMIT 1", [order.id]);
    if (paid) return res.json(fail('订单已支付'));

    const tradeNo = genOrderNo('MP'); // 小程序支付单号前缀
    const makePayUrl = (tn) => paymentSdk.isSimulateMode()
      ? `/api/payment/mock-pay?trade_no=${tn}&order_no=${order_no || ''}`
      : `/api/miniapp-pay/pay?trade_no=${tn}&order_no=${order_no || ''}`;

    // 模拟模式：直接返回 H5 mock（与现有一致）
    if (paymentSdk.isSimulateMode()) {
      return res.json(success({ mode: 'simulate', trade_no: tradeNo, pay_url: makePayUrl(tradeNo) }));
    }

    // 生产：走 JSAPI 原生支付（需 openid + 微信已配置）
    if (!openid) {
      return res.json(success({ mode: 'h5', reason: 'no_openid', pay_url: `/api/miniapp-pay/pay?order_no=${order_no}` }));
    }
    const r = await paymentSdk.createPayment(tradeNo, amount, safeSubject(subject), 'wechat', { openid, clientIp: clientIp(req) });
    if (r.mode === 'production' && r.jsParams) {
      return res.json(success({ mode: 'jsapi', trade_no: tradeNo, params: r.jsParams }));
    }
    // 兜底：返回 H5 回落
    return res.json(success({ mode: 'h5', pay_url: makePayUrl(tradeNo) }));
  } catch (e) {
    const msg = String(e && e.message || '创建支付失败');
    // 未配置时明确提示
    if (/未配置/.test(msg)) return res.json(fail(msg));
    console.error('[小程序支付]', e);
    return res.json(fail('创建支付失败: ' + msg));
  }
});

module.exports = router;
