package com.iformall.controller.car;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.annotation.SystemControllerLog;
import com.iformall.common.ErrorCode;
import com.iformall.common.ResultData;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.WxCouponCarVo;
import com.iformall.enums.EnumCarVendor;
import com.iformall.enums.EnumCouponStatus;
import com.iformall.enums.EnumETCPCode;
import com.iformall.enums.EnumRentContractAppStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxCouponMapper;
import com.iformall.service.*;
import com.iformall.utils.car.ETCPUtil;
import com.iformall.utils.car.TJDUtil;
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.Map;

@RestController
@RequestMapping("/car")
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
    WxCarCmdLogService wxCarCmdLogService;

    @Autowired
    WxCouponService wxCouponService;

    @Autowired
    WxCouponCarService wxCouponCarService;

    @Autowired
    WxFlowService wxFlowService;

    @Autowired
    WxCouponMapper wxCouponMapper;

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

    @ApiOperation(value = "获取车场支持的厂家", notes = "{}")
    @GetMapping("/getVendor")
    @SystemControllerLog(description = "车-获取车场支持的厂家")
    public ResultData getVendor() {
        logger.debug("[" + getIpAddr() + "] WxCarController::getVendor");
        // 1, get mall's park
        WxPark park = getCurrentPark();
        Map map = new HashMap();
        map.put("vendor", park.getVendorType());
        return new ResultData(map);
    }

    // 优免券模板
    /*
    {
         "id": 4974, //优免券模板 ID
         "parkId": "fbqXUlfVvfc=", //车场标识
         "businessId": "ZcWQ26TeJuQ=", //商家标识
         title -- "businessName": "天洋广场", //商家名称
         subtitle -- "name": "商家 1 小时优免券", //优免券名称
         "category": "1", //优免券类型 1:小时优惠券，2:金额优惠券，3:折扣优惠券，4:免费券
         price -- "categoryValue": "1.00", //优免券价值
         total -- "amount": 100000, //优免券数量
         valid_start_date -- "effectiveStart": "2018-02-01", //生效开始时间
         valid_end_date -- "effectiveEnd": "2028-02-01",//生效结束时间
         -"couponType": "0",//优惠券类型
         number 库存     -- "avaliavleNum": 99993 //可用优惠券
     },
     */
    @ApiOperation(value = "优免券模板", notes = "{\"merchantId\":\"商户ID\"}\n输出\n" +
            "{\n" +
            "\"data\":{" +
            "\"count\": 4," +
            "\"couponPlatformModels\": [\n" +
            "  {\n" +
            "    \"id\": 4974, //优免券模板 ID\n" +
            "    \"parkId\": \"fbqXUlfVvfc=\", //车场标识" +
            "    \"businessId\": \"ZcWQ26TeJuQ=\", //商家标识" +
            "    \"businessName\": \"天洋广场\", //商家名称" +
            "    \"name\": \"商家 1 小时优免券\", //优免券名称" +
            "    \"category\": \"1\", //优免券类型\n 1:小时优惠券，2:金额优惠券，3:折扣优惠券，4:免费券" +
            "    \"categoryValue\": \"1.00\", //优免券价值\n" +
            "    \"amount\": 100000, //优免券数量\n" +
            "    \"effectiveStart\": \"2018-02-01\", //生效开始时间\n" +
            "    \"effectiveEnd\": \"2028-02-01\",//生效结束时间\n" +
            "    \"couponType\": \"0\",//优惠券类型\n" +
            "    \"avaliavleNum\": 99993 //可用优惠券\n" +
            "   },\n" +
            "   {...},\n" +
            "   {...}\n" +
            "   ]}}\n")
    @GetMapping("/quanTemplate")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "merchantId", value = "商户ID", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "车-优免券模板")
    public ResultData quanTemplate(String merchantId, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] WxCarController::quanTemplate");
        /// 1, get mall's park
        WxPark park = getCurrentPark();
        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 parkId = park.getParkId();

        if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
            if (StringUtils.isBlank(merchantId)) {
                // 优先从从商户表里取
                logger.error("quanTemplate failed, merchantId为空");
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "商户为空");
            }
            // bussinessId from 参数信息
            String businessId = "";
            // 优先从从商户表里取
            businessId = getETCPBusinessID(merchantId);
            if (StringUtils.isBlank(businessId)) {
                // 1期只有一个虚拟商户，可以写在商场配置里
                businessId = objParams.getString("businessId");
            }
            String ret = "";
            try {
                ret = etcp.getBCouponList(url, merchantNo, merchantKey, version, parkId, businessId);
            } catch (MallinkException e) {
                return new ResultData(e.getErrorCode(), e.getMessage());
            }

            if (ret == null) {
                logger.error("quanTemplate failed, 优免券模板未发现");
                return new ResultData(ErrorCode.ETCP_CMD_FAIL.getCode(), "获取优免券模板异常");
            }
            JSONObject retObj = JSON.parseObject(ret);
            if (retObj.getIntValue("code") == 0) {
                return new ResultData(retObj.getJSONObject("data"));
            } else {
                logger.error("quanTemplate failed, 优免券模板未发现");
                return new ResultData(ErrorCode.ETCP_QUAN_TEMP_FAIL.getCode(), "优免券模板未发现", retObj);
            }
        }
        return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "优免券模板失败");
    }

    private String getETCPBusinessID(String merchantIdStr) {
        String businessId;
        Long merchantId = 0L;
        try {
            merchantId = Long.valueOf(merchantIdStr);
        } catch (NumberFormatException e) {
            logger.error(e.getMessage());
        }
        WxMerchant wxMerchant = wxMerchantService.getById(merchantId);
        String carParams = wxMerchant.getCarParams();
        JSONObject objParams1 = JSON.parseObject(carParams);
        businessId = objParams1.getString("businessId");
        return businessId;
    }

    @ApiOperation("新增停车券接口")
    @PostMapping("save")
    @SystemControllerLog(description = "车-新增停车券接口")
    public ResultData save(@RequestBody WxCouponCarVo coupon) {
        logger.debug("[" + getIpAddr() + "] WxCarController::save");
        logger.info(coupon.toString());
        // Save to wx_counpon
        Date curDate = new Date();
        WxPark park = getCurrentPark();
        if (park.getVendorType().equals(EnumCarVendor.CAR_ETCP.getCode())) {
            // check 同一个模板的券分配额是否超了
            if (StringUtils.isBlank(coupon.getVendorParams())) {
                logger.error("请填充停车厂商优免券参数");
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "停车厂商参数为空");
            }
            JSONObject vendorParamsObj = JSON.parseObject(coupon.getVendorParams());
            Long templateId = vendorParamsObj.getLong("id");
            Integer amount = vendorParamsObj.getInteger("amount");
            Integer avaliavleNum = vendorParamsObj.getInteger("avaliavleNum");
            Integer amtCount = wxCouponCarService.getAmtCountByTemplateId(templateId);
            Integer availCount = wxCouponCarService.getAvaibleCountByTemplateId(templateId);
            if (amtCount >= amount) {
                logger.error("总库存已达到停车厂商优免券数量限制");
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "总库存已达到停车厂商优免券数量限制");
            }
            if (availCount >= avaliavleNum) {
                logger.error("可用库存已达到停车厂商优免券数量限制");
                return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "可用库存已达到停车厂商优免券数量限制");
            }
        }
        // check End
        coupon.setTenantId(getTenantId());

        ResultData resultData = wxCouponService.saveOrUpdate(coupon);
        if (resultData.code != ResultData.SUCCESS){
            return resultData;
        }

        // Save to wx_coupon_car
        WxCouponCar couponCar = new WxCouponCar();
        couponCar.setId(coupon.getId());
        couponCar.setTenantId(getTenantId());
        couponCar.setParkId(park.getId());
        couponCar.setVendorType(park.getVendorType());
        couponCar.setVendorParams(coupon.getVendorParams());
        couponCar.setCreateDate(curDate);
        couponCar.setUpdateDate(curDate);
        WxCouponCar newCouponCar = wxCouponCarService.getById(couponCar.getId());
        if (newCouponCar == null) {
            wxCouponCarService.save(couponCar);
        } else {
            wxCouponCarService.update(couponCar);
        }

        //启动审批流
        if (coupon.getFlowParams() != null && coupon.getFlowParams().size() > 0) {
            WxCoupon wc = new WxCoupon();
            wc.setId(coupon.getId());

            coupon.getFlowParams().put("businessId",coupon.getId());
            wxFlowService.start(coupon.getFlowParams(), getUserId(), getUser().getName(), getTenantId());
            //作废审批
            if (EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode().equals(coupon.getStatus())) {
                wc.setCancleApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
            }else{
                //投放审批
                wc.setPutApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
            }
            wxCouponMapper.updateById(wc);
        }

        return new ResultData(coupon.getId());
    }


    @ApiOperation("优免券模板库存总数")
    @GetMapping("/templateAmtCount")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateId", value = "模板ID", dataType = "Long", paramType = "query", required = true)})
    @SystemControllerLog(description = "车-优免券模板已分配总数")
    public ResultData getTemplateAmountSum(Long templateId) {
        logger.debug("[" + getIpAddr() + "] WxCarController::getTemplateAmountSum");
        // 库存总数 = 库存总数(status=0) + 作废券已领取(待使用+已使用)
        Integer amountCount = 0;
        try {
            amountCount = wxCouponCarService.getAmtCountByTemplateId(templateId) +
                    wxCouponCarService.getClaimCountByTemplateId(templateId);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        Map map = new HashMap();
        map.put("amountCount", amountCount);
        return new ResultData(map);
    }

    @ApiOperation("优免券模板已分配总数")
    @GetMapping("/templateAvaiCount")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateId", value = "模板ID", dataType = "Long", paramType = "query", required = true)})
    @SystemControllerLog(description = "车-优免券模板库存总数")
    public ResultData getTemplateAvailSum(Long templateId) {
        logger.debug("[" + getIpAddr() + "] WxCarController::getTemplateAvailSum");
        // 已分配总数 = 可用库存总数（status=0）+ 作废券已领取(待使用+已使用)
        Integer availCount = 0;
        try {
            availCount = wxCouponCarService.getAvaibleCountByTemplateId(templateId) +
                    wxCouponCarService.getClaimCountByTemplateId(templateId);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        Map map = new HashMap();
        map.put("availCount", availCount);
        return new ResultData(map);
    }

    @ApiOperation("停车券detail")
    @GetMapping("/detail")
    @SystemControllerLog(description = "车-停车券detail")
    public ResultData getCouponCarDetail(@RequestParam Long id) {
        logger.debug("[" + getIpAddr() + "] WxCarController::getCouponCarDetail");
        return new ResultData(wxCouponCarService.findDetailVo(id));
    }

    @ApiOperation(value = "停车场状态")
    @GetMapping("/getParkStatus")
    @SystemControllerLog(description = "车-停车场状态")
    public ResultData getParkStatus() {
        /// 1, get mall's park
        WxPark park = getCurrentPark();
        if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
            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 new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "车场不支持");
    }


}
