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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.utils.ShiroUtils;
import com.liquidnet.client.admin.common.utils.poi.ExcelUtil;
import com.liquidnet.client.admin.zhengzai.adam.dto.AdamMemberCodeExcelDto;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamMemberAdminService;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamMemberCodeAdminService;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamMemberPriceAdminService;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamMemberRightsAdminService;
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.adam.dto.param.admin.*;
import com.liquidnet.service.adam.entity.AdamMember;
import com.liquidnet.service.adam.entity.AdamMemberCode;
import com.liquidnet.service.adam.entity.AdamMemberPrice;
import com.liquidnet.service.adam.entity.AdamMemberRights;
import com.liquidnet.service.candy.dto.admin.CandyCouponRuleBuildParam;
import com.liquidnet.service.candy.dto.admin.CandyMemberCouponBuildParam;
import com.liquidnet.service.candy.dto.admin.CandyMgtCouponMemberDto;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "登登登会员")
@Controller
@RequestMapping("adam/member/detail")
public class AdamMemberAdminController extends BaseController {
    private final String prefix = "zhengzai/adam/member/detail";
    @Autowired
    IAdamMemberAdminService adamMemberService;
    @Autowired
    IAdamMemberPriceAdminService adamMemberPriceAdminService;
    @Autowired
    IAdamMemberRightsAdminService adamMemberRightsAdminService;
    @Autowired
    IAdamMemberCodeAdminService adamMemberCodeAdminService;
    @Autowired
    ICandyMgtCouponAdminService candyMgtCouponAdminService;
    @Autowired
    ICandyCouponAdminService candyCouponAdminService;

    @RequiresPermissions("adam:member:detail:view")
    @GetMapping()
    public String detailInfo(ModelMap mmap) {
        AdamMember member = adamMemberService.getOne(Wrappers.lambdaQuery(AdamMember.class)
                .eq(AdamMember::getState, 1)
                .select(
                        AdamMember::getMemberId,
                        AdamMember::getName,
                        AdamMember::getTitle,
                        AdamMember::getSubTitle,
                        AdamMember::getAvatar,
                        AdamMember::getIcon,
                        AdamMember::getLimitation,
                        AdamMember::getLimitStart,
                        AdamMember::getLimitEnd,
                        AdamMember::getInterestsDetail,
                        AdamMember::getNotes,
                        AdamMember::getType,
                        AdamMember::getIntegralRate
                )
        );
        mmap.put("member", member);

        if (null != member) {
            List<AdamMemberRights> memberRightsList = adamMemberRightsAdminService.list(Wrappers.lambdaQuery(AdamMemberRights.class)
                    .eq(AdamMemberRights::getState, 1)
                    .eq(AdamMemberRights::getMemberId, member.getMemberId())
                    .select(
                            AdamMemberRights::getMrightsId,
                            AdamMemberRights::getCover,
                            AdamMemberRights::getTitle,
                            AdamMemberRights::getSubTitle,
                            AdamMemberRights::getDetail
                    )
            );
            mmap.put("memberRightsList", memberRightsList);

            if (!CollectionUtils.isEmpty(memberRightsList)) {
                List<String> mrightsIdList = memberRightsList.stream().map(AdamMemberRights::getMrightsId).collect(Collectors.toList());

                List<CandyMgtCouponMemberDto> couponMemberDtoList = candyMgtCouponAdminService.listForMgtCouponMemberDto(mrightsIdList);

                mmap.put("couponMemberDtoList", couponMemberDtoList);
            }

            AdamMemberPrice memberPrice = adamMemberPriceAdminService.getOne(Wrappers.lambdaQuery(AdamMemberPrice.class)
                    .eq(AdamMemberPrice::getState, 1)
                    .eq(AdamMemberPrice::getMemberId, member.getMemberId())
                    .select(
                            AdamMemberPrice::getMemberPriceId,
                            AdamMemberPrice::getPrice,
                            AdamMemberPrice::getPriceFixed,
                            AdamMemberPrice::getPriceSpecial,
                            AdamMemberPrice::getDays
                    )
            );
            mmap.put("memberPrice", memberPrice);
        }
        return prefix + "/info";
    }

    @ApiOperation(value = "会员设置:基础信息编辑")
    @RequiresPermissions("adam:member:detail:edit")
    @PostMapping("edit")
    @ResponseBody
    public AjaxResult detailInfoEdit(AdamMemberBuildParam parameter) {
        return this.toAjax(adamMemberService.edit(parameter));
    }

    @ApiOperation(value = "会员套餐:价格编辑")
    @RequiresPermissions("adam:member:detail:price:edit")
    @PostMapping("price_edit")
    @ResponseBody
    public AjaxResult detailPriceEdit(AdamMemberPriceBuildParam parameter) {
        return this.toAjax(adamMemberPriceAdminService.edit(parameter));
    }

    @ApiOperation(value = "会员套餐:权益编辑")
    @RequiresPermissions("adam:member:detail:rights:edit")
    @PostMapping("rights_edit")
    @ResponseBody
    public AjaxResult detailRightsEdit(AdamMemberRightsBuildParam parameter) {
        return this.toAjax(adamMemberRightsAdminService.edit(parameter));
    }

    @ApiOperation(value = "会员套餐:券编辑")
    @RequiresPermissions("adam:member:detail:coupon:edit")
    @PostMapping("coupon_edit")
    @ResponseBody
    public AjaxResult detailCouponEdit(CandyMemberCouponBuildParam parameter) {
        BigDecimal valFace = null, valOver = null, valMinus = null;
        switch (parameter.getCouType()) {// TODO: 2021/8/20 校验
            case 1:// 代金券
                valFace = parameter.getValFace();
                break;
            case 2:// 满减券
                valOver = parameter.getValOver();
                valMinus = parameter.getValMinus();
                break;
            default:
                logger.warn("Invalid operation[buildParam.couType={}]", parameter.getCouType());
                return this.error(AjaxResult.Type.WARN, "券类型无效");
        }

        String memberId = parameter.getMemberId(), couponId = parameter.getCouponId(), operator = ShiroUtils.getLoginName();
        LocalDateTime nowTime = LocalDateTime.now();
        boolean editRst = false;
        if (StringUtils.isEmpty(couponId)) {// 新增券
            LambdaQueryWrapper<AdamMemberPrice> memberPriceLambdaQueryWrapper = Wrappers.lambdaQuery(AdamMemberPrice.class)
                    .eq(AdamMemberPrice::getMemberId, memberId).eq(AdamMemberPrice::getState, 1);
            AdamMemberPrice memberPrice = adamMemberPriceAdminService.getOne(memberPriceLambdaQueryWrapper);

            CandyCoupon initCoupon = new CandyCoupon();
            initCoupon.setCouponId(IDGenerator.nextMilliId());
            initCoupon.setState(1);
            initCoupon.setTitle(parameter.getTitle());
            initCoupon.setLabel(parameter.getLabel());
            initCoupon.setNotice("会员权益");
            initCoupon.setExclusive(1);
            initCoupon.setBusiType(parameter.getBusiType());
            initCoupon.setCouType(parameter.getCouType());
            initCoupon.setBindType(1);// 领取方式[0-用户输入兑换｜1-发放至用户]
            //initCoupon.setDiscount();
            initCoupon.setValFace(valFace);
            initCoupon.setValOver(valOver);
            initCoupon.setValMinus(valMinus);
            initCoupon.setOverlay(parameter.getOverlay());
            initCoupon.setValidity(memberPrice.getDays());
            //initCoupon.setRedeemValidity();
            //initCoupon.setRedeemStart();
            //initCoupon.setRedeemStop();
            //initCoupon.setEffectAt();
            //initCoupon.setExpireAt();
            initCoupon.setOperator(operator);
            initCoupon.setCreatedAt(nowTime);


            List<CandyCouponRuleBuildParam> couponRuleList = parameter.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(parameter.getMrightsId());
            initMgtCoupon.setCouponId(initCoupon.getCouponId());
            initMgtCoupon.setState(10);// 发放状态[0-未发放|1-已发放|2-无效｜9-发放中|10-会员礼包初始模版]

            initMgtCoupon.setEventAmt(parameter.getEventAmt());
            initMgtCoupon.setEventType(2);
            //initMgtCoupon.setEventLimit();
            //initMgtCoupon.setEventAt();
            initMgtCoupon.setOperator(operator);
            initMgtCoupon.setCreatedAt(nowTime);

            editRst = candyMgtCouponAdminService.saveMgtCouponInfo(initCoupon, initMgtCoupon, initCouponRuleList);
        } else {// 编辑券
            LambdaQueryWrapper<CandyCoupon> candyCouponLambdaQueryWrapper = Wrappers.lambdaQuery(CandyCoupon.class)
                    .eq(CandyCoupon::getCouponId, couponId)
                    .eq(CandyCoupon::getState, 1)
                    .eq(CandyCoupon::getExclusive, 10);
            if (candyCouponAdminService.count(candyCouponLambdaQueryWrapper) > 0) {
                CandyCoupon updateCoupon = new CandyCoupon();
                updateCoupon.setCouponId(couponId);

                updateCoupon.setTitle(parameter.getTitle());
                updateCoupon.setBusiType(parameter.getBusiType());
                updateCoupon.setCouType(parameter.getCouType());
                updateCoupon.setValFace(valFace);
                updateCoupon.setValOver(valOver);
                updateCoupon.setValMinus(valMinus);
                updateCoupon.setOverlay(parameter.getOverlay());
                updateCoupon.setOperator(operator);
                updateCoupon.setUpdatedAt(nowTime);


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

                        initCouponRuleList.add(initCouponRule);
                    });
                }


                CandyMgtCoupon updateMgtCoupon = new CandyMgtCoupon();
                updateMgtCoupon.setMcouponId(parameter.getMrightsId());

                updateMgtCoupon.setEventAmt(parameter.getEventAmt());
                updateMgtCoupon.setOperator(operator);
                updateMgtCoupon.setUpdatedAt(nowTime);

                editRst = candyMgtCouponAdminService.updateMgtCouponInfo(updateCoupon, updateMgtCoupon, initCouponRuleList);
            }
        }

        return this.toAjax(editRst);
    }

    @ApiOperation(value = "会员码:列表")
    @RequiresPermissions("adam:member:detail:code:list")
    @PostMapping("code_list")
    @ResponseBody
    public TableDataInfo detailCodeList(AdamMemberCodeListParam parameter) {
        return getDataTable(detailCodeListQuery(parameter));
    }

    private List<AdamMemberCode> detailCodeListQuery(AdamMemberCodeListParam parameter) {
        LambdaQueryWrapper<AdamMemberCode> queryWrapper = Wrappers.lambdaQuery(AdamMemberCode.class).orderByDesc(AdamMemberCode::getCreatedAt);
        queryWrapper.eq(AdamMemberCode::getMemberId, parameter.getMemberId())
                .ne(AdamMemberCode::getState, 2)
                .select(
                        AdamMemberCode::getCode,
                        AdamMemberCode::getState,
                        AdamMemberCode::getMemberId
                        );
        return adamMemberCodeAdminService.list(queryWrapper);
    }

    @ApiOperation(value = "会员码:导出")
    @RequiresPermissions("adam:member:detail:code:export")
    @PostMapping("code_export")
    @ResponseBody
    public AjaxResult detailCodeExport(AdamMemberCodeListParam parameter) {
        List<AdamMemberCode> list = detailCodeListQuery(parameter);

        ExcelUtil<AdamMemberCodeExcelDto> excelUtil = new ExcelUtil<>(AdamMemberCodeExcelDto.class);
        List<AdamMemberCodeExcelDto> excelList = new ArrayList<>();
        list.forEach(r -> {
            excelList.add(AdamMemberCodeExcelDto.getNew().copy(r));
        });
        return excelUtil.exportExcel(excelList, "会员码数据");
    }

    @ApiOperation(value = "会员码:生成")
    @RequiresPermissions("adam:member:detail:code:gen")
    @PostMapping("code_gen")
    @ResponseBody
    public AjaxResult detailCodeGen(@Validated AdamMemberCodeGenParam parameter) {
        int count = adamMemberPriceAdminService.count(
                Wrappers.lambdaQuery(AdamMemberPrice.class)
                        .eq(AdamMemberPrice::getMemberPriceId, parameter.getMemberPriceId())
                        .eq(AdamMemberPrice::getMemberId, parameter.getMemberId())
                        .eq(AdamMemberPrice::getState, 1)
        );
        if (count <= 0) {
            logger.warn("会员卡ID/价格ID无效[{}]", parameter);
            return this.error("会员卡ID/价格ID无效");
        }
        return this.toAjax(adamMemberCodeAdminService.createGiftCode(parameter));
    }


//    @Log(title = "会员信息", businessType = BusinessType.LIST)
//    @RequiresPermissions("adam:member:list")
//    @ApiOperation(value = "会员卡列表")
//    @PostMapping("list")
//    public ResponseDto<List<AdamMemberVo>> list() {
//        List<AdamMember> list = adamMemberService.list(
//                Wrappers.lambdaQuery(AdamMember.class).select(
//                        AdamMember::getMemberId, AdamMember::getName, AdamMember::getTitle, AdamMember::getType, AdamMember::getState
//                )
//        );
//        List<AdamMemberVo> vos = new ArrayList<>();
//        list.forEach(r -> {
//            vos.add(AdamMemberVo.getNew().copy(r));
//        });
//        return ResponseDto.success(vos);
//    }
//
//    @Log(title = "会员信息", businessType = BusinessType.INSERT)
//    @RequiresPermissions("adam:member:add")
//    @ApiOperation(value = "添加会员卡")
//    @PostMapping("add")
//    public ResponseDto<Object> add(@Valid @RequestBody AdamMemberParam parameter) {
//        adamMemberService.add(parameter);
//        return ResponseDto.success();
//    }
//
//    @Log(title = "会员信息", businessType = BusinessType.DETAIL)
//    @RequiresPermissions("adam:member:info")
//    @ApiOperation(value = "会员卡详情")
//    @PostMapping("info")
//    public ResponseDto<Object> info(@NotBlank(message = "会员类型ID不能为空") @RequestParam String memberId) {
//        return ResponseDto.success(adamMemberService.getOne(
//                Wrappers.lambdaQuery(AdamMember.class).eq(AdamMember::getMemberId, memberId)
//        ));
//    }
//
//    @Log(title = "会员信息", businessType = BusinessType.UPDATE)
//    @RequiresPermissions("adam:member:edit")
//    @ApiOperation(value = "会员卡编辑")
//    @PostMapping("edit")
//    public ResponseDto<Object> edit(@Valid @RequestBody AdamMemberParam parameter) {
//        adamMemberService.edit(parameter);
//        return ResponseDto.success();
//    }
//
//    @Log(title = "会员信息", businessType = BusinessType.MEMBER_GEN_CODE)
//    @RequiresPermissions("adam:member:gen_code")
//    @ApiOperation(value = "生成兑换码")
//    @PostMapping("gen_code")
//    public ResponseDto<String> genMemberCode(@Valid @RequestBody AdamMemberCodeParam parameter) {
//        if (1 != parameter.getType()) {
//            return ResponseDto.failure("参数有误[TYPE]");
//        }
//        int count = adamMemberPriceAdminService.count(
//                Wrappers.lambdaQuery(AdamMemberPrice.class)
//                        .eq(AdamMemberPrice::getMemberPriceId, parameter.getMemberPriceId())
//                        .eq(AdamMemberPrice::getMemberId, parameter.getMemberId())
//                        .eq(AdamMemberPrice::getState, 1)
//        );
//        if (count <= 0) {
//            return ResponseDto.failure("会员卡ID/价格ID无效");
//        }
//        return ResponseDto.success(adamMemberCodeAdminService.createGiftCode(parameter));
//    }
}
