package com.liquidnet.client.admin.web.controller.zhengzai.candy;

import com.liquidnet.client.admin.common.annotation.Log;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.core.page.TableDataInfo;
import com.liquidnet.client.admin.common.enums.BusinessType;
import com.liquidnet.client.admin.common.utils.DateUtils;
import com.liquidnet.client.admin.common.utils.ShiroUtils;
import com.liquidnet.client.admin.zhengzai.candy.service.ICandyCouponAdminService;
import com.liquidnet.client.admin.zhengzai.candy.service.ICandyMgtCouponAdminService;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.candy.dto.admin.CandyCouponRuleBuildParam;
import com.liquidnet.service.candy.dto.admin.CandyMgtCouponBuildParam;
import com.liquidnet.service.candy.dto.admin.CandyMgtCouponInfoDto;
import com.liquidnet.service.candy.dto.admin.CandyMgtCouponListParam;
import com.liquidnet.service.candy.entity.CandyCoupon;
import com.liquidnet.service.candy.entity.CandyCouponRule;
import com.liquidnet.service.candy.entity.CandyMgtCoupon;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Api(tags = "券发放管理")
@Controller
@RequestMapping("candy/coupon/mgt")
public class CandyMgtCouponAdminController extends BaseController {
    private final String prefix = "zhengzai/candy/coupon/mgt";
    @Autowired
    private ICandyMgtCouponAdminService candyMgtCouponAdminService;

    @RequiresPermissions("candy:coupon:mgt:view")
    @GetMapping()
    public String coupon(@RequestParam int couType) {
        return prefix + "/coupon" + couType;
    }

    @RequiresPermissions("candy:coupon:mgt:list")
    @PostMapping("list")
    @ResponseBody
    public TableDataInfo list(CandyMgtCouponListParam listParam) {
        startPage();
        List<CandyMgtCouponInfoDto> list = candyMgtCouponAdminService.listForMgtCouponInfoDto(listParam);
        return getDataTable(list);
    }

    @GetMapping("add/{couType}")
    public String add(@PathVariable("couType") String couType, ModelMap mmap) {
        mmap.put("couType", couType);
        return prefix + "/add";
    }

    @ApiOperation(value = "新建券")
    @RequiresPermissions("candy:coupon:mgt:add")
    @Log(title = "券发放管理", businessType = BusinessType.INSERT)
    @PostMapping("add")
    @ResponseBody
    public AjaxResult addSave(@RequestBody @Validated CandyMgtCouponBuildParam buildParam) {
        LocalDateTime nowTime = LocalDateTime.now(), redeemStart = null, redeemStop = null, effectAt, expireAt;

        String eventAtStr = buildParam.getEventAt();
        LocalDateTime eventAt = StringUtils.isEmpty(eventAtStr.trim()) ? nowTime
                : LocalDateTime.parse(eventAtStr, DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS));

        switch (buildParam.getCouType()) {// TODO: 2021/8/20 校验
            case 1:// 代金券
                BigDecimal valFace = buildParam.getValFace();
                if (null == valFace || valFace.compareTo(BigDecimal.ZERO) <= 0) {
                    return AjaxResult.warn("代金券金额无效");
                }
                buildParam.setDiscount(null);
                buildParam.setValOver(null);
                buildParam.setValMinus(null);
                buildParam.setOverlay(0);
                break;
            case 2:// 满减券
                BigDecimal valOver = buildParam.getValOver();
                BigDecimal valMinus = buildParam.getValMinus();
                if (null == valOver || valOver.compareTo(BigDecimal.ZERO) <= 0
                        || null == valMinus || valMinus.compareTo(BigDecimal.ZERO) <= 0) {
                    return AjaxResult.warn("满减金额无效");
                }
                buildParam.setDiscount(null);
                buildParam.setValFace(valMinus);
                buildParam.setOverlay(0);
                break;
            case 3:// 兑换券
                buildParam.setBindType(0);
                buildParam.setDiscount(null);
                buildParam.setValFace(null);
                buildParam.setValOver(null);
                buildParam.setValMinus(null);
                buildParam.setOverlay(0);
                break;
            case 4:// 折扣券
                BigDecimal discount = buildParam.getDiscount();
                if (null == discount || discount.compareTo(BigDecimal.ZERO) <= 0) {
                    return AjaxResult.warn("折扣配置无效");
                }
                break;
            case 101:
                buildParam.setDiscount(null);
                buildParam.setValFace(null);
                buildParam.setValOver(null);
                buildParam.setValMinus(null);

                if (null == buildParam.getOverlay()) {
                    return AjaxResult.warn("叠加限制配置无效");
                }
                break;
            default:
                logger.warn("Invalid operation[buildParam.couType={}]", buildParam.getCouType());
                return this.error(AjaxResult.Type.WARN, "券类型无效");
        }
        Integer validity = buildParam.getValidity();
        Integer redeemValidity = buildParam.getRedeemValidity();
        if (0 == buildParam.getBindType()) {
            buildParam.setEventType(null);
            buildParam.setEventLimit(null);
            if (null == redeemValidity) {
                return AjaxResult.warn("兑换有效期无效");
            }
            redeemStart = eventAt.with(LocalTime.MIN);
            redeemStop = eventAt.plusDays(redeemValidity).withHour(23).withMinute(59).withSecond(59);
        } else {
            if (buildParam.getEventType() == 2) {// 指定用户手机号
                if (StringUtils.isEmpty(buildParam.getEventLimit().trim())) {
                    return this.error(AjaxResult.Type.WARN, "请指定手机号");
                }
            }
        }
        effectAt = eventAt.with(LocalTime.MIN);
        expireAt = eventAt.plusDays(validity).withHour(23).withMinute(59).withSecond(59);

        String operator = ShiroUtils.getLoginName();

        CandyCoupon initCoupon = new CandyCoupon();
        initCoupon.setCouponId(IDGenerator.nextMilliId());
        initCoupon.setState(1);
        initCoupon.setTitle(buildParam.getTitle());
        initCoupon.setLabel(buildParam.getLabel());
        initCoupon.setNotice(buildParam.getNotice());
        initCoupon.setExclusive(0);
        initCoupon.setBusiType(buildParam.getBusiType());
        initCoupon.setCouType(buildParam.getCouType());
        initCoupon.setBindType(buildParam.getBindType());
        initCoupon.setDiscount(buildParam.getDiscount());
        initCoupon.setValFace(buildParam.getValFace());
        initCoupon.setValOver(buildParam.getValOver());
        initCoupon.setValMinus(buildParam.getValMinus());
        initCoupon.setOverlay(buildParam.getOverlay());
        initCoupon.setValidity(validity);
        initCoupon.setRedeemValidity(redeemValidity);
        initCoupon.setRedeemStart(redeemStart);
        initCoupon.setRedeemStop(redeemStop);
        initCoupon.setEffectAt(effectAt);
        initCoupon.setExpireAt(expireAt);
        initCoupon.setOperator(operator);
        initCoupon.setCreatedAt(nowTime);

        List<CandyCouponRuleBuildParam> couponRuleList = buildParam.getCouponRuleList();
        List<CandyCouponRule> initCouponRuleList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(couponRuleList)) {
            couponRuleList.forEach(r -> {
                CandyCouponRule initCouponRule = new CandyCouponRule();
                initCouponRule.setCruleId(IDGenerator.nextTimeId2());
                initCouponRule.setCouponId(initCoupon.getCouponId());
                initCouponRule.setUseScope(r.getUseScope());
                initCouponRule.setBusiName(r.getBusiName());
                initCouponRule.setBusiId(r.getBusiId());
                initCouponRule.setState(1);

                initCouponRuleList.add(initCouponRule);
            });
        }

        CandyMgtCoupon initMgtCoupon = new CandyMgtCoupon();
        initMgtCoupon.setMcouponId(IDGenerator.nextMilliId());
        initMgtCoupon.setCouponId(initCoupon.getCouponId());
        initMgtCoupon.setState(0);
        initMgtCoupon.setEventAmt(buildParam.getEventAmt());
        initMgtCoupon.setEventType(buildParam.getEventType());
        initMgtCoupon.setEventLimit(buildParam.getEventLimit());
        initMgtCoupon.setEventAt(eventAt);
        initMgtCoupon.setOperator(operator);
        initMgtCoupon.setCreatedAt(nowTime);

        candyMgtCouponAdminService.saveMgtCouponInfo(initCoupon, initMgtCoupon, initCouponRuleList);

        return toAjax(true);
    }
}
