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.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.zhengzai.adam.service.IAdamMemberAdminService;
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.service.adam.dto.admin.AdamMemberBuildParam;
import com.liquidnet.service.adam.dto.admin.AdamMemberPriceBuildParam;
import com.liquidnet.service.adam.dto.admin.AdamMemberRightsBuildParam;
import com.liquidnet.service.adam.entity.AdamMember;
import com.liquidnet.service.adam.entity.AdamMemberPrice;
import com.liquidnet.service.adam.entity.AdamMemberRights;
import com.liquidnet.service.candy.dto.admin.CandyMemberCouponMatchParam;
import com.liquidnet.service.candy.dto.admin.CandyMgtCouponMemberDto;
import com.liquidnet.service.candy.entity.CandyCoupon;
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.beans.factory.annotation.Value;
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.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "会员管理")
@Controller
@RequestMapping("adam/member")
public class AdamMemberAdminController extends BaseController {
    private final String prefix = "zhengzai/adam/member";

    @Value("${liquidnet.client.admin.platformUrl}")
    private String platformUrl;

    @Autowired
    IAdamMemberAdminService adamMemberService;
    @Autowired
    IAdamMemberPriceAdminService adamMemberPriceAdminService;
    @Autowired
    IAdamMemberRightsAdminService adamMemberRightsAdminService;
    @Autowired
    ICandyMgtCouponAdminService candyMgtCouponAdminService;
    @Autowired
    ICandyCouponAdminService candyCouponAdminService;

    @GetMapping()
    public String view() {
        return prefix + "/member";
    }

    @RequiresPermissions("adam:member:view:list")
    @Log(title = "会员管理:会员卡:列表", businessType = BusinessType.LIST)
    @PostMapping("list")
    @ResponseBody
    public TableDataInfo list() {
        startPage();
        return getDataTable(adamMemberService.list(
                Wrappers.lambdaQuery(AdamMember.class).eq(AdamMember::getState, 1).select(
                        AdamMember::getMemberId, AdamMember::getIcon, AdamMember::getTitle, AdamMember::getSubTitle, AdamMember::getOnsale
                )
        ));
    }

    @RequiresPermissions("adam:member:view:edit")
    @Log(title = "会员管理:会员卡:详情", businessType = BusinessType.DETAIL)
    @GetMapping("info/{memberId}")
    public String info(@PathVariable("memberId") String memberId, ModelMap mmap) {
        AdamMember member = adamMemberService.getOne(Wrappers.lambdaQuery(AdamMember.class)
                .eq(AdamMember::getState, 1)
                .eq(AdamMember::getMemberId, memberId)
                .select(
                        AdamMember::getMemberId,
                        AdamMember::getName,
                        AdamMember::getTitle,
                        AdamMember::getSubTitle,
                        AdamMember::getAvatar,
                        AdamMember::getIcon,
                        AdamMember::getLimitation,
                        AdamMember::getLimitbAt,
                        AdamMember::getLimiteAt,
                        AdamMember::getNoticeInfo,
                        AdamMember::getNotes,
                        AdamMember::getType,
                        AdamMember::getOnsale,
                        AdamMember::getIntegralRate
                )
        );
        mmap.put("member", member);
        mmap.put("memberPriceList", java.util.Collections.emptyList());
        mmap.put("memberRightsList", java.util.Collections.emptyList());
        mmap.put("couponMemberDtoListMap", java.util.Collections.emptyMap());
        mmap.put("memberPrice", null);

        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::getMemberId,
                            AdamMemberRights::getMemberPriceId,
                            AdamMemberRights::getCover,
                            AdamMemberRights::getTitle,
                            AdamMemberRights::getSubTitle,
                            AdamMemberRights::getDetail
                    )
            );
            mmap.put("memberRightsList", memberRightsList);
            mmap.put("couponMemberDtoListMap", java.util.Collections.emptyMap());

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

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

                Map<String, List<CandyMgtCouponMemberDto>> couponMemberDtoListMap = couponMemberDtoList.stream().collect(Collectors.groupingBy(CandyMgtCouponMemberDto::getMcouponId));

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

            List<AdamMemberPrice> memberPriceList = adamMemberPriceAdminService.list(Wrappers.lambdaQuery(AdamMemberPrice.class)
                    .in(AdamMemberPrice::getState, Arrays.asList(1, 2))
                    .eq(AdamMemberPrice::getMemberId, member.getMemberId())
                    .orderByAsc(AdamMemberPrice::getState)
                    .orderByAsc(AdamMemberPrice::getDays)
                    .select(
                            AdamMemberPrice::getMemberPriceId,
                            AdamMemberPrice::getMemberId,
                            AdamMemberPrice::getName,
                            AdamMemberPrice::getPrice,
                            AdamMemberPrice::getPriceFixed,
                            AdamMemberPrice::getPriceSpecial,
                            AdamMemberPrice::getDays,
                            AdamMemberPrice::getState
                    )
            );
            mmap.put("memberPriceList", memberPriceList);
            AdamMemberPrice memberPrice = CollectionUtils.isEmpty(memberPriceList) ? null
                    : memberPriceList.stream()
                    .filter(p -> p.getState() != null && p.getState() == 1)
                    .max(Comparator.comparing(AdamMemberPrice::getDays, Comparator.nullsFirst(Integer::compareTo)))
                    .orElse(null);
            mmap.put("memberPrice", memberPrice);
        }
        mmap.put("platformUrl", platformUrl);
        return prefix + "/info";
    }

    @RequiresPermissions("adam:member:edit:onsale")
    @Log(title = "会员管理:会员卡编辑:开售停售", businessType = BusinessType.UPDATE)
    @PostMapping("edit_onsale")
    @ResponseBody
    public AjaxResult editOnsale(AdamMemberBuildParam parameter) {
        return this.toAjax(adamMemberService.edit(parameter));
    }

    @ApiOperation(value = "会员设置:基础信息编辑")
    @RequiresPermissions("adam:member:edit:basic")
    @Log(title = "会员管理:会员卡编辑:基础信息", businessType = BusinessType.UPDATE)
    @PostMapping("edit_basic")
    @ResponseBody
    public AjaxResult editBasic(@Validated AdamMemberBuildParam parameter) {
        return this.toAjax(adamMemberService.edit(parameter));
    }

    @ApiOperation(value = "会员套餐:价格编辑")
    @RequiresPermissions("adam:member:edit:price")
    @Log(title = "会员管理:会员卡编辑:价格配置", businessType = BusinessType.UPDATE)
    @PostMapping("edit_price")
    @ResponseBody
    public AjaxResult editPrice(@Validated AdamMemberPriceBuildParam parameter) {
        return AjaxResult.success(adamMemberPriceAdminService.edit(parameter));
    }

    @ApiOperation(value = "会员套餐:权益编辑")
    @RequiresPermissions("adam:member:edit:rights")
    @Log(title = "会员管理:会员卡编辑:权益", businessType = BusinessType.UPDATE)
    @PostMapping("edit_rights")
    @ResponseBody
    public AjaxResult editRights(@Validated AdamMemberRightsBuildParam parameter) {
        if (parameter.getState() != 2) {
            // 这里编辑包含新增、更新、删除分别对应state:1,1,2
            parameter.setState(1);
            if (StringUtils.isBlank(parameter.getMemberPriceId())) {
                return AjaxResult.warn("请指定权益所属价格包");
            }
        } else if (StringUtils.isBlank(parameter.getMrightsId())) {
            return AjaxResult.warn("请指定要删除的权益ID");
        }
        if (null == parameter.getSeqNo()) {
            parameter.setSeqNo(0);
        }
        AdamMemberRights rights = adamMemberRightsAdminService.edit(parameter);
        if (rights == null || StringUtils.isBlank(rights.getMrightsId())) {
            return AjaxResult.error("权益保存失败");
        }
        // 显式回传 id，避免实体序列化字段名差异导致前端读不到
        Map<String, Object> data = new HashMap<>(8);
        data.put("mrightsId", rights.getMrightsId());
        data.put("memberId", rights.getMemberId());
        data.put("memberPriceId", rights.getMemberPriceId());
        data.put("state", rights.getState());
        data.put("title", rights.getTitle());
        return AjaxResult.success(data);
    }

//    @ApiOperation(value = "会员套餐:券编辑")
//    @RequiresPermissions("adam:member:edit:coupon")
//    @Log(title = "会员管理:会员卡编辑:权益券", businessType = BusinessType.UPDATE)
//    @PostMapping("edit_coupon")
//    @ResponseBody
//    public AjaxResult editCoupon(@RequestBody @Validated CandyMemberCouponBuildParam parameter) {
//        Integer busiType = parameter.getBusiType();// 业务类别[0-全场｜1-演出｜2-商品｜3-优先购]
////        if (busiType > 0) {
////            if (CollectionUtils.isEmpty(parameter.getCouponRuleList())) {
////                return AjaxResult.warn("适用范围无效");
////            }
////        } else {
////            parameter.setCouponRuleList(null);
////        }
//        parameter.setCouponRuleList(Collections.singletonList(CandyCouponRuleBuildParam.getNew().setUseScope(100)));
//
//        parameter.setOverlay(busiType < 3 ? 0 : parameter.getOverlay());
//        switch (parameter.getCouType()) {// 券类型[1-代金券｜2-满减券]
//            case 1:
//                BigDecimal valFace = parameter.getValFace();
//                if (null == valFace || valFace.compareTo(BigDecimal.ZERO) <= 0) {
//                    return AjaxResult.warn("代金券金额无效");
//                }
//                parameter.setValOver(null);
//                parameter.setValMinus(null);
//                break;
//            case 2:
//                BigDecimal valOver = parameter.getValOver();
//                BigDecimal valMinus = parameter.getValMinus();
//                if (null == valOver || valOver.compareTo(BigDecimal.ZERO) <= 0
//                        || null == valMinus || valMinus.compareTo(BigDecimal.ZERO) <= 0) {
//                    return AjaxResult.warn("满减金额无效");
//                }
//                parameter.setValFace(valMinus);
//                break;
//            case 101:
//                parameter.setValFace(null);
//                parameter.setValOver(null);
//                parameter.setValMinus(null);
//                break;
//            default:
//                logger.warn("Invalid operation[buildParam.couType={}]", parameter.getCouType());
//                return this.error(AjaxResult.Type.WARN, "券类型无效");
//        }
//
//
//        if (StringUtils.isEmpty(parameter.getCouponId())) {
//            // 新增券
//            return this.toAjax(candyMgtCouponAdminService.saveMgtCouponForMemberRights(parameter));
//        } else {
//            // 编辑券
//            return this.toAjax(candyMgtCouponAdminService.editMgtCouponForMemberRights(parameter));
//        }
//    }

    @ApiOperation(value = "会员套餐:券编辑")
    @RequiresPermissions("adam:member:edit:coupon")
    @Log(title = "会员管理:会员卡编辑:权益券", businessType = BusinessType.UPDATE)
    @PostMapping("edit_coupon")
    @ResponseBody
    public AjaxResult editCoupon(@RequestBody @Validated CandyMemberCouponMatchParam parameter) {
        switch (parameter.getBusiType()) {// 券类别类型配置校验
            case 0:
            case 1:
                if (!Arrays.asList(1, 2).contains(parameter.getCouType())) {
                    String msg = String.format("会员券类别【%s】", parameter.getBusiType() == 0 ? "全场" : "演出");
                    logger.warn("{}暂不支持所选券类型[{}]", msg, parameter.getCouType());
                    return this.error(AjaxResult.Type.WARN, String.format("%s暂不支持所选券类型", msg));
                }
                break;
            case 2:
                if (!Arrays.asList(1, 2, 3).contains(parameter.getCouType())) {
                    logger.warn("券类别【商品】暂不支持所选券类型[{}]", parameter.getCouType());
                    return this.error(AjaxResult.Type.WARN, "会员券类别【商品】暂不支持所选券类型");
                }
                break;
            case 3:
                if (101 != parameter.getCouType()) {
                    logger.warn("会员券类别【优先购买】暂不支持所选券类型[{}]", parameter.getCouType());
                    return this.error(AjaxResult.Type.WARN, "会员券类别【优先购买】暂不支持所选券类型");
                }
                break;
            default:
                logger.warn("Invalid argument[parameter.busiType={}]", parameter.getBusiType());
                return this.error(AjaxResult.Type.WARN, "无效的券类别");
        }

        LambdaQueryWrapper<AdamMemberRights> memberRightsLambdaQueryWrapper = Wrappers.lambdaQuery();
        memberRightsLambdaQueryWrapper.eq(AdamMemberRights::getMrightsId, parameter.getMrightsId());
        memberRightsLambdaQueryWrapper.eq(AdamMemberRights::getState, 1);
        AdamMemberRights memberRights = adamMemberRightsAdminService.getOne(memberRightsLambdaQueryWrapper);
        if (null == memberRights) {
            logger.warn("会员权益[{}]不存在", parameter.getMrightsId());
            return this.error(AjaxResult.Type.WARN, String.format("会员权益【%s】不存在", parameter.getMrightsId()));
        }
        if (!memberRights.getMemberId().equals(parameter.getMemberId())) {
            logger.warn("会员权益[{}]所属卡[{}]与所选卡[{}]不一致", parameter.getMrightsId(), memberRights.getMemberId(), parameter.getMemberId());
            return this.error(AjaxResult.Type.WARN, "权益配置不匹配");
        }

        LambdaQueryWrapper<CandyCoupon> couponLambdaQueryWrapper = Wrappers.lambdaQuery();
        couponLambdaQueryWrapper.eq(CandyCoupon::getCouponId, parameter.getCouponId());
        couponLambdaQueryWrapper.eq(CandyCoupon::getState, 1);
        CandyCoupon coupon = candyCouponAdminService.getOne(couponLambdaQueryWrapper);
        if (null == coupon) {
            logger.warn("会员权益券[{}]不存在", parameter.getCouponId());
            return this.error(AjaxResult.Type.WARN, String.format("券【%s】不存在", parameter.getCouponId()));
        }
        if (!coupon.getBusiType().equals(parameter.getBusiType())) {
            logger.warn("会员权益券[{}]类别[{}]与所选类别[{}]不一致", parameter.getCouponId(), coupon.getBusiType(), parameter.getBusiType());
            return this.error(AjaxResult.Type.WARN, "券信息不匹配");
        }
        if (!coupon.getCouType().equals(parameter.getCouType())) {
            logger.warn("会员权益券[{}]类型[{}]与所选类型[{}]不一致", parameter.getCouponId(), coupon.getCouType(), parameter.getCouType());
            return this.error(AjaxResult.Type.WARN, "券信息不匹配");
        }

        LambdaQueryWrapper<CandyMgtCoupon> mgtCouponLambdaQueryWrapper = Wrappers.lambdaQuery();
        mgtCouponLambdaQueryWrapper.eq(CandyMgtCoupon::getMcouponId, parameter.getMrightsId());
        mgtCouponLambdaQueryWrapper.in(CandyMgtCoupon::getCouponId, parameter.getCouponId(), parameter.getOperCouponId());
        mgtCouponLambdaQueryWrapper.eq(CandyMgtCoupon::getState, 10);
        List<CandyMgtCoupon> mgtCouponList = candyMgtCouponAdminService.list(mgtCouponLambdaQueryWrapper);
        switch (parameter.getOper()) {
            case 1:// 添加
                if (!CollectionUtils.isEmpty(mgtCouponList)) {
                    logger.warn("会员权益[{}]已配置该券[{}]", parameter.getMrightsId(), parameter.getCouponId());
                    return this.error(AjaxResult.Type.WARN, "该权益已配置当前券，请选择其它券");
                }
                break;
            case 2:// 删除
                if (CollectionUtils.isEmpty(mgtCouponList)) {
                    logger.warn("会员权益[{}]中不存在该券[{}]", parameter.getMrightsId(), parameter.getCouponId());
                    return this.error(AjaxResult.Type.WARN, "该权益未配置当前券，请核实确认");
                }
                break;
            case 3:// 编辑
                if (StringUtils.isBlank(parameter.getOperCouponId())) {
                    logger.warn("会员权益券[{}]编辑未指定券ID[{},{}]", parameter.getMrightsId(), parameter.getOperCouponId(), parameter.getCouponId());
                    return this.error(AjaxResult.Type.WARN, "编辑未指定券ID【operCouponId】");
                }
                if (CollectionUtils.isEmpty(mgtCouponList)) {
                    logger.warn("会员权益[{}]编辑指定券[{}]无效", parameter.getMrightsId(), parameter.getCouponId());
                    return this.error(AjaxResult.Type.WARN, String.format("编辑指定券【%s】无效", parameter.getOperCouponId()));
                }
                break;
            default:
                logger.warn("Invalid operation[parameter.oper={}]", parameter.getOper());
                return this.error(AjaxResult.Type.WARN, "无效操作");
        }

        try {
            return this.toAjax(candyMgtCouponAdminService.saveUpdateMgtCouponForMemberRights(parameter, coupon));
        } catch (Exception e) {
            logger.error("会员管理:会员卡编辑:权益券配置异常", e);
            return this.toAjax(false);
        }
    }
}
