package com.iformall.controller.callback;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.*;
import com.iformall.enums.EnumCarCmd;
import com.iformall.enums.EnumCarVendor;
import com.iformall.enums.EnumCouponSendSendType;
import com.iformall.service.*;
import com.iformall.utils.DateUtils;
import com.iformall.utils.car.TJDUtil;
import org.apache.commons.collections.CollectionUtils;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@RequestMapping("/carCallback")
public class WxCarTJDCallBackController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxParkService wxParkService;

    @Autowired
    WxCUserCarService wxCUserCarService;

    @Autowired
    WxMerchantService wxMerchantService;

    @Autowired
    WxCarCmdLogService wxCarCmdLogService;

    @Autowired
    WxCouponSendService wxCouponSendService;

    @Autowired
    WxCarPayRecordService wxCarPayRecordService;

    @Autowired
    WxCUserService wxCUserService;

	/**
     * 注册车牌
     * @param paramMap
     * @return
     * {
     *    "service": "parkhub.car.register",
     *    "partner": "5836b8b51ada463ebc6199579f029566", "sign": "3347b109a1e44f3fd5baa78b74184948", "signType": "md5",
     *    "charset": "utf-8",
     *    "version": "1.0",
     *    "timestamp": "2016-05-26 11:30:10",
     *    "carNum": "京A12345",
     *    "carNumColor": "blue",
     *    "phone": "13612341234",
     *    "outCarId": "432d85d7441316d29504f480e6a734a8"
     * }
     * {
     *    "timestamp": "1464235239561",
     *    "returnCode": "T",
     *    "returnMsg": "OK",
     *    "isSuccess": "0",
     *    "errorMSG": "",
     *    "carId": "11ce3dca34124e97830ad466e532eda7"
     * }
     */
    @RequestMapping(value = "/tjdRegisterCallback")
    public Map tjdRegisterCallback(@RequestBody Map<String, String> paramMap) {
        Map map = new HashMap();
        return map;
    }
	
    /**
     * 进场通知
     * {
     *   wLon=116.310335,
     *   lon=116.316813,
     *   outCarId=,
     *   parkId=7715622dff834b34a44448b801c27607,
     *   tradeId=e9e0d5db057f412fa323995fc292f6f7,
     *   carNumColor=blue,
     *   canFindCar=0,
     *   miniProgram={
     *      "path": "pages/pre_pay/index/main",
     *      "extraData": {
     *         "prePayType": "16",
     *         "channel": "30166",
     *         "isShowDetail": "true",
     *         "partnerId": "",
     *         "orderId": "e9e0d5db057f412fa323995fc292f6f7"}
     *   },
     *   city=北京市,
     *   parkName=开发停车场25,
     *   address=财智大厦23楼,
     *   carNum=京YTJD01,
     *   wLat=39.93609,
     *   payUrl=https://prep.tingjiandan.com/tcweixin/letter/prePay/pagePayInPark?prePayType=16&channel=30166&isShowDetail=true&partnerId=&orderId=e9e0d5db057f412fa323995fc292f6f7&returnUrl=,
     *   district=海淀区,
     *   lat=39.942078,
     *   inDt=20190920070500
     * }
     */
    @RequestMapping(value = "/tjdParkInCallback")
    public Map tjdParkInCallback(@RequestBody Map<String, String> paramMap) {
        logger.info("["+getIpAddr()+"tjdParkInCallback: " + paramMap.toString());
        Map map = new HashMap();
        Date currentDate = new Date();

        String parkId = paramMap.get(TJDUtil.TJD_PARK_ID);
        String parkName = paramMap.get(TJDUtil.TJD_PARK_NAME);
        String carNumber = paramMap.get(TJDUtil.TJD_CAR_NUMBER);
        String tradeId = paramMap.get(TJDUtil.TJD_TRADE_ID);
        String inDt = paramMap.get(TJDUtil.TJD_IN_DT);

        WxCarCmdLog wxCarCmdLog = new WxCarCmdLog();
        wxCarCmdLog.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        wxCarCmdLog.setCmdType(EnumCarCmd.CAR_TJD_CALLBACK_PARK_IN.getCode());
        wxCarCmdLog.setCmdJson(JSON.toJSONString(paramMap));
        wxCarCmdLog.setCreateDate(currentDate);
        wxCarCmdLog.setUpdateDate(currentDate);

        String tenantId = null;
        WxPark parkQ = new WxPark();
        parkQ.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        parkQ.setParkId(parkId);
        WxPark park = wxParkService.getByObj(parkQ);
        if (park == null) {
            logger.error("tjdParkInCallback: 车场未找到" + parkId);
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_1);
            map.put(TJDUtil.TJD_ERR_MSG, "车场未找到" + parkId);
            return map;
        } else {
            tenantId = park.getTenantId();
            wxCarCmdLog.setTenantId(park.getTenantId());
        }

        try {
            wxCarCmdLogService.saveOrUpdate(wxCarCmdLog);
        } catch (Exception e) {
            logger.error("tjdParkInCallback: 入库错误" + paramMap.toString());
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_2);
            map.put(TJDUtil.TJD_ERR_MSG, "入库错误" + paramMap.toString());
            return map;
        }

        // 停车发券
        String phoneStrs = "";
        if (StringUtils.isNotBlank(carNumber)) {
            // 根据车牌查找用户
            WxCUserCar userCarQ = new WxCUserCar();
            userCarQ.setTenantId(tenantId);
            userCarQ.setCarNumber(carNumber);
            userCarQ.setVendorType(EnumCarVendor.CAR_ETCP.getCode());
            // TODO 可能多用户关联同一张车牌
            List<WxCUserCar> userCarList = wxCUserCarService.getList(userCarQ);
            boolean bFirst = true;
            for (WxCUserCar userCar : userCarList) {
                wxCouponSendService.sendCouponToUser(EnumCouponSendSendType.CAR_STOP, userCar);
                WxCUser cUser = wxCUserService.getById(userCar.getCUserId());
                if(cUser != null){
                    if(bFirst) {
                        phoneStrs = cUser.getPhone();
                        bFirst = false;
                    } else {
                        phoneStrs += "," + cUser.getPhone();
                    }
                }
            }
        }

        try {
            // 保存WxCarPayRecord
            WxCarPayRecord record = new WxCarPayRecord();
            record.setTenantId(tenantId);
            record.setVendorType(wxCarCmdLog.getVendorType());
            record.setSynId(tradeId);
            record.setParkId(parkId);
            record.setParkName(parkName);
            record.setPlateNumber(carNumber);
            if(StringUtils.isNotBlank(inDt)) {
                record.setEntranceTime(TJDUtil.dateOutFormat.parse(inDt));
            }
            record.setPhone(phoneStrs);
            WxCarPayRecord query = new WxCarPayRecord();
            query.setTenantId(tenantId);
            query.setParkId(parkId);
            query.setSynId(tradeId);
            PageInfo<WxCarPayRecord> page = wxCarPayRecordService.findCarPayListByPage(query,1,1);
            if(page != null && CollectionUtils.isNotEmpty(page.getList())){
                record.setId(page.getList().get(0).getId());
            }
            wxCarPayRecordService.saveOrUpdate(record);
        } catch (Exception e) {
            logger.error("WxCarPayRecord: 入库错误 "+e.getMessage()+"," + paramMap.toString());
        }

        map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_SUC);
        return map;
    }

    /**
     * 离场通知
     * {
     *    "parkId": "f3f11a46f3a14056953aed97944242d4",
     *    "parkName": "测试停车场",
     *    "carNum": "京A12345",
     *    "carNumColor ": "blue",
     *    "tradeId": "5836b8b52ada463ebc6199579f029565",
     *    "inDt": "20170319232020",
     *    "outDt": "20170319232020",
     *    "parkAmount": "5.20",
     *    "lon": "74.000272",
     *    "lat": "159.768703",
     *    "wLon": "123.523032",
     *    "wLat": "35.430735"
     * }
     */
    @RequestMapping(value = "/tjdParkOutCallback")
    public Map tjdParkOutCallback(@RequestBody Map<String, String> paramMap) {
        logger.info("["+getIpAddr()+"tjdParkOutCallback: " + paramMap.toString());
        Map map = new HashMap();

        String parkId = paramMap.get(TJDUtil.TJD_PARK_ID);
        String parkName = paramMap.get(TJDUtil.TJD_PARK_NAME);
        String carNumber = paramMap.get(TJDUtil.TJD_CAR_NUMBER);
        String tradeId = paramMap.get(TJDUtil.TJD_TRADE_ID);
        String inDt = paramMap.get(TJDUtil.TJD_IN_DT);
        String outDt = paramMap.get(TJDUtil.TJD_OUT_DT);
        String stopFee = paramMap.get(TJDUtil.TJD_PARK_AMT);

        Date currentDate = new Date();
        WxCarCmdLog wxCarCmdLog = new WxCarCmdLog();
        wxCarCmdLog.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        wxCarCmdLog.setCmdType(EnumCarCmd.CAR_TJD_CALLBACK_PARK_OUT.getCode());
        wxCarCmdLog.setCmdJson(JSON.toJSONString(paramMap));
        wxCarCmdLog.setCreateDate(currentDate);
        wxCarCmdLog.setUpdateDate(currentDate);

        String tenantId = null;
        WxPark parkQ = new WxPark();
        parkQ.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        parkQ.setParkId(parkId);
        WxPark park = wxParkService.getByObj(parkQ);
        if (park == null) {
            logger.error("tjdParkOutCallback: 车场未找到" + parkId);
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_1);
            map.put(TJDUtil.TJD_ERR_MSG, "车场未找到" + parkId);
            return map;
        } else {
            tenantId = park.getTenantId();
            wxCarCmdLog.setTenantId(tenantId);
        }

        try {
            wxCarCmdLogService.saveOrUpdate(wxCarCmdLog);
        } catch (Exception e) {
            logger.error("tjdParkOutCallback: 入库错误" + paramMap.toString());
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_2);
            map.put(TJDUtil.TJD_ERR_MSG, "入库错误" + paramMap.toString());
            return map;
        }

        try {
            // 保存WxCarPayRecord
            WxCarPayRecord record = new WxCarPayRecord();
            record.setTenantId(tenantId);
            record.setVendorType(wxCarCmdLog.getVendorType());
            record.setParkId(parkId);
            record.setParkName(parkName);
            record.setPlateNumber(carNumber);
            record.setSynId(tradeId);
            if(StringUtils.isNotBlank(inDt)) {
                record.setEntranceTime(TJDUtil.dateOutFormat.parse(inDt));
            }
            if(StringUtils.isNotBlank(outDt)) {
                record.setExitTime(TJDUtil.dateOutFormat.parse(outDt));
                Long stayedTime = (record.getExitTime().getTime() - record.getEntranceTime().getTime())/ 1000;
                record.setStayedTime(stayedTime);
            }
            if (StringUtils.isNotBlank(stopFee)) {
                record.setFee(stopFee);
            }
            WxCarPayRecord query = new WxCarPayRecord();
            query.setTenantId(tenantId);
            query.setParkId(parkId);
            query.setSynId(tradeId);
            PageInfo<WxCarPayRecord> page = wxCarPayRecordService.findCarPayListByPage(query,1,1);
            if(page != null && CollectionUtils.isNotEmpty(page.getList())){
                record.setId(page.getList().get(0).getId());
            }
            wxCarPayRecordService.saveOrUpdate(record);
        } catch (Exception e) {
            logger.error("WxCarPayRecord: 出场更新错误 " +e.getMessage()+", " +paramMap.toString());
        }

        map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_SUC);
        return map;
    }

    /**
     * 支付通知
     * {
     *    "parkId ": "77a3424e06e64248b4cf9e490c8c682d",
     *    "parkName ": "测试停车场",
     *    "carNum": "京A12345",
     *    "carNumColor": "blue",
     *    "tradeId": "6d697f7579724345881633a00ed3a671",
     *    "payAmount": "5.00",
     *    "payDt": "20180516225701",
     *    "lon": "74.000272",
     *    "lat": "159.768703",
     *    "wLon": "123.523032",
     *    "wLat": "35.430735"
     * }
     */
    @RequestMapping(value = "/tjdPaidCallback")
    public Map tjdPaidCallback(@RequestBody Map<String, String> paramMap) {
        logger.info("["+getIpAddr()+"tjdPaidCallback: " + paramMap.toString());
        Date currentDate = new Date();
        Map map = new HashMap();

        String parkId = paramMap.get(TJDUtil.TJD_PARK_ID);
        String parkName = paramMap.get(TJDUtil.TJD_PARK_NAME);
        String carNumber = paramMap.get(TJDUtil.TJD_CAR_NUMBER);
        String tradeId = paramMap.get(TJDUtil.TJD_TRADE_ID);
        String stopFee = paramMap.get(TJDUtil.TJD_PAY_AMT);
        String stopFeeTime = paramMap.get(TJDUtil.TJD_PAY_DT);

        WxCarCmdLog wxCarCmdLog = new WxCarCmdLog();
        wxCarCmdLog.setVendorType(EnumCarVendor.CAR_ETCP.getCode());
        wxCarCmdLog.setCmdType(EnumCarCmd.CAR_TJD_CALLBACK_PAID.getCode());
        wxCarCmdLog.setCmdJson(JSON.toJSONString(paramMap));
        wxCarCmdLog.setCreateDate(currentDate);
        wxCarCmdLog.setUpdateDate(currentDate);

        String tenantId = null;
        WxPark parkQ = new WxPark();
        parkQ.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        parkQ.setParkId(parkId);
        WxPark park = wxParkService.getByObj(parkQ);
        if (park == null) {
            logger.error("tjdPaidCallback: 车场未找到" + parkId);
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_1);
            map.put(TJDUtil.TJD_ERR_MSG, "车场未找到" + parkId);
            return map;
        } else {
            tenantId = park.getTenantId();
            wxCarCmdLog.setTenantId(tenantId);
        }

        try {
            wxCarCmdLogService.saveOrUpdate(wxCarCmdLog);
        } catch (Exception e) {
            logger.error("tjdPaidCallback: 入库错误" + paramMap.toString());
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_2);
            map.put(TJDUtil.TJD_ERR_MSG, "入库错误" + paramMap.toString());
            return map;
        }

        try {
            // 保存WxCarPayRecord
            WxCarPayRecord record = new WxCarPayRecord();
            record.setTenantId(tenantId);
            record.setVendorType(wxCarCmdLog.getVendorType());
            record.setParkId(parkId);
            record.setParkName(parkName);
            record.setPlateNumber(carNumber);
            record.setSynId(tradeId);
            record.setFee(stopFee);
            if (StringUtils.isNotBlank(stopFeeTime)) {
                record.setFeeTime(TJDUtil.dateOutFormat.parse(stopFeeTime));
            }

            WxCarPayRecord query = new WxCarPayRecord();
            record.setTenantId(tenantId);
            record.setParkId(parkId);
            record.setPlateNumber(carNumber);
            query.setSynId(tradeId);
            PageInfo<WxCarPayRecord> page = wxCarPayRecordService.findCarPayListByPage(query,1,2);
            if(page != null && page.getList().size() > 0){

                if(page.getList().size() >= 2){
                    wxCarPayRecordService.saveOrUpdate(record);
                } else {
                    WxCarPayRecord r = page.getList().get(0);
                    if(r.getFeeTime() == null) {
                        // 无缴费信息， 更新
                        record.setId(r.getId());
                        wxCarPayRecordService.saveOrUpdate(record);
                    } else {
                        // 缴费时间在15分钟以内，更新之前的数据, ETCP会把之前的缴费自动退款
                        if(DateUtils.isInDate15Mins(record.getFeeTime(), r.getFeeTime())) {
                            record.setId(r.getId());
                        }
                        wxCarPayRecordService.saveOrUpdate(record);
                    }
                }
            } else {
                wxCarPayRecordService.saveOrUpdate(record);
            }
        } catch (Exception e) {
            logger.error("WxCarPayRecord: 缴费更新错误 " +e.getMessage()+", "+ paramMap.toString());
            //return new Result(ErrorCode.DB_FAIL.getCode(), "入库错误" + paramMap.toString());
        }

        map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_SUC);
        return map;
    }

    /**
     * 退款通知 (仅当接入方作为第一收款方时适用)
     * {
     *    "parkId ": "77a3424e06e64248b4cf9e490c8c682d",
     *    "parkName ": "测试停车场",
     *    "carNum": "京A12345",
     *    "carNumColor": "blue",
     *    "tradeId": "6d697f7579724345881633a00ed3a671",
     *    "payAmount": "5.00",
     *    "payDt": "20180516225701",
     *    "lon": "74.000272",
     *    "lat": "159.768703",
     *    "wLon": "123.523032",
     *    "wLat": "35.430735"
     * }
     */
    @RequestMapping(value = "/tjdRefundCallback")
    public Map tjdRefundCallback(@RequestBody Map<String, String> paramMap) {
        logger.info("["+getIpAddr()+"tjdRefundCallback: " + paramMap.toString());
        Date currentDate = new Date();
        Map map = new HashMap();

        String tjdParkId = paramMap.get(TJDUtil.TJD_PARK_ID);
        String carNumber = paramMap.get(TJDUtil.TJD_CAR_NUMBER);
        String tradeId = paramMap.get(TJDUtil.TJD_TRADE_ID);

        WxCarCmdLog wxCarCmdLog = new WxCarCmdLog();
        wxCarCmdLog.setVendorType(EnumCarVendor.CAR_ETCP.getCode());
        wxCarCmdLog.setCmdType(EnumCarCmd.CAR_TJD_CALLBACK_REFUND.getCode());
        wxCarCmdLog.setCmdJson(JSON.toJSONString(paramMap));
        wxCarCmdLog.setCreateDate(currentDate);
        wxCarCmdLog.setUpdateDate(currentDate);

        String tenantId = null;
        WxPark parkQ = new WxPark();
        parkQ.setVendorType(EnumCarVendor.CAR_TJD.getCode());
        parkQ.setParkId(tjdParkId);
        WxPark park = wxParkService.getByObj(parkQ);
        if (park == null) {
            logger.error("tjdRefundCallback: 停简单车场未找到" + tjdParkId);
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_1);
            map.put(TJDUtil.TJD_ERR_MSG, "车场未找到" + tjdParkId);
            return map;
        } else {
            tenantId = park.getTenantId();
            wxCarCmdLog.setTenantId(tenantId);
        }

        try {
            wxCarCmdLogService.saveOrUpdate(wxCarCmdLog);
        } catch (Exception e) {
            logger.error("tjdRefundCallback: 入库错误" + paramMap.toString());
            map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_ERR_2);
            map.put(TJDUtil.TJD_ERR_MSG, "入库错误" + paramMap.toString());
            return map;
        }

        map.put(TJDUtil.TJD_IS_SUC, TJDUtil.TJD_SUC);
        return map;
    }

}
