package com.yiqi.core.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.yiqi.common.exception.ServiceException;
import com.google.gson.JsonObject;
import com.yiqi.common.config.CompositeWxMaService;
import com.yiqi.common.config.WxMaProperties;
import com.yiqi.common.utils.wx.*;
import com.yiqi.core.domain.dto.wx.*;
import com.yiqi.core.domain.vo.wx.*;
import com.yiqi.core.service.ISysStoreIntracityExpressService;
import com.yiqi.order.domain.OrderClothDeliveryAddress;
import com.yiqi.system.domain.SysStore;
import com.yiqi.system.service.ISysStoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.logging.Logger;

/**
 * @author xiaohei
 * @date 2024/1/31
 */
@Slf4j
@Service
public class SysStoreIntracityExpressServiceImpl implements ISysStoreIntracityExpressService {

    private static final Logger logger = Logger.getLogger(SysStoreIntracityExpressServiceImpl.class.getName());
    @Autowired
    private CompositeWxMaService compositeWxMaService;
    @Autowired
    private WxMaProperties wxMaProperties;
    @Autowired
    private ISysStoreService sysStoreService;

    @Override
    public IntracityExpressCreateStoreResult createStore(IntracityExpressCreateStoreRequest intracityExpressCreateStoreRequest)
            throws Exception {
        IntracityExpressCreateStoreResult result = IntracityExpressCreateStoreResult.fromJson(
                httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/createstore", intracityExpressCreateStoreRequest.toJson()));
        if (result.getErrcode() != 0) {
            logger.warning("同城配送创建门店失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
            throw new ServiceException("同城配送创建门店失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        //更新门店信息
        SysStore sysStore = sysStoreService.getById(Long.parseLong(result.getOut_store_id().replace("store", "")));
        sysStore.setWxStoreId(result.getWx_store_id());
        sysStoreService.updateById(sysStore);
        return result;
    }

    @Override
    public IntracityExpressStoreInfoResult getStoreInfo(IntracityExpressStoreInfoRequest intracityExpressStoreInfoRequest) throws Exception {
        IntracityExpressStoreInfoResult result = IntracityExpressStoreInfoResult.fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/querystore"
                , intracityExpressStoreInfoRequest.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店查询失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressBaseResult updateStore(IntracityExpressStoreUpdateRequest intracityExpressStoreUpdateRequest) throws Exception {
        IntracityExpressBaseResult result = IntracityExpressBaseResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/updatestore"
                        , intracityExpressStoreUpdateRequest.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店修改失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressStoreBalanceInfoResult getStoreBalance(IntracityExpressStoreBalanceInfoRequest request) throws Exception {
        IntracityExpressStoreBalanceInfoResult result = IntracityExpressStoreBalanceInfoResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/balancequery"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店获取余额失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressStoreBalanceChargeResult storeBalanceCharge(IntracityExpressStoreBalanceChargeRequest request) throws Exception {
        IntracityExpressStoreBalanceChargeResult result = IntracityExpressStoreBalanceChargeResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/storecharge"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店充值失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressPreAddOrderResult preAddOrder(IntracityExpressPreAddOrderRequest request) throws Exception {
        IntracityExpressPreAddOrderResult result = IntracityExpressPreAddOrderResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/preaddorder"
                        , request.toJson()));
//        if(result.getErrcode() != 0){
//            throw new ServiceException("同城配送查询运费失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
//        }
        return result;
    }

    @Override
    public IntracityExpressCreateOrderResult addOrder(IntracityExpressAddOrderRequest request) throws Exception {
        IntracityExpressCreateOrderResult result = IntracityExpressCreateOrderResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/addorder"
                        , request.toJson()));
        return result;
    }

    @Override
    public IntracityExpressBaseResult cancelOrder(IntracityExpressCancelOrderRequest request) throws Exception {
        IntracityExpressBaseResult result = IntracityExpressBaseResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/cancelorder"
                        , request.toJson()));
        return result;
    }

    @Override
    public IntracityExpressGetCityResult getCity(IntracityExpressGetCityRequest request) throws Exception {
        IntracityExpressGetCityResult result = IntracityExpressGetCityResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/getcity"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送查询支持同城配送的城市失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressQueryFlowResult queryFlow(IntracityExpressQueryFlowRequest request) throws Exception {
        IntracityExpressQueryFlowResult result = IntracityExpressQueryFlowResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/queryflow"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店运费流水查询失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressOrderInfoResult getOrderInfo(IntracityExpressOrderInfoRequest request) throws Exception {
        IntracityExpressOrderInfoResult result = IntracityExpressOrderInfoResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/queryorder"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店运费流水查询失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public IntracityExpressBaseResult mocknotify(IntracityExpressMockNotifyRequest request) throws Exception {
        IntracityExpressBaseResult result = IntracityExpressBaseResult
                .fromJson(httpPost("https://api.weixin.qq.com/cgi-bin/express/intracity/mocknotify"
                        , request.toJson()));
        if (result.getErrcode() != 0) {
            throw new ServiceException("同城配送门店模拟订单状态失败,errcode:" + result.getErrcode() + ";errmsg:" + result.getErrmsg());
        }
        return result;
    }

    private String httpPost(String url, String body) throws Exception {
        JsonObject reqforsign = AES_Enc.getReqForSign(WxAppApiAESSecretDTO.build(url, wxMaProperties)
                , JSONObject.parseObject(body));
        String accessToken = compositeWxMaService.get().getAccessToken();
        log.info("WX请求: {}, {}", accessToken, body);
        HttpResponse response = HttpRequest.post(url + "?access_token=" + accessToken)
                .header("Wechatmp-Appid", wxMaProperties.getAppid())
                .header("Wechatmp-TimeStamp", reqforsign.get("req_ts").getAsString())
                .header("Wechatmp-Signature", RSA_Sign.getSignature(WxAppApiRSASecretDTO.build(url, wxMaProperties), reqforsign))
                .header("Content-Type", "application/json;charset=utf-8")
                .body(reqforsign.get("req_data").getAsString())
                .execute();
        String respData = AES_Dec.getRealResp(WxAppApiAESSecretDTO.build(url, wxMaProperties)
                , Integer.parseInt(response.header("Wechatmp-TimeStamp")), response.body());
        log.info("WX请求返回: {}, {}", response.body(), respData);
        return respData;
    }

    @Override
    public void updateStoreInfo(SysStore sysStore, OrderClothDeliveryAddress orderClothDeliveryAddress) throws Exception {
        IntracityExpressStoreUpdateRequest.KeyInfo keyInfo = new IntracityExpressStoreUpdateRequest.KeyInfo();
        keyInfo.setWx_store_id(sysStore.getWxStoreId());
        IntracityExpressStoreUpdateRequest request = new IntracityExpressStoreUpdateRequest();
        request.setKeys(keyInfo);
        IntracityExpressStoreUpdateRequest.UpdateContent updateContent = new IntracityExpressStoreUpdateRequest.UpdateContent();
        IntracityExpressCreateStoreRequest.AddressInfo addressInfo = new IntracityExpressCreateStoreRequest.AddressInfo();
        addressInfo.setProvince(orderClothDeliveryAddress.getProvince());
        addressInfo.setCity(orderClothDeliveryAddress.getCity());
        addressInfo.setArea(orderClothDeliveryAddress.getArea());
        addressInfo.setHouse(orderClothDeliveryAddress.getAddress() + orderClothDeliveryAddress.getAddressDetail());
        addressInfo.setLat(orderClothDeliveryAddress.getLatitude().doubleValue());
        addressInfo.setLng(orderClothDeliveryAddress.getLongitude().doubleValue());
        addressInfo.setPhone(orderClothDeliveryAddress.getContactPhone());
        updateContent.setAddress_info(addressInfo);
        updateContent.setStore_name(orderClothDeliveryAddress.getContactName());
        request.setContent(updateContent);
        updateStore(request);
    }

    @Override
    public void updateStoreInfo(SysStore sysStore) throws Exception {
        IntracityExpressStoreUpdateRequest.KeyInfo keyInfo = new IntracityExpressStoreUpdateRequest.KeyInfo();
        keyInfo.setWx_store_id(sysStore.getWxStoreId());
        IntracityExpressStoreUpdateRequest request = new IntracityExpressStoreUpdateRequest();
        request.setKeys(keyInfo);
        IntracityExpressStoreUpdateRequest.UpdateContent updateContent = new IntracityExpressStoreUpdateRequest.UpdateContent();
        IntracityExpressCreateStoreRequest.AddressInfo addressInfo = new IntracityExpressCreateStoreRequest.AddressInfo();
        addressInfo.setProvince(sysStore.getProvinceName());
        addressInfo.setCity(sysStore.getCityName());
        addressInfo.setArea(sysStore.getAreaName());
        addressInfo.setHouse(sysStore.getAddress() + sysStore.getAddressDetail());
        addressInfo.setLat(sysStore.getLatitude().doubleValue());
        addressInfo.setLng(sysStore.getLongitude().doubleValue());
        addressInfo.setPhone(sysStore.getContactPhone());
        updateContent.setAddress_info(addressInfo);
        updateContent.setStore_name(sysStore.getName());
        request.setContent(updateContent);
        updateStore(request);
    }
}
