package com.iformall.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.BaseEntity;
import com.iformall.domain.vo.WxCouponOrderCarCVo;
import com.iformall.domain.vo.WxMerchantVo;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.service.*;
import com.iformall.utils.car.DaHuaUtil;
import com.iformall.utils.car.ETCPUtil;
import com.iformall.utils.car.TJDUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/car")
@Api(description = "智慧停车相关接口")
public class WxCarController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    ETCPUtil etcp = new ETCPUtil();

    TJDUtil tjd = new TJDUtil();

    @Autowired
    WxParkService wxParkService;

    @Autowired
    WxCUserCarService wxCUserCarService;

    @Autowired
    WxMerchantService wxMerchantService;

    @Autowired
    WxCouponService couponService;

    @Autowired
    WxCouponOrderService wxCouponOrderService;

    @Autowired
    WxScoreRulesService wxScoreRulesService;

    @Autowired
    WxCUserTagsService wxCUserTagsService;

    @Autowired
    WxCarCmdLogService wxCarCmdLogService;

    @Autowired
    WxCreditHistoryService wxCreditHistoryService;

    private WxPark getCurrentPark(String tenantId) {
        WxPark parkQ = new WxPark();
        parkQ.setTenantId(tenantId);
        WxPark wxPark = wxParkService.getByObj(parkQ);
        // 1, get mall's park
        // future use redis to optimize
        return wxPark;
    }

    @ApiOperation(value = "获取车场支持的厂家", notes = "返回\n{\"vendor\":integer}")
    @GetMapping("/getVendor")
    public ResultData getVendor() {
        // 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        Map map = new HashMap();
        map.put("vendor", park.getVendorType());
        return new ResultData(map);
    }

    /**
     * 初始化/etcp共同登录
     *
     * @param paramMap
     * @return
     */
    @ApiOperation(value = "初始化/etcp共同登录", notes = "{\"phone\":\"string\"}")
    @PostMapping("/init")
    public ResultData init(@RequestBody Map<String, String> paramMap) {
        WxCUser user = getUser();
        // 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        // 2. get vendor params
        if (park.getVendorType().equals(EnumCarVendor.CAR_ETCP.getCode())) {
            return initForEtcp(paramMap, user, park);
        } else if (park.getVendorType().equals(EnumCarVendor.CAR_TJD.getCode())) {
            // TJD不需要共同登录
            Map resultMap = new HashMap();
            resultMap.put("vendor", EnumCarVendor.CAR_TJD.getCode());
            return new ResultData(resultMap);
        } else if (park.getVendorType().equals(EnumCarVendor.CAR_DAHUA.getCode())) {
            Map resultMap = new HashMap();
            resultMap.put("vendor", EnumCarVendor.CAR_DAHUA.getCode());
            return new ResultData(resultMap);
        }

        return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "登录失败");
    }

    private ResultData initForEtcp(Map<String, String> paramMap, WxCUser user, WxPark park) {
        String phone = paramMap.get("phone");
        if (StringUtils.isBlank(phone) && StringUtils.isBlank(user.getPhone()) && StringUtils.isBlank(user.getVerifyCodePhone())) {
            logger.error("手机号为空,请授权手机号");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "手机号为空,请授权手机号");
        }
        if (!StringUtils.isBlank(user.getPhone()) && !user.getPhone().contains("*")) {
            phone = user.getPhone();
        } else {
            phone = user.getVerifyCodePhone();
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String appId = objParams.getString("appId");
        String merchantNo = objParams.getString("merchantNo");
        String merchantKey = objParams.getString("merchantKey");
        String version = objParams.getString("version");

        String ret = "";
        try {
            ret = etcp.userSignin(url, appId, merchantNo, merchantKey, version, phone);
        } catch (MallinkException e) {
            logger.error("ETCP failed: " + e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        }
        JSONObject retObj = JSON.parseObject(ret);
        if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) {
            // 获取绑定的车牌
            JSONObject dataObj = retObj.getJSONObject("data");
            dataObj.put("vendor", EnumCarVendor.CAR_ETCP.getCode());
            String etcpToken = dataObj.getString("token");
            try {
                JSONObject dataObj1 = etcpSyncCarNumbers(user.getId(), user.getTenantId(), park.getVendorType(),
                        url, merchantNo, merchantKey, version,
                        etcpToken);
            } catch (MallinkException e) {
                logger.error("ETCP cmd error: " + e.getMessage());
            }
            // c端必须保存此token
            return new ResultData(dataObj);
        } else {
            logger.error("共同登录失败: " + phone);
            return new ResultData(ErrorCode.ETCP_LOGIN_FAIL.getCode(), "共同登录失败");
        }
    }

    /**
     * ETCP同步
     *
     * @param cUserId
     * @param tenantId
     * @param iVendorType
     * @param url
     * @param merchantNo
     * @param merchantKey
     * @param version
     * @param etcpToken
     * @return
     */
    private JSONObject etcpSyncCarNumbers(Long cUserId, String tenantId, int iVendorType,
                                          String url, String merchantNo, String merchantKey, String version,
                                          String etcpToken) {
        String ret;
        JSONObject retObj;
        /*{"code": 0,"msg": "ok","data": {"number": 3,"carList": ["晋 BMZ105","云 C12345"]}} */
        try {
            ret = etcp.carNum(url, merchantNo, merchantKey, version, etcpToken);
        } catch (MallinkException e) {
            logger.error("ETCP failed: " + e.getMessage());
            throw new MallinkException(e.getErrorCode(), e.getMessage());
        }
        retObj = JSON.parseObject(ret);
        JSONObject dataObj1 = retObj.getJSONObject("data");
        dataObj1.put("vendor", iVendorType);
        JSONArray arr = dataObj1.getJSONArray("carList");
        WxCUserCar queryUserCar = new WxCUserCar();
        queryUserCar.setCUserId(cUserId);
        List<WxCUserCar> uclist = wxCUserCarService.getList(queryUserCar);
        // 删除ETCP不存在
        for (WxCUserCar userCar : uclist) {
            boolean bExist = isExistInArray(arr, userCar.getCarNumber());
            if (!bExist) {
                wxCUserCarService.deleteById(userCar.getId());
                uclist.remove(userCar);
            }
        }
        // 添加ETCP的
        for (int i = 0; i < arr.size(); i++) {
            String _carNum = arr.getString(i);
            boolean bExist = isExistInList(uclist, _carNum);
            if (!bExist) {
                Date curr = new Date();
                WxCUserCar userCar = new WxCUserCar();
                userCar.setCUserId(cUserId);
                userCar.setTenantId(tenantId);
                userCar.setCarNumber(_carNum);
                userCar.setVendorType(EnumCarVendor.CAR_ETCP.getCode());
                userCar.setCreateDate(curr);
                userCar.setUpdateDate(curr);
                wxCUserCarService.saveOrUpdate(userCar);
            }
        }
        return dataObj1;
    }

    private boolean isExistInArray(JSONArray arr, String carNumber) {
        boolean bExist = false;
        for (int i = 0; i < arr.size(); i++) {
            // check carNum+cUserId是否存在, 不存在新建
            String _carNum = arr.getString(i);

            if (carNumber.equals(_carNum)) {
                bExist = true;
                break;
            }
        }
        return bExist;
    }

    private boolean isExistInList(List<WxCUserCar> list, String carNumber) {
        boolean bExist = false;
        for (WxCUserCar userCar : list) {
            if (carNumber.equals(userCar.getCarNumber())) {
                bExist = true;
                break;
            }
        }
        return bExist;
    }

    /**
     * 绑车牌
     *
     * @param paramMap
     * @return
     */
    @ApiOperation(value = "绑车牌", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}, TJD:={\"carNumber\":\"string\"}")
    @PostMapping("/bindCar")
    public ResultData bindCar(@RequestBody Map<String, String> paramMap) {
        // 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        // 2. get vendor params
        if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
            return etcpBindCar(paramMap, park);
        } else {
            // 内部操作
            return bindCar(paramMap, park);
        }
    }

    private ResultData etcpBindCar(Map<String, String> paramMap, WxPark park) {
        String etcpToken = paramMap.get("etcpToken");
        if (StringUtils.isBlank(etcpToken)) {
            logger.error("etcpToken为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
        }
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            logger.error("carNumber为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String merchantNo = objParams.getString("merchantNo");
        String merchantKey = objParams.getString("merchantKey");
        String version = objParams.getString("version");

        String ret = "";
        try {
            ret = etcp.bindCar(url, merchantNo, merchantKey, version, etcpToken, carNumber, null);
        } catch (MallinkException e) {
            logger.error("ETCP failed: " + e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        }
        JSONObject retObj = JSON.parseObject(ret);
        if (retObj.getIntValue("code") == 0) {
            addCarInfoToDB(carNumber, EnumCarVendor.CAR_ETCP);
            JSONObject dataObj = retObj.getJSONObject("data");
            return new ResultData(dataObj);
        } else {
            String message = retObj.getString("message");
            logger.error("绑车牌失败: " + carNumber);
            return new ResultData(ErrorCode.ETCP_BIND_FAIL.getCode(), message, retObj);
        }
    }

    private ResultData bindCar(Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            logger.error("carNumber为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        try {
            addCarInfoToDB(carNumber, EnumCarVendor.getEnum(park.getVendorType()));
        } catch (MallinkException e) {
            return new ResultData(e.getErrorCode(), e.getMessage());
        } catch (Exception e) {
            return new ResultData(500, e.getMessage());
        }
        return new ResultData();
    }

    private void addCarInfoToDB(String carNumber, EnumCarVendor carVendor) {
        // 插入车牌
        Date curr = new Date();
        WxCUserCar userCar = new WxCUserCar();
        userCar.setCUserId(getUserId());
        userCar.setTenantId(getTenantId());
        userCar.setCarNumber(carNumber);
        userCar.setVendorType(carVendor.getCode());
        userCar.setCreateDate(curr);
        userCar.setUpdateDate(curr);
        wxCUserCarService.saveOrUpdate(userCar);

        // 成长值
        wxScoreRulesService.addScore(EnumScoreType.BIND_CAR, userCar);
        //增加积分
        addCredit();
        wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_CAR, getUserId());
    }

    private ResultData tjdBindCar(@RequestBody Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            logger.error("carNumber为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        String carNumColor = paramMap.get("carNumColor");
        //if (StringUtils.isBlank(carNumColor)) {
        //    logger.error("carNumColor为空");
        //   return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumColor为空");
        //}
        Long newCarId = 0L;
        String outCarId = paramMap.get("outCarId");
        if (StringUtils.isBlank(outCarId)) {
            logger.warn("outCarId为空");
            newCarId = wxCUserCarService.getNewCarID();
            outCarId = String.valueOf(newCarId);
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String partner = objParams.getString("partner");
        String key = objParams.getString("key");
        String version = objParams.getString("version");
        String ret = tjd.registerCar(url, partner, key, version,
                carNumber, carNumColor, null, outCarId);
        JSONObject retObj = JSON.parseObject(ret);
        retObj.put("vendor", park.getVendorType());
        if (retObj.getString("returnCode").equalsIgnoreCase(EnumTJDCode.SUCCESS.getMessage())) {
            ResultData e = tjdInsertToDB(carNumber, newCarId, retObj);
            if (e != null) return e;
            return new ResultData(retObj);
        } else {
            return new ResultData(ErrorCode.TJD_BIND_FAIL.getCode(), "绑车牌失败", retObj);
        }
    }

    private ResultData tjdInsertToDB(String carNumber, Long newCarId, JSONObject retObj) {
        String carId = retObj.getString("carId");
        // 插入车牌
        Date curr = new Date();
        WxCUserCar userCar = new WxCUserCar();
        userCar.setId(newCarId);
        userCar.setCUserId(getUserId());
        userCar.setTenantId(getTenantId());
        userCar.setCarNumber(carNumber);
        userCar.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        JSONObject jo = new JSONObject();
        jo.put("carId", carId);
        userCar.setVendorParams(JSON.toJSONString(jo));
        userCar.setCreateDate(curr);
        userCar.setUpdateDate(curr);
        try {
            wxCUserCarService.save(userCar);
            wxScoreRulesService.addScore(EnumScoreType.BIND_CAR, userCar);
            //增加积分
            addCredit();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.DB_FAIL.getCode(), "TJD保存车牌失败, e：" + e.getMessage());
        }

        wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_CAR, getUserId());
        return null;
    }

    //-----增加积分start-----
    private void addCredit() {
        WxCreditHistory wxCreditHistory = new WxCreditHistory();
        wxCreditHistory.setCUserId(getUserId());
        wxCreditHistory.setTenantId(getTenantId());
        wxCreditHistory.setCreateDate(new Date());
        wxCreditHistory.setCreditType(EnumScoreType.BIND_CAR.getCode());
        wxCreditHistory.setOperatorType(EnumUserType.CUSER.getCode());
        wxCreditHistory.setOperatorId(getUserId());
        wxCreditHistoryService.saveOrUpdate(wxCreditHistory);
    }

    /**
     * 解绑车牌
     *
     * @param paramMap
     * @return
     */
    @ApiOperation(value = "解绑车牌", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}\n返回:\n" +
            "{\n" +
            "  \"code\": 0,\n" +
            "  \"message\": \"ok\"" +
            "}" +
            "TJD:={\"carNumber\":\"string\"}")
    @PostMapping("/unbindCar")
    public ResultData unbindCar(@RequestBody Map<String, String> paramMap) {
        // 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        if (park.getVendorType().equals(EnumCarVendor.CAR_ETCP.getCode())) {
            return etcpUnbindCar(paramMap, park);
        } else {
            return unbindCar(paramMap, park);
        }
    }

    private ResultData etcpUnbindCar(Map<String, String> paramMap, WxPark park) {
        String etcpToken = paramMap.get("etcpToken");
        if (StringUtils.isBlank(etcpToken)) {
            logger.error("etcpToken为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
        }
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            logger.error("carNumber为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String merchantNo = objParams.getString("merchantNo");
        String merchantKey = objParams.getString("merchantKey");
        String version = objParams.getString("version");

        String ret = "";
        try {
            ret = etcp.unbindCar(url, merchantNo, merchantKey, version, etcpToken, carNumber);
        } catch (MallinkException e) {
            logger.error("ETCP failed: " + e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        }

        JSONObject retObj = JSON.parseObject(ret);
        if (retObj.getIntValue("code") == 0) {
            try {
                WxCUserCar userCar = new WxCUserCar();
                userCar.setCUserId(getUserId());
                userCar.setTenantId(getTenantId());
                userCar.setCarNumber(carNumber);
                wxCUserCarService.deleteByObj(userCar);
            } catch (Exception e) {
                logger.error(e.getMessage());
                return new ResultData(ErrorCode.DB_FAIL.getCode(), "解绑车牌数据库错误, e:" + e.getMessage());
            }

            return new ResultData();
        } else {
            String message = retObj.getString("message");
            logger.error("解绑车牌失败");
            return new ResultData(ErrorCode.ETCP_UNBIND_FAIL.getCode(), message, retObj);
        }
    }

    private ResultData unbindCar(Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            logger.error("carNumber为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        try {
            WxCUserCar userCar = new WxCUserCar();
            userCar.setTenantId(getTenantId());
            userCar.setCUserId(getUserId());
            userCar.setCarNumber(carNumber);
            wxCUserCarService.deleteByObj(userCar);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.DB_FAIL.getCode(), "解绑车牌数据库错误, e:" + e.getMessage());
        }

        return new ResultData();
    }

    private ResultData tjdUnbindCar(@RequestBody Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        WxCUserCar queryOne = new WxCUserCar();
        queryOne.setCarNumber(carNumber);
        queryOne.setTenantId(getTenantId());
        queryOne.setCUserId(getUserId());
        WxCUserCar userCar = wxCUserCarService.getOne(queryOne);
        if (userCar != null) {
            String params = userCar.getVendorParams();
            JSONObject objParams = JSON.parseObject(params);
            String carId = objParams.getString("carId");

            params = park.getVendorParams();
            String url = objParams.getString("url");
            String partner = objParams.getString("partner");
            String key = objParams.getString("key");
            String version = objParams.getString("version");
            String ret = tjd.writeOffCar(url, partner, key, version, carId);
            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getString("returnCode").equalsIgnoreCase(EnumTJDCode.SUCCESS.getMessage())) {
                try {
                    wxCUserCarService.deleteByObj(userCar);
                } catch (Exception e) {
                    logger.error("解绑车牌数据库错误, e:" + e.getMessage());
                    return new ResultData(ErrorCode.DB_FAIL.getCode(), "解绑车牌数据库错误, e:" + e.getMessage());
                }

                return new ResultData();
            } else {
                return new ResultData(ErrorCode.TJD_UNBIND_FAIL, "解绑车牌失败");
            }
        }
        return null;
    }

    /**
     * 停车费
     *
     * @param paramMap
     * @return
     */
    @ApiOperation(value = "停车费", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}\n输出\n{\n" +
            "                    \"carNumber\": \"渝****87\",\n" +
            "                    \"entranceTime\": \"2017-06-11 11:19:27\",\n" +
            "                    \"exitTime\": \"2017-06-11 11:59:47\",\n" +
            "                    \"orderId\": \"B9466E26-7420-4BDF-958D-E90106AB5F20\", \"parkingFee\": 2.00，\n" +
            "                    \"remainingServiceFee\": 0,\n" +
            "                    \"payedServiceFee\": 0,\n" +
            "                    \"remainingParkFee\": 2.00,\n" +
            "                    \"discountAmount\": 0,\n" +
            "                    \"parkingId\": 3126,\n" +
            "                    \"parkingName\": \"ETCP 停车场\",\n" +
            "                    \"remainingFee\": 2.00，\n" +
            "                    \"paidFee\": 0,\n" +
            "                    \"verificationInfo\": \"FSED9JvxgAU6XJUd8YRF5YH/LpfQYzCAfcPbAOKPV3BjKSatbgIsh7EBH2JBiRoGBe3btr gzKRMTfIoFuCn1XX7HUsJYlb7JSCBArnNmEVU4JuDLLjzoqB7qhQ8KnP16\"\n" +
            "                 }" +
            "TJD:={\"carNumber\":\"string\"}\n输出\n{\n" +
            "                  \"inDt\": \"20160526112000\",\n" +
            "                  \"timestamp\": \"1464235239561\",\n" +
            "                  \"returnCode\": \"T\",\n" +
            "                  \"errorMsg\": \"\",\n" +
            "                  \"tradeId\": \"d49aeaedcf144f1faf569846d6b1667e\",\n" +
            "                  \"parkTime\": \"2439593\",\n" +
            "                  \"returnMsg\": \"OK\",\n" +
            "                  \"totalAmount\": \"0.03\",\n" +
            "                  \"isSuccess\": \"0\",\n" +
            "                  \"unPayAmount\": \"0.03\",\n" +
            "                  \"paidAmount\": \"0.00\",\n" +
            "                  \"freeThroughTime\": \"15\",\n" +
            "                  \"outDt\": \"20170321121212\",\n" +
            "                  \"payUrl\": \"http://prep.tingjiandan.com/tcweixin/letter/prePay/payInPark.html?\n" +
            "                   prePayType=16&channel=10001\",\n" +
            "                  \"accountId\": \"d49aeaedcf144f1faf569846d6b16671\",\n" +
            "                  \"freeMinsAmount\": \"0.00\",\n" +
            "                  \"pmParkId\": \"d49aeaedcf144f1faf569846d6b16670\"\n" +
            "              }")
    @PostMapping("/getCarStopFee")
    public ResultData getCarStopFee(@RequestBody Map<String, String> paramMap) {
        // 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        if (park.getVendorType().equals(EnumCarVendor.CAR_ETCP.getCode())) {
            return etcpCarStopFee(paramMap, park);
        } else if (park.getVendorType().equals(EnumCarVendor.CAR_TJD.getCode())) {
            return tjdCarStopFee(paramMap, park);
        } else if (park.getVendorType().equals(EnumCarVendor.CAR_DAHUA.getCode())) {
            return dahuaCarStopFee(paramMap, park);
        }
        return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "停车费获取失败");
    }

    private ResultData dahuaCarStopFee(Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        String result = DaHuaUtil.plateCharge(carNumber, park.getParkId());
        logger.info("大华查询车辆费用接口返回值:{}", result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String code = jsonObject.getString("code");
        if (!code.equals(DaHuaUtil.SUCCESS_CODE)) {
            return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "停车费获取失败");
        }
        Object data = jsonObject.get("data");
        return new ResultData(data);
    }

    private ResultData etcpCarStopFee(@RequestBody Map<String, String> paramMap, WxPark park) {
        String etcpToken = paramMap.get("etcpToken");
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(etcpToken)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
        }
        if (StringUtils.isBlank(carNumber)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String appId = objParams.getString("appId");
        String merchantNo = objParams.getString("merchantNo");
        String merchantKey = objParams.getString("merchantKey");
        String version = objParams.getString("version");

        String ret = "";
        try {
            ret = etcp.orderUnpay(url, appId, merchantNo, merchantKey, version, etcpToken, carNumber);
        } catch (MallinkException e) {
            logger.error("ETCP failed: " + e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        }

        JSONObject retObj = JSON.parseObject(ret);
        if (retObj.getIntValue("code") == 0) {
            JSONObject feeObj = retObj.getJSONArray("data").getJSONObject(0);
            /*
            Date currentDate = new Date();
            WxCarCmdLog wxCarCmdLog = new WxCarCmdLog();
            wxCarCmdLog.setTenantId(user.getTenantId());
            wxCarCmdLog.setVendorType(EnumCarVendor.CAR_ETCP.getCode());
            wxCarCmdLog.setCmdType(EnumCarCmd.CAR_ETCP_CALLBACK_UNPAY.getCode());
            String feeStr = JSON.toJSONString(feeObj);
            wxCarCmdLog.setCmdJson(feeStr);
            wxCarCmdLog.setCreateDate(currentDate);
            wxCarCmdLog.setUpdateDate(currentDate);
            try {
                wxCarCmdLogService.saveOrUpdate(wxCarCmdLog);
            } catch (Exception e) {
                logger.error("etcpOrderUnpay: 入库错误:" + feeStr);
                return new ResultData(ErrorCode.DB_FAIL.getCode(), "入库错误", feeStr);
            }
            */
            return new ResultData(Result.SUCCESS, "停车费获取成功", feeObj);
        } else {
            String message = retObj.getString("message");
            return new ResultData(ErrorCode.ETCP_STOP_FEE_FAIL.getCode(), message, retObj);
        }
    }

    private ResultData tjdCarStopFee(@RequestBody Map<String, String> paramMap, WxPark park) {
        String carNumber = paramMap.get("carNumber");
        if (StringUtils.isBlank(carNumber)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        String params = park.getVendorParams();
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString(TJDUtil.TJD_URL);
        String partner = objParams.getString(TJDUtil.TJD_ACCOUNT);
        String key = objParams.getString(TJDUtil.TJD_ACCOUNT_KEY);
        String version = objParams.getString(TJDUtil.TJD_VERSION);
        String ret = tjd.infoForFreeMins(url, partner, key, version, carNumber);
        JSONObject retObj = JSON.parseObject(ret);
        if (retObj.getString(TJDUtil.TJD_RETURN_CODE).equalsIgnoreCase(EnumTJDCode.SUCCESS.getMessage())) {
            return new ResultData(retObj);
        } else {
            return new ResultData(ErrorCode.TJD_STOP_FEE_FAIL.getCode(), "停车费获取失败");
        }
    }

    private String getETCPBusinessID(Long merchantId) {
        String businessId;
        WxMerchant wxMerchant = wxMerchantService.getById(merchantId);
        String carParams = wxMerchant.getCarParams();
        JSONObject objParams1 = JSON.parseObject(carParams);
        businessId = objParams1.getString("businessId");
        return businessId;
    }

    /**
     * 优免券领取
     * 优免券不可退
     */
    @ApiOperation(value = "停车券使用", notes = "ETCP:={\"etcpToken\":\"string(ETCP专用)\",\"carNumber\":\"string\",\"couponOrderId\"=\"String\"}，输出\n{}\n" +
            "TJD:{\"carNumber\":\"string\",\"tradeId\":\"string\",\"accountId\":\"string\",\"couponOrderId\":\"string\"}")
    @PostMapping("/getCoupon")
    public ResultData getCoupon(@RequestBody Map<String, String> paramMap) {
        /// 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        String carNumber = paramMap.get("carNumber");
        String couponOrderIdStr = paramMap.get("couponOrderId");
        if (StringUtils.isBlank(carNumber)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
        }
        if (StringUtils.isBlank(couponOrderIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponOrderId为空");
        }
        Long couponOrderId = 0L;
        try {
            couponOrderId = Long.valueOf(couponOrderIdStr);
        } catch (NumberFormatException e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponOrderId转化失败");
        }

        WxCouponOrderCarCVo userCar = null;
        WxCouponOrder userCarQ = new WxCouponOrder();
        userCarQ.setTenantId(getTenantId());
        userCarQ.setCUserId(getUserId());
        userCarQ.setId(couponOrderId);
        userCarQ.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode());
        List<WxCouponOrderCarCVo> list = wxCouponOrderService.carListCUserVo(userCarQ);
        if (list.size() > 0) {
            userCar = list.get(0);
        }

        if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
            String etcpToken = paramMap.get("etcpToken");
            if (StringUtils.isBlank(etcpToken)) {
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
            }
            String params = park.getVendorParams();
            JSONObject objParams = JSON.parseObject(params);
            String url = objParams.getString("url");
            String merchantNo = objParams.getString("merchantNo");
            String merchantKey = objParams.getString("merchantKey");
            String version = objParams.getString("version");
            String businessId = "";
            // 获取merchantId
            WxMerchantVo merchantVo = null;
            if (userCar.getMerchantVoList().size() > 0) {
                merchantVo = userCar.getMerchantVoList().get(0);
            }

            // 优先从从商户表里取
            businessId = getETCPBusinessID(merchantVo.getId());
            if (StringUtils.isBlank(businessId)) {
                // 1期只有一个虚拟商户，可以写在商场配置里
                businessId = objParams.getString("businessId");
            }

            String ret = "";
            try {
                ret = etcp.bCouponRecord(url, merchantNo, merchantKey, version,
                        etcpToken, park.getParkId(), businessId, carNumber, String.valueOf(userCar.getCouponFreeId()));
            } catch (MallinkException e) {
                logger.error("ETCP failed: " + e.getMessage());
                return new ResultData(e.getErrorCode(), e.getMessage());
            }
            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) {

                // 券状态设为已使用
                WxCouponOrder couponOrder = new WxCouponOrder();
                couponOrder.setId(userCar.getId());
                couponOrder.setTenantId(getTenantId());
                couponOrder.setUpdateDate(new Date());
                couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USED.getCode());
                try {
                    wxCouponOrderService.saveOrUpdate(couponOrder);
                } catch (Exception e) {
                    logger.error("券包状态更新失败:" + couponOrderIdStr);
                    return new ResultData(ErrorCode.DB_FAIL.getCode(), "券包状态更新失败");
                }
                return new ResultData();
            } else {
                return new ResultData(ErrorCode.ETCP_QUAN_SEND_FAIL.getCode(), retObj.getString("message"));
            }
        } else if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()) {
            String tradeId = paramMap.get("tradeId");
            String accountId = paramMap.get("accountId");
            if (StringUtils.isBlank(tradeId)) {
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "tradeId为空");
            }
            if (StringUtils.isBlank(accountId)) {
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "accountId为空");
            }
            WxCoupon coupon = couponService.getById(userCar.getCouponId());
            if (coupon == null) {
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "券为空");
            }
            String params = park.getVendorParams();
            JSONObject objParams = JSON.parseObject(params);
            String url = objParams.getString(TJDUtil.TJD_URL);
            String partner = objParams.getString(TJDUtil.TJD_ACCOUNT);
            String key = objParams.getString(TJDUtil.TJD_ACCOUNT_KEY);
            String version = objParams.getString(TJDUtil.TJD_VERSION);

            String ret = tjd.deductionForDetail(url, partner, key, version,
                    tradeId, accountId, userCar, coupon);
            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getString(TJDUtil.TJD_RETURN_CODE).equalsIgnoreCase(EnumTJDCode.SUCCESS.getMessage())) {
                return new ResultData();
            } else {
                return new ResultData(ErrorCode.TJD_DEDUCE_FEE_FAIL.getCode(), "停车费抵扣失败");
            }
        }
        return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "优免券领取失败");
    }

    @ApiOperation("券包分页列表接口")
    @GetMapping("/couponOrderList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true),
    })
    public ResultData list(@ModelAttribute WxCouponOrder wxCouponOrder, Integer pageNum, Integer pageSize) {

        if (pageNum == null || pageSize == null) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL);
        }
        if (wxCouponOrder == null) wxCouponOrder = new WxCouponOrderCarCVo();
        wxCouponOrder.setTenantId(getTenantId());
        wxCouponOrder.setCUserId(getUserId());
        if (wxCouponOrder.getCouponOrderStatus() == null)
            wxCouponOrder.setSortColumns(BaseEntity.SortField.CreateDate_DESC);
        else if (wxCouponOrder.getCouponOrderStatus() == EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())
            wxCouponOrder.setSortColumns(BaseEntity.SortField.CreateDate_DESC);
        else
            wxCouponOrder.setSortColumns(BaseEntity.SortField.UpdateDate_DESC);
        return wxCouponOrderService.carListCUserVoAsPage(wxCouponOrder, pageNum, pageSize);
    }

    @ApiOperation(value = "停车场状态")
    @GetMapping("/getParkStatus")
    public ResultData getParkStatus() {
        /// 1, get mall's park
        WxPark park = getCurrentPark(getTenantId());
        if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
            ResultData e = etcpParkStatus(park);
            if (e != null) return e;
        }
        return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "车场不支持");
    }

    private ResultData etcpParkStatus(WxPark park) {
        String params = park.getVendorParams();
        if (params == null) {
            return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "车场不支持");
        }
        JSONObject objParams = JSON.parseObject(params);
        String url = objParams.getString("url");
        String merchantNo = objParams.getString("merchantNo");
        String merchantKey = objParams.getString("merchantKey");
        String version = objParams.getString("version");
        if (park.getParkingId() == null) {
            // those code is not supported
            /*
            String lat = objParams.getString("lat");
            String lon = objParams.getString("lon");
            String radius = objParams.getString("radius");
            String ret = etcp.parkingInfo(url, merchantNo, merchantKey, version, lat, lon, radius);
            logger.info(ret);
            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) {
                JSONObject retData = retObj.getJSONObject("data");
                if (retData != null) {
                    JSONArray retDataList = retData.getJSONArray("list");
                    if (retDataList != null) {
                        JSONObject parkData = retDataList.getJSONObject(0);
                        if (parkData != null) {
                            String parkId = parkData.getString("id");
                            objParams.put("parkId", parkId);
                            params = JSON.toJSONString(objParams);
                            park.setVendorParams(params);
                            park.setParkingId(parkId);
                            wxParkService.saveOrUpdate(park);
                        }
                    }
                }
            }
            */
        }

        if (park.getParkingId() != null) {
            String ret = "";
            try {
                ret = etcp.parkingStatus(url, merchantNo, merchantKey, version, park.getParkingId());
            } catch (MallinkException e) {
                logger.error("ETCP failed: " + e.getMessage());
                return new ResultData(e.getErrorCode(), e.getMessage());
            }

            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) {
                if (retObj.get("data") != null) {
                    return new ResultData(retObj.getJSONObject("data"));
                }
            }
        }
        return null;
    }


}
