package com.iformall.controller.market;

import com.github.pagehelper.PageInfo;
import com.iformall.annotation.SystemControllerLog;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.WxCoupon;
import com.iformall.domain.po.WxCouponChannel;
import com.iformall.domain.po.WxCouponPassword;
import com.iformall.domain.vo.WxCouponStatisVo;
import com.iformall.enums.*;
import com.iformall.mapper.WxCouponChannelMapper;
import com.iformall.service.WxCouponPasswordService;
import com.iformall.service.WxCouponService;
import com.iformall.service.WxFlowService;
import com.iformall.utils.DateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping("wxCoupon")
@Api(description = "优惠券接口")
public class WxCouponController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxCouponService wxCouponService;
    @Autowired
    private WxCouponPasswordService couponPasswordService;
    @Autowired
    private WxCouponChannelMapper wxCouponChannelMapper;
    @Autowired
    private WxFlowService wxFlowService;

    @ApiOperation("分页列表接口")
    @GetMapping("list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "券投放-列表")
    public ResultData list(@ModelAttribute WxCoupon wxCoupon, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::list");
        if (wxCoupon == null) wxCoupon = new WxCoupon();
        wxCoupon.setTenantId(getTenantId());
        return wxCouponService.list(wxCoupon, pageNum, pageSize); //全列表
    }
    @ApiOperation("分页列表接口")
    @GetMapping("listWithTypePress")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "券投放-列表")
    public ResultData listWithTypePress(@ModelAttribute WxCoupon wxCoupon, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::list");
        if (wxCoupon == null) wxCoupon = new WxCoupon();
        wxCoupon.setTenantId(getTenantId());
        Integer[] typeArray = {
                EnumCouponType.COUPON_MANJIAN.getCode(),
                EnumCouponType.COUPON_DAIJIN.getCode(),
                EnumCouponType.COUPON_TUANGOU.getCode(),
                EnumCouponType.COUPON_LIPIN.getCode(),
                EnumCouponType.COUPON_TINGCHE.getCode(),
                EnumCouponType.COUPON_MULTIMCH.getCode(),
                EnumCouponType.COUPON_PRESS.getCode()};

        wxCoupon.setTypes(Arrays.asList(typeArray));
        return wxCouponService.list(wxCoupon, pageNum, pageSize); //全列表
    }

    @ApiOperation("新增接口")
    @PostMapping("add")
    @SystemControllerLog(description = "券投放-新增")
    public ResultData add(@RequestBody WxCoupon wxCoupon) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::add");
        wxCoupon.setTenantId(getTenantId());

        ResultData resultData = wxCouponService.saveOrUpdate(wxCoupon);
        if(resultData.code != 200){
            return resultData;
        }

        //启动投放审批
        if(wxCoupon.getFlowParams() !=null && wxCoupon.getFlowParams().size()>0) {
            wxCoupon.getFlowParams().put("businessId",wxCoupon.getId());
            wxFlowService.start(wxCoupon.getFlowParams(), getUserId(), getUser().getName(), getTenantId());
            //修改coupon applyStatus状态为审核中
            wxCoupon.setPutApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
        }
        return resultData;
    }

    @ApiOperation("根据id更新接口")
    @PostMapping("update")
    @SystemControllerLog(description = "券投放-更新")
    public ResultData update(@RequestBody WxCoupon wxCoupon) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::update");
        if (wxCoupon.getId() == null) {
            return new ResultData(ResultData.ERROR, "缺少id");
        }
        if(EnumDelFlag.YES.getCode().equals(wxCoupon.getIsDel())){
            WxCouponChannel query = new WxCouponChannel();
            query.setTenantId(wxCoupon.getTenantId());
            query.setCouponId(wxCoupon.getId());
            query.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode());
            if(CollectionUtils.isNotEmpty(wxCouponChannelMapper.findList(query))){
                return new ResultData(ResultData.ERROR, "有活动正在上架，请先下架。");
            }
        }
        wxCoupon.setTenantId(getTenantId());

        //启动审批流
        if (wxCoupon.getFlowParams() != null && wxCoupon.getFlowParams().size() > 0) {
            logger.info("------coupon.update().businessType:"+wxCoupon.getFlowParams().get("businessType"));
            wxCoupon.getFlowParams().put("businessId",wxCoupon.getId());
            wxFlowService.start(wxCoupon.getFlowParams(), getUserId(), getUser().getName(), getTenantId());
            //作废审批
            if (EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode().equals(wxCoupon.getStatus())) {
                wxCoupon.setCancleApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
                return new ResultData(wxCoupon);
            }else{
                //投放审批
                wxCoupon.setPutApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
            }
        }
        return wxCouponService.saveOrUpdate(wxCoupon);
    }

    @ApiOperation("根据id更新库存及有效期接口")
        @PostMapping("updateStokeAndValidDate")
    @SystemControllerLog(description = "券投放-库存/有效期更新")
    public ResultData updateStokeAndValidDate(@RequestBody WxCoupon wxCoupon) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::updateStokeAndValidDate");
        if (wxCoupon.getId() == null) {
            logger.error("缺少id");
            return new ResultData(ResultData.ERROR, "缺少id");
        }
        if(wxCoupon.getType() == null) {
            logger.error("缺少type");
            return new ResultData(ResultData.ERROR, "缺少type");
        }
        if(wxCoupon.getRemainInventory() == null || wxCoupon.getInventory() == null) {
            logger.error("库存错误1");
            return new ResultData(ErrorCode.COUPON_STOCK_ERR);
        }
        if(wxCoupon.getRemainInventory() > wxCoupon.getInventory()) {
            logger.error("库存错误2");
            return new ResultData(ErrorCode.COUPON_STOCK_ERR);
        }
        if(wxCoupon.getValidType() == null) {
            logger.error("库存错误3");
            return new ResultData(ErrorCode.COUPON_VALID_DATE_ERR);
        }
        if(wxCoupon.getValidType().equals(EnumCouponValidType.BETWEEN_TWO_TIME.getCode())) {
            if(wxCoupon.getValidEndDate() == null) {
                logger.error("有效期错误1");
                return new ResultData(ErrorCode.COUPON_VALID_DATE_ERR);
            }
        } else {
            if(wxCoupon.getValidDays() == null) {
                logger.error("有效期错误2");
                return new ResultData(ErrorCode.COUPON_VALID_DATE_ERR);
            }
        }
        if(wxCoupon.getType().equals(EnumCouponType.COUPON_TINGCHE.getCode()) ||
            wxCoupon.getType().equals(EnumCouponType.COUPON_CREDIT_PARK.getCode())) {
            logger.error("券库存有效期不支持停车券");
            return new ResultData(ErrorCode.COUPON_STOCK_DATE_NO_CAR);
        }
        wxCoupon.setTenantId(getTenantId());

        WxCoupon coupon = wxCouponService.findById(wxCoupon);
        if(coupon!=null){
            if((wxCoupon.getValidEndDate()!=null&&coupon.getValidEndDate()!=null && DateUtils.format(wxCoupon.getValidEndDate()).equals(DateUtils.format(coupon.getValidEndDate()))
                    && wxCoupon.getInventory().equals(coupon.getInventory()))
                    ||
                    (wxCoupon.getValidDays()!=null && coupon.getValidDays()!=null && wxCoupon.getInventory().equals(coupon.getInventory()) &&
                            wxCoupon.getValidDays().equals(coupon.getValidDays()))
                    ){
                return new ResultData(ErrorCode.COUPON_STOCK_VALID_DATE_SETTING_ERR);
            }

            if(wxCoupon.getValidEndDate()!=null && wxCoupon.getValidEndDate().before(coupon.getValidEndDate())){
                return new ResultData(ErrorCode.COUPON_STOCK_ENDTIME_ERR);
            }
            if(wxCoupon.getInventory()!=null && wxCoupon.getInventory().intValue() < coupon.getInventory().intValue()   ){
                return new ResultData(ErrorCode.COUPON_STOCK_INV_ERR);
            }

            if(wxCoupon.getValidDays()!=null && coupon.getValidDays()!=null && wxCoupon.getValidDays().intValue() < coupon.getValidDays().intValue()){
                return new ResultData(ErrorCode.COUPON_STOCK_ENDTIME_ERR);
            }
        }

        //启动审批流
        if(wxCoupon.getFlowParams() != null && wxCoupon.getFlowParams().size() >0){
            List<Map<String,Object>> variables = (List)wxCoupon.getFlowParams().get("variables");
            Map<String,Object> map = new HashedMap();
            map.put("key","inventory");
            map.put("value",wxCoupon.getInventory());
            variables.add(map);
            map = new HashedMap();
            map.put("key","remainInventory");
            map.put("value",wxCoupon.getRemainInventory());
            variables.add(map);
            map = new HashedMap();
            map.put("key","type");
            map.put("value",wxCoupon.getType());
            variables.add(map);
            map = new HashedMap();
            map.put("key","validEndDate");
            map.put("value",wxCoupon.getValidEndDate());
            map = new HashedMap();
            map.put("key","validStartDate");
            map.put("value",wxCoupon.getValidStartDate());
            map = new HashedMap();
            map.put("key","validType");
            map.put("value",wxCoupon.getValidType());
            variables.add(map);
            map = new HashedMap();
            map.put("key","validDays");
            map.put("value",wxCoupon.getValidDays());
            variables.add(map);
            wxCoupon.getFlowParams().put("businessId",wxCoupon.getId());
            wxFlowService.start(wxCoupon.getFlowParams(), getUserId(), getUser().getName(), getTenantId());
            //更新状态
            WxCoupon updateCoupon = new WxCoupon();
            updateCoupon.setTenantId(wxCoupon.getTenantId());
            updateCoupon.setId(wxCoupon.getId());
            updateCoupon.setStockApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
            updateCoupon.setUpdateDate(new Date());
            wxCouponService.update(updateCoupon);
        }else{
            return wxCouponService.updateCouponStockAndEndTime(wxCoupon);
        }

        return new ResultData();
    }

    @ApiOperation("根据id删除接口")
    @GetMapping("/del")
    @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true)
    @SystemControllerLog(description = "券投放-删除")
    public ResultData delete(Long id) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::delete");
        wxCouponService.deleteById(id);
        return new ResultData(Result.SUCCESS, "删除成功", null);
    }

    @ApiOperation("根据id查询接口")
    @GetMapping("/findById")
    @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true)
    @SystemControllerLog(description = "券投放-查询")
    public ResultData findById(@RequestParam Long id) {
        logger.debug("[" + getIpAddr() + "] WxCouponController::findById");
        return new ResultData(wxCouponService.getVoById(id));
    }


    @ApiOperation("卡营销列表接口")
    @GetMapping("findCardCountList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "券投放-卡营销列表")
    public ResultData findCardCountList(@ModelAttribute WxCoupon wxCoupon, Integer pageNum, Integer pageSize) {
        //默认时间本月第一天，截止到当天
        Map<String,Object> result = new HashedMap();
        if(wxCoupon.getStartdate() == null){
            wxCoupon.setStartdate(DateUtils.getFirstDayForCurrMonth());
        }
        if(wxCoupon.getEnddate() == null){
            wxCoupon.setEnddate(DateUtils.stringToDate(DateUtils.getSystemTime("yyyy-MM-dd") + " 23:59:59"));
        }
        PageInfo<WxCouponStatisVo> pageInfo = wxCouponService.findCountData(wxCoupon,pageNum,pageSize);
        for (WxCouponStatisVo coupon:pageInfo.getList()) {
            if(coupon.getSaleAmount() == null){
                coupon.setSaleAmount(0);
            }
            if(coupon.getSumPayment() == null){
                coupon.setSumPayment(0);
            }
            if(coupon.getSumSubsidy() == null){
                coupon.setSumSubsidy(0);
            }
        }
        result.put("list",pageInfo);
        return new ResultData(result);
    }

    @ApiOperation("券营销列表接口")
    @GetMapping("findCouponCountList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "券投放-券营销列表")
    public ResultData findCouponCountList(@ModelAttribute WxCoupon wxCoupon, Integer pageNum, Integer pageSize) {
        //默认时间本月第一天，截止到当天
        Map<String,Object> result = new HashedMap();
        if(wxCoupon.getStartdate() == null){
            wxCoupon.setStartdate(DateUtils.getFirstDayForCurrMonth());
        }
        if(wxCoupon.getEnddate() == null){
            wxCoupon.setEnddate(DateUtils.stringToDate(DateUtils.getSystemTime("yyyy-MM-dd") + " 23:59:59"));
        }

        PageInfo<WxCouponStatisVo> pageInfo = wxCouponService.findCouponData(wxCoupon,pageNum,pageSize);
        for (WxCouponStatisVo coupon:pageInfo.getList()) {
            if(coupon.getSumSubsidy() == null){
                coupon.setSumSubsidy(0);
            }
            if(coupon.getSumSubsidy() == null){
                coupon.setSumSubsidy(0);
            }
        }
        return new ResultData(pageInfo);
    }

    @ApiOperation("砍价营销列表接口")
    @GetMapping("findPressCountList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "券投放-砍价营销列表")
    public ResultData findPressCountList(@ModelAttribute WxCoupon wxCoupon, Integer pageNum, Integer pageSize) {
        Map<String,Object> result = new HashedMap();
        wxCoupon.setTenantId(getTenantId());
        PageInfo<WxCouponStatisVo> pages = wxCouponService.findPressData(wxCoupon,pageNum,pageSize);
        return new ResultData(pages);
    }

    @GetMapping("exportCouponPassword")
    @SystemControllerLog(description = "卡券兑换码-导出数据")
    public void exportCouponPassword(@ModelAttribute WxCouponPassword wxCouponPassword, HttpServletRequest request, HttpServletResponse response) {
        wxCouponPassword.setTenantId(getTenantId());
        if (wxCouponPassword.getCouponId() == null) {
            wxCouponPassword.setCouponId(0L);
        }
        couponPasswordService.exportData(request, response, wxCouponPassword);
    }

}
