package com.heyu.api.controller.vv;


import com.alibaba.fastjson.JSONObject;
import com.heyu.api.data.dao.vv.VvReverseOrderDao;
import com.heyu.api.data.dao.vv.VvReverseOrderLineDao;
import com.heyu.api.data.dao.vv.VvTradeOrderDao;
import com.heyu.api.data.dao.vv.VvTradeOrderLineDao;
import com.heyu.api.data.entity.vv.VvReverseOrderEntity;
import com.heyu.api.data.entity.vv.VvReverseOrderLineEntity;
import com.heyu.api.data.entity.vv.VvTradeOrderLineEntity;
import com.heyu.api.data.enums.ReverseStatusEnums;
import com.heyu.api.data.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/app/weixin")
public class AppWeiXinRefundNotifyController {


    @Autowired
    private VvTradeOrderLineDao vvTradeOrderLineDao;


    // 微信支付APIv3密钥
    @Value("${eb.config.weixin.pay.apiv3key}")
    private String apiV3key;

    @Autowired
    private VvTradeOrderDao tradeOrderDao;


    @Value("${eb.config.weixin.pay.mchid}")
    private String mchid;

    @Autowired
    private VvReverseOrderDao reverseOrderDao;


    @Autowired
    private VvReverseOrderLineDao vvReverseOrderLineDao;



    /***
     *{
     *     "mchid": "1731491745",
     *     "out_trade_no": "202511172474",
     *     "transaction_id": "4200002965202511091318712632",
     *     "out_refund_no": "25",
     *     "refund_id": "50303205432025110956602127632",
     *     "refund_status": "SUCCESS",
     *     "success_time": "2025-11-09T15:13:05+08:00",
     *     "amount": {
     *         "total": 1,
     *         "refund": 1,
     *         "payer_total": 1,
     *         "payer_refund": 1
     *     },
     *     "user_received_account": "交通银行信用卡5874"
     * }
     * @param jsonData
     * @return
     * @throws Exception
     */
    //退款回调
    @PostMapping("/refundNotify")
    @Transactional
    public Object refundNotifyUrl(@RequestBody String jsonData) throws Exception {
        log.info("AppWeiXinRefundNotifyController refundNotifyUrl jsonData = " + jsonData);
        //转为map格式
        Map<String, String> jsonMap = JSONObject.parseObject(jsonData, Map.class);
        //退款成功后返回一个加密字段resource,以下为解密
        /**
         * 解密需要从resource参数中，获取到ciphertext，nonce，associated_data这三个参数进行解密
         */
        String resource = JSONObject.toJSONString(jsonMap.get("resource"));
        JSONObject object = JSONObject.parseObject(resource);
        String ciphertext = String.valueOf(object.get("ciphertext"));

        String nonce = String.valueOf(object.get("nonce"));

        String associated_data = String.valueOf(object.get("associated_data"));

        String resultStr = decryptToString(associated_data.getBytes("UTF-8"), nonce.getBytes("UTF-8"), ciphertext);

        Map<String, String> reqInfo = JSONObject.parseObject(resultStr, Map.class);

        String refund_status = reqInfo.get("refund_status");//退款状态
        String out_trade_no = reqInfo.get("out_trade_no"); //订单号
        String out_refund_no = reqInfo.get("out_refund_no"); //订单号
        log.info("AppWeiXinRefundNotifyController refundNotifyUrl out_trade_no:{} ,out_refund_no:{} refund_status:{} resultStr :{} " ,out_trade_no,out_refund_no,refund_status,resultStr);
        Map<String, Object> parm = new HashMap<>();
        if (!StringUtils.isEmpty(refund_status) && "SUCCESS".equals(refund_status)) {

            VvReverseOrderEntity vvReverseOrderEntity = reverseOrderDao.selectVvReverseOrderByOutRefundNo(out_refund_no);

            log.info("AppWeiXinRefundNotifyController refundNotifyUrl reverseStatus:{}", vvReverseOrderEntity.getStatus());

            if(ReverseStatusEnums.weixin_refunding.getStatus().equals(vvReverseOrderEntity.getStatus())){
                vvReverseOrderEntity.setGmtRefunded(new Date());
                vvReverseOrderEntity.setStatus(ReverseStatusEnums.refunded.getStatus());
                vvReverseOrderEntity.setGmtRefundNotify(new Date());
                reverseOrderDao.updateVvReverseOrderById(vvReverseOrderEntity);

                List<VvReverseOrderLineEntity > vvReverseOrderLineEntities = vvReverseOrderLineDao.selectVvReverseOrderLineByReverseOrderId(vvReverseOrderEntity.getId());
                List<Long> tradeOrderLineIds = new ArrayList<>();
                for (VvReverseOrderLineEntity vvReverseOrderLineEntity : vvReverseOrderLineEntities) {
                    tradeOrderLineIds.add(vvReverseOrderLineEntity.getTradeOrderLineId());
                }
                List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByIds(tradeOrderLineIds);
                for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
                    vvTradeOrderLineEntity.setReverseStatus(ReverseStatusEnums.refunded.getStatus());
                    vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
                }
            }
            //你自己的业务
            parm.put("code", "SUCCESS");
            parm.put("message", "成功");
        } else {
            parm.put("code", "FAIL");
            parm.put("message", "失败");
            throw new RuntimeException("退款失败");
        }
        return parm;  //返回给前端的参数
    }

    //退款回调  解密数据
    public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            SecretKeySpec key = new SecretKeySpec(apiV3key.getBytes(), "AES");//todo 这里的apiV3key是你的商户APIV3密钥
            GCMParameterSpec spec = new GCMParameterSpec(128, nonce);//规定为128

            cipher.init(Cipher.DECRYPT_MODE, key, spec);
            cipher.updateAAD(associatedData);
            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalStateException(e);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }


}
