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(@Validated CandyMgtCouponBuildParam buildParam) {
        BigDecimal discount = null, valFace = null, valOver = null, valMinus = null;
        Integer couType = buildParam.getCouType(),
                validity = buildParam.getValidity(),
                redeemValidity = buildParam.getRedeemValidity();
        LocalDateTime nowTime = LocalDateTime.now(),
                redeemStart = null, redeemStop = null, effectAt, expireAt,
                eventAt = LocalDateTime.parse(buildParam.getEventAt(), DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS));

        switch (couType) {// TODO: 2021/8/20 校验
            case 1:// 代金券
                valFace = buildParam.getValFace();
                break;
            case 2:// 满减券
                valOver = buildParam.getValOver();
                valMinus = buildParam.getValMinus();
                break;
            case 3:// 兑换券
                redeemStart = eventAt.with(LocalTime.MIN);
                redeemStop = eventAt.plusDays(redeemValidity).withHour(23).withMinute(59).withSecond(59);
                break;
            case 4:// 折扣券
                discount = buildParam.getDiscount();
                break;
            default:
                logger.warn("Invalid operation[buildParam.couType={}]", couType);
                return this.error(AjaxResult.Type.WARN, "券类型无效");
        }
        effectAt = eventAt.with(LocalTime.MIN);
        expireAt = eventAt.plusDays(validity).withHour(23).withMinute(59).withSecond(59);

        StringBuilder eventLimit = new StringBuilder();
        String operator = ShiroUtils.getLoginName();
        if (buildParam.getEventType() == 2) {// 指定用户手机号
            String eventLimitStr = buildParam.getEventLimit().trim();
            // TODO: 2021/8/20 正则校验手机号字符串
            if (StringUtils.isEmpty(eventLimitStr)) {
                return this.error(AjaxResult.Type.WARN, "请指定手机号");
            }
            Set<String> eventLimitSet = Stream.of(eventLimitStr.split(",")).collect(Collectors.toSet());
            for (String l : eventLimitSet) {
                eventLimit.append(l).append(",");
            }
        }

        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(couType);
        initCoupon.setBindType(buildParam.getBindType());
        initCoupon.setDiscount(discount);
        initCoupon.setValFace(valFace);
        initCoupon.setValOver(valOver);
        initCoupon.setValMinus(valMinus);
        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.nextMilliId());
                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(eventLimit.toString());
        initMgtCoupon.setEventAt(eventAt);
        initMgtCoupon.setOperator(operator);
        initMgtCoupon.setCreatedAt(nowTime);

        candyMgtCouponAdminService.saveMgtCouponInfo(initCoupon, initMgtCoupon, initCouponRuleList);

        return toAjax(true);
    }
}
