const { ok } = require('../lib/response')
const config = require('../config')
const wxpay = require('../lib/wxpay')
const paymentOrderDao = require('../dao/payment-order.dao')
const logDao = require('../dao/log.dao')

async function handleNotify(req, res) {
  try {
    if (!Buffer.isBuffer(req.body)) throw new Error('invalid body format')
    const rawBody = req.body.toString('utf8')
    const parsed = JSON.parse(rawBody)

    await wxpay.verifyNotifySignature(req.headers, rawBody)

    const result = wxpay.decryptNotifyResource(parsed.resource)

    // Validate appid and mchid
    const expectedAppid = config.wxpay.appid || config.wechat.appid
    if (result.appid !== expectedAppid) throw new Error('appid mismatch')
    if (result.mchid !== config.wxpay.mchId) throw new Error('mchid mismatch')

    const orderId = result.out_trade_no
    const order = await paymentOrderDao.findByOutTradeNo(orderId)
    if (!order) throw new Error('order not found: ' + orderId)

    if (!result.amount || result.amount.total !== order.amount_fen) throw new Error('amount mismatch')

    if (result.trade_state === 'SUCCESS') {
      const activated = await paymentOrderDao.markPaidAndActivateSubscription(orderId, result.transaction_id, result)
      if (activated) {
        await logDao.write({ user_id: order.user_id, action: 'payment_notify_success', detail: 'order: ' + orderId + ' tx: ' + result.transaction_id, ip: req.ip })
      }
    }

    // WeChat expects this exact response format
    res.status(200).json({ code: 'SUCCESS', message: '' })
  } catch (err) {
    console.error('[WXPAY NOTIFY ERROR]', err.message)
    res.status(400).json({ code: 'FAIL', message: 'processing error' })
  }
}

module.exports = handleNotify
