package com.yc.ship.module.trade.service.supplier.system;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yc.ship.framework.common.exception.ServiceException;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.module.product.api.dto.SupplierRespDTO;
import com.yc.ship.module.resource.service.resource.util.MD5Utils;
import com.yc.ship.module.trade.controller.app.ota.vo.OtaVoucherVO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderUserDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeVisitorDO;
import com.yc.ship.module.trade.dal.dataobject.supplier.SupplierRefundDO;
import com.yc.ship.module.trade.dal.dataobject.supplier.TradeSupplierOrderDO;
import com.yc.ship.module.trade.framework.common.ota.DesUtil;
import com.yc.ship.module.trade.service.order.TradeOrderRepositoryService;
import com.yc.ship.module.trade.service.supplier.SupplierTradeService;
import com.yc.ship.module.trade.service.supplier.TradeSupplierOrderRepositoryService;
import com.yc.ship.module.trade.service.supplier.bo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yc.ship.module.trade.enums.ErrorCodeConstants.*;
import static com.yc.ship.module.trade.service.supplier.SupplierTradeService.ZSHL_SERVICE;

/**
 * &#064;Description ：智胜慧旅提供供应商服务 <a href="https://huilvticket.yuque.com/staff-kx84vq/wnasfn/tyg2sn#ZaEN4">...</a>
 * &#064;Author ：qsl
 * &#064;Date ：2025/6/16 16:02
 */
@Service(ZSHL_SERVICE)
@Slf4j
public class ZshlSupplierTradeService implements SupplierTradeService {

    @Resource
    private TradeSupplierOrderRepositoryService tradeSupplierOrderRepositoryService;

    @Resource
    private TradeOrderRepositoryService tradeOrderRepositoryService;

    @Override
    public CommonResult<SupplierTradeOrderRespBO> createOrder(SupplierTradeOrderBO supplierTradeOrderBO, SupplierRespDTO supplierRespDTO) {
        try {

            log.info("三峡二期系统createOrder=" + 11);
            //jfg景区对接
            //下单地址
            String method = "createOrder";
            String createOrderUrl = supplierRespDTO.getDirectOrderUrl() + method;
            String userId = supplierRespDTO.getDirectAccount();
            String userKey = supplierRespDTO.getDirectParam();
            String productId = supplierTradeOrderBO.getTradeSupplierOrderDO().getSupplierProductId();
            Long timestamp = System.currentTimeMillis() / 1000;

            TradeOrderUserDO tradeOrderUserDO = tradeOrderRepositoryService.getOrderUser(supplierTradeOrderBO.getTradeSupplierOrderDO().getOrderId());

            JSONObject rep_body = new JSONObject();
            rep_body.put("orderId", supplierTradeOrderBO.getTradeSupplierOrderDO().getTradeNo());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String localDateNowStr = supplierTradeOrderBO.getTradeSupplierOrderDO().getUseDate().format(formatter);
            rep_body.put("travelDate", localDateNowStr);
            rep_body.put("travelTime", "");
            rep_body.put("quantity", supplierTradeOrderBO.getTradeVisitorDOList().size());
            rep_body.put("productId", productId);
            rep_body.put("bookName", tradeOrderUserDO.getContactName());
            rep_body.put("bookMobile", tradeOrderUserDO.getMobile());
            rep_body.put("idCard", tradeOrderUserDO.getCredentialNo());

            JSONArray vistorList = new JSONArray();
            for (TradeVisitorDO tradeVisitorDO : supplierTradeOrderBO.getTradeVisitorDOList()) {
                JSONObject vistor = new JSONObject();
                vistor.put("name", tradeVisitorDO.getName());
                vistor.put("mobile", tradeVisitorDO.getMobile());
                vistor.put("idCard", tradeVisitorDO.getCredentialNo());
                vistor.put("face", "");
                vistorList.add(vistor);
            }
            rep_body.put("visitPersons", vistorList);
            String bodyStr = DesUtil.encrypt(rep_body.toString(), userKey);
            String signStr = userId + method + timestamp + bodyStr + userKey;
            log.info("jfg供应商预下单开始,signStr:{}", signStr);
            String sign = MD5Utils.getMD5(signStr.getBytes("UTF-8"));

            JSONObject rep_head = new JSONObject();
            rep_head.put("user_id", userId);
            rep_head.put("method", method);
            rep_head.put("timestamp", timestamp);
            rep_head.put("sign", sign);

            JSONObject req = new JSONObject();
            req.put("requestHead", rep_head);
            req.put("requestBody", bodyStr);
            Map<String, String> headMap = new HashMap<>();
            headMap.put("Content-type", "application/x-www-form-urlencoded");
            log.info("jfg供应商预下单开始,请求地址:{},请求参数:{}", createOrderUrl, req.toString());
            String res = HttpUtil.createPost(createOrderUrl).contentType("application/json")
                    .body(Base64Util.encode(req.toString()))
                    .headerMap(headMap, false)
                    .timeout(100000)
                    .execute().body();
            log.info("jfg供应商预下单完成,响应参数:{}", res);
            // base64解密
            String json = new String(Base64.decodeBase64(res.getBytes("UTF-8")));
            log.info("jfg供应商预下单完成,响应response参数:{}", json);
            JSONObject jsonObj = JSONUtil.parseObj(json);
            JSONObject responseHead = jsonObj.getJSONObject("responseHead");
            if (StringUtils.equals("1000", responseHead.getStr("res_code"))) {
                String response = jsonObj.getStr("responseBody");
                String body = "";
                try {
                    body = DesUtil.decrypt(response, userKey);
                } catch (Exception e) {
                    log.info(e.toString());
                }
                log.info("jfg供应商预下单完成,响应body参数:{}", body);
                JSONObject responseBody = JSONUtil.parseObj(body);
                return CommonResult.success(new SupplierTradeOrderRespBO().setSupplierOrderNo(responseBody.getStr("partnerOrderId")));
            } else {
                return CommonResult.error(500, responseHead.getStr("res_msg"));
            }
        } catch (ServiceException e) {
            log.error("jfg供应商预下单失败：", e);
            return CommonResult.error(e);
        } catch (Exception e) {
            log.error("jfg供应商预下单失败：", e);
            return CommonResult.error(SUPPLIER_ZSHL_ORDER_CREATE_FAIL);
        }
    }

    @Override
    public CommonResult<SupplierTradeOrderPayRespBO> payOrder(SupplierTradeOrderPayBO supplierTradeOrderPayBO, SupplierRespDTO supplierRespDTO) {
        try {
            //jfg景区对接
            //下单地址
            String method = "payOrder";
            String createOrderUrl = supplierRespDTO.getDirectOrderUrl() + method;
            String userId = supplierRespDTO.getDirectAccount();
            String userKey = supplierRespDTO.getDirectParam();
            Long timestamp = System.currentTimeMillis() / 1000;

            JSONObject rep_head = new JSONObject();
            rep_head.put("user_id", userId);
            rep_head.put("method", method);
            rep_head.put("timestamp", timestamp);

            JSONObject rep_body = new JSONObject();
            rep_body.put("orderId", supplierTradeOrderPayBO.getTradeSupplierOrderDO().getTradeNo());
            rep_body.put("partnerOrderId", supplierTradeOrderPayBO.getTradeSupplierOrderDO().getSupplierOrderNo());

            String bodyStr = DesUtil.encrypt(rep_body.toString(), userKey);
            String signStr = userId + method + timestamp + bodyStr + userKey;
            log.error("jfg供应商预下单开始,signStr:{}", signStr);
            String sign = MD5Utils.getMD5(signStr.getBytes("UTF-8"));
            rep_head.put("sign", sign);

            JSONObject req = new JSONObject();
            req.put("requestHead", rep_head);
            req.put("requestBody", bodyStr);

            Map<String, String> headMap = new HashMap<>();
            headMap.put("Content-type", "application/x-www-form-urlencoded");
            log.info("jfg供应商支付下单开始,请求地址:{},请求参数:{}", createOrderUrl, req.toString());
            String res = HttpUtil.createPost(createOrderUrl).contentType("application/json")
                    .body(Base64Util.encode(req.toString()))
                    .headerMap(headMap, false)
                    .timeout(15000)
                    .execute().body();
            log.info("jfg供应商支付下单完成,响应参数:{}", res);
            // base64解密
            String json = new String(Base64.decodeBase64(res.getBytes("UTF-8")));
            log.info("jfg供应商支付完成,响应response参数:{}", json);
            JSONObject jsonObj = JSONUtil.parseObj(json);
            JSONObject responseHead = jsonObj.getJSONObject("responseHead");
            if (StringUtils.equals("1000", responseHead.getStr("res_code"))) {
                String response = jsonObj.getStr("responseBody");
                String body = "";
                try {
                    body = DesUtil.decrypt(response, userKey);
                } catch (Exception e) {
                    log.info(e.toString());
                }
                log.info("jfg供应商支付请求完成,响应body参数:{}", body);
                JSONObject responseBody = JSONUtil.parseObj(body);
                JSONArray vistors = responseBody.getJSONArray("visitPersons");
                List<OtaVoucherVO> list = new ArrayList<>();
                for (int i = 0; i < vistors.size(); i++) {
                    JSONObject vistor = vistors.getJSONObject(i);
                    OtaVoucherVO otaVoucherVO = new OtaVoucherVO();
                    otaVoucherVO.setCredentialNo(vistor.getStr("idCard"));
                    otaVoucherVO.setVoucherCode(vistor.getStr("ticketId"));
                    list.add(otaVoucherVO);
                }
                return CommonResult.success(new SupplierTradeOrderPayRespBO().setSupplierOrderNo(supplierTradeOrderPayBO.getTradeSupplierOrderDO().getSupplierOrderNo())
                        .setPlatSupplierOrderId(supplierTradeOrderPayBO.getTradeSupplierOrderDO().getId())
                        .setVoucherList(list));
            } else {
                return CommonResult.error(500, responseHead.getStr("res_msg"));
            }
        } catch (ServiceException e) {
            log.error("jfg票务系统供应商支付失败：", e);
            return CommonResult.error(e);
        } catch (Exception e) {
            log.error("jfg票务系统供应商支付失败：", e);
            return CommonResult.error(SUPPLIER_PLAT_ORDER_PAY_FAIL);
        }
    }

    @Override
    public CommonResult<SupplierRefundRespBO> refund(SupplierRefundDO supplierRefundDO, SupplierRespDTO supplierRespDTO) {
        try {
            //jfg景区对接
            //退票地址
            String method = "cancelTicket";
            String createOrderUrl = supplierRespDTO.getDirectOrderUrl() + method;
            String userId = supplierRespDTO.getDirectAccount();
            String userKey = supplierRespDTO.getDirectParam();
            Long timestamp = System.currentTimeMillis() / 1000;

            JSONObject rep_head = new JSONObject();
            rep_head.put("user_id", userId);
            rep_head.put("method", method);
            rep_head.put("timestamp", timestamp);
            List<TradeSupplierOrderDO> tradeSupplierOrderDOList = tradeSupplierOrderRepositoryService.getTradeSupplierOrderList(supplierRefundDO.getOrderId());
            String orderId = "";
            if (tradeSupplierOrderDOList != null && tradeSupplierOrderDOList.size() > 0) {
                orderId = tradeSupplierOrderDOList.get(0).getTradeNo();
            }
            JSONObject rep_body = new JSONObject();
            rep_body.put("orderId", orderId);
            rep_body.put("partnerOrderId", supplierRefundDO.getSupplierOrderNo());
            List<String> ticketIds = tradeSupplierOrderRepositoryService.getVoucherListByPlatSupplierRefundId(supplierRefundDO.getId());

            rep_body.put("refundDetailIds", ticketIds);

            String bodyStr = DesUtil.encrypt(rep_body.toString(), userKey);
            String signStr = userId + method + timestamp + bodyStr + userKey;
            log.error("jfg供应商退票开始,signStr:{}", signStr);
            String sign = MD5Utils.getMD5(signStr.getBytes("UTF-8"));
            rep_head.put("sign", sign);

            JSONObject req = new JSONObject();
            req.put("requestHead", rep_head);
            req.put("requestBody", bodyStr);
            Map<String, String> headMap = new HashMap<>();
            headMap.put("Content-type", "application/x-www-form-urlencoded");

            log.info("jfg供应商退票开始,请求地址:{},请求参数:{}", createOrderUrl, req.toString());
            String res = HttpUtil.createPost(createOrderUrl).contentType("application/json")
                    .body(Base64Util.encode(req.toString()))
                    .headerMap(headMap, false)
                    .timeout(15000)
                    .execute().body();
            log.info("jfg供应商退票完成,响应参数:{}", res);
            // base64解密
            String json = new String(Base64.decodeBase64(res.getBytes("UTF-8")));
            log.info("jfg供应商退票完成,响应response参数:{}", json);
            JSONObject jsonObj = JSONUtil.parseObj(json);
            JSONObject responseHead = jsonObj.getJSONObject("responseHead");
            if (StringUtils.equals("1000", responseHead.getStr("res_code"))) {
                String response = jsonObj.getStr("responseBody");
                String body = "";
                try {
                    body = DesUtil.decrypt(response, userKey);
                } catch (Exception e) {
                    log.info(e.toString());
                }
                log.info("jfg供应商退票请求完成,响应body参数:{}", body);
                JSONObject responseBody = JSONUtil.parseObj(body);
                return CommonResult.success(new SupplierRefundRespBO().setSupplierRefundNo(responseBody.getStr("partnerOrderId")));
            } else {
                return CommonResult.error(500, responseHead.getStr("res_msg"));
            }
        } catch (ServiceException e) {
            log.error("jfg票务系统供应商退票失败：", e);
            return CommonResult.error(e);
        } catch (Exception e) {
            log.error("jfg票务系统供应商退票失败：", e);
            return CommonResult.error(SUPPLIER_ZSHL_REFUND_FAIL);
        }
    }
}
