package com.tzy.controller.group;

import com.github.pagehelper.PageInfo;
import com.tzy.annotation.ApiLimitRule;
import com.tzy.annotation.ApiLog;
import com.tzy.annotation.RequireRoles;
import com.tzy.app.dto.OpenCardParam;
import com.tzy.common.annotation.SensitiveData;
import com.tzy.common.config.handle.ApiVersion;
import com.tzy.common.constant.MsgConstants;
import com.tzy.common.dto.GoodsQuery;
import com.tzy.common.dto.InDto;
import com.tzy.common.dto.OutDTO;
import com.tzy.common.dto.UserInfo;
import com.tzy.common.enums.BusinessType;
import com.tzy.common.exception.AppAssert;
import com.tzy.common.utils.StringUtils;
import com.tzy.common.utils.UserType;
import com.tzy.common.utils.UserUtils;
import com.tzy.framework.web.domain.LimitRule;
import com.tzy.pojo.card.CardGroupGoods;
import com.tzy.pojo.card.CardGroupInfo;
import com.tzy.sportcard.api.bean.goods.PaniniCheckList;
import com.tzy.sportcard.api.bean.param.GoodsCheckParam;
import com.tzy.sportcard.api.bean.param.GroupPublicParam;
import com.tzy.sportcard.api.bean.param.PublicReportDTO;
import com.tzy.sportcard.api.domain.AppUserInfoDto;
import com.tzy.sportcard.api.domain.GoodsSerialDto;
import com.tzy.sportcard.api.service.*;
import com.tzy.sportcard.group.domain.AppUserWinCard;
import com.tzy.sportcard.group.domain.MerchantActGoods;
import com.tzy.sportcard.group.dto.MerchantCardInfoDTO;
import com.tzy.sportcard.group.dto.MerchantCardQuery;
import com.tzy.sportcard.group.dto.OpenCardDTO;
import com.tzy.sportcard.group.mapper.AppUserWinCardMapper;
import com.tzy.sportcard.group.service.ICardGroupGoodsService;
import com.tzy.sportcard.group.service.ICardGroupOrderReviewService;
import com.tzy.sportcard.group.service.impl.MerchantActGoodsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import org.teasoft.bee.osql.Condition;
import org.teasoft.bee.osql.Op;
import org.teasoft.bee.osql.SuidRich;
import org.teasoft.honey.osql.core.ConditionImpl;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author by po'yi
 * @Classname GroupControllerNew
 * @Description
 * @Date 2022/12/15 13:24
 */
@Api(value = "卡密相关新接口")
@RestController
@RequestMapping("/api/goods")
@Slf4j
public class GroupGoodsController {
    @Autowired
    @Lazy
    private GroupApiService groupApiService;
    @Autowired
    private ICardGroupOrderReviewService cardGroupOrderReviewService;
    @Autowired
    private SuidRich suidRich;
    @Autowired
    private ICardGroupGoodsService cardGroupGoodsService;
    @Resource
    @Lazy
    private IAllocateGoodsService allocateGoodsService;
    @Autowired
    private MineApiService mineApiService;
    @Resource
    private MerchantActGoodsService merchantActGoodsService;
    @Resource
    private  IAppUserWinCardService appUserWinCardService;
    @Resource
    private  ICardReportService cardReportService;
    @Resource
    private AppUserWinCardMapper appUserWinCardMapper;

    /**
     * 查询组团卡密
     *
     * @param inDto
     * @return
     */
    @ApiLog(title = "查询组团卡密", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ResponseBody
    @ApiVersion(1.0)
    @PostMapping(value = "/{version}/public/list")
    public OutDTO getPublicGroupGoods(@RequestBody InDto inDto) {
        return groupApiService.searchPublicGoods(inDto);
    }

    /**
     * 新版公示,兼容新旧版本
     */
    @ApiLog(title = "填写公示结果", businessType = BusinessType.INSERT, indto = "{{inDto}}")
    @ResponseBody
    @PostMapping(value = "/{version}/merchant/publicity")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    public OutDTO publicityResult(@RequestBody PublicReportDTO param) {
        if (param==null){
            return OutDTO.error500("参数不能为空");
        }
        GroupPublicParam publicParam = param.getPublicParam();
        groupApiService.publicityResult(publicParam);
        return OutDTO.ok();
    }

    @ApiLog(title = "卡片审核", businessType = BusinessType.SEARCH)
    @PostMapping(value = "/{version}/merchant/check/card")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    public OutDTO checkCardOrPass(@RequestBody InDto inDto) {
        GoodsCheckParam checkParam = inDto.buildParam(new GoodsCheckParam());
        if (checkParam.getGroupInfoId() == null || checkParam.getReviewStatus() == null) {
            return OutDTO.error(10090, "参数错误!");
        }
        if (StringUtils.isEmpty( checkParam.getIds()) &&  checkParam.getReviewStatus() == 3) {
            return OutDTO.error(10090, "请选中条目驳回!");
        }
        Long infoStatus=cardGroupOrderReviewService.checkGoods(checkParam);
        return OutDTO.ok().put("infoStatus", infoStatus);
    }

    @ApiLog(title = "清除新版卡密公示信息", businessType = BusinessType.SEARCH)
    @PostMapping(value = "/{version}/merchant/publicity/del")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    @ApiOperation("清除新版卡密公示信息,参数id(卡密id),goodsType")
    public OutDTO delGoodsPublicity(@RequestBody InDto inDto) {
        groupApiService.delGoodsPublicity(Long.valueOf(inDto.getString("id")),Integer.valueOf(inDto.getString("goodsType")));
        return OutDTO.ok();
    }

    @ApiLog(title = "删除卡密子条目", businessType = BusinessType.SEARCH)
    @PostMapping(value = "/{version}/merchant/publicity/del/sub")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    @ApiOperation("删除卡密子条目,参数id(卡密id),goodsType,paniniListId")
    public OutDTO delSubGoodsPublicity(@RequestBody InDto inDto) {
        groupApiService.delSubGoodsPublicity(Long.valueOf(inDto.getString("id")),Integer.valueOf(inDto.getString("goodsType")),
                Long.valueOf(inDto.getString("paniniListId")));
        return OutDTO.ok();
    }

    /**
     * 球队,球队帅选条件
     *
     * @param inDto
     * @return
     */
    @ApiLog(title = "球队,球队帅选条件", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ResponseBody
    @PostMapping(value = "/selected/param/type")
    public OutDTO searchParamByType(@RequestBody InDto inDto) {
        Integer paniniListId = (Integer) inDto.get("paniniListId");
        if(paniniListId==null){
            return OutDTO.error500("参数为空!");
        }
        String title = inDto.getString("title");
        if(StringUtils.isEmpty(title)){
            return OutDTO.error500("参数为空!");
        }
        String team = inDto.getString("team");
        String playerName = inDto.getString("playerName");
        if(StringUtils.isEmpty(team)&&StringUtils.isEmpty(playerName)){
            return OutDTO.error500("参数为空!");
        }
        return groupApiService.searchParamByType(title,paniniListId,team,playerName);
    }

    @ApiLog(title = "修改拆卡报告图片", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/{version}/change/publicity/image")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    @ApiOperation("修改拆卡报告图片,参数:groupInfoId,reportFlag(1:新,0:,旧)")
    @ApiVersion(1.0)
    public OutDTO changePublicityImage(@RequestBody InDto inDto) {
        Long groupInfoId = Long.valueOf(inDto.getString("groupInfoId"));
        Long cardGoodsId = Long.valueOf(inDto.getString("cardGoodsId"));
        String img = inDto.getString("imageStr");

        CardGroupGoods goods = new CardGroupGoods();
        goods.setGroupInfoId(groupInfoId);
        goods.setId(cardGoodsId);
        goods.setImg(img);
        suidRich.update(goods);
        AppUserWinCard appUserWinCard = new AppUserWinCard();
        List<Integer> ids = new ArrayList<>();
        ids.add(cardGoodsId.intValue());
        List<Long> cardids = appUserWinCardMapper.selectUserWindCardByGoodsId(ids);
        if(cardids!=null&&cardids.size()>0){
            appUserWinCard.setId(cardids.get(0));
        }
        appUserWinCard.setRefInfoId(groupInfoId);
        appUserWinCard.setGroupGoodsId(cardGoodsId);
        appUserWinCard.setImgUrl(img);
        appUserWinCardService.updateAppUserWinCard(appUserWinCard);
        List<Long> idList=new ArrayList<>();
        idList.add(cardGoodsId);
        cardReportService.syncCardWithGoodsId(idList);
        return OutDTO.ok();
    }


    @ApiLog(title = "切换拆卡报告版本", businessType = BusinessType.SEARCH)
    @PostMapping(value = "/{version}/change/publicity/type")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING, UserType.USER_ROLE_ADMIN})
    @ApiOperation("切换拆卡报告版本,参数:groupInfoId,reportFlag(1:新,0:,旧)")
    @ApiVersion(1.0)
    public OutDTO changePublicityType(@RequestBody InDto inDto) {
        Integer reportFlag=Integer.valueOf(inDto.getString("reportFlag"));
        Long groupInfoId=Long.valueOf(inDto.getString("groupInfoId"));
        CardGroupInfo groupInfo = new CardGroupInfo();
        groupInfo.setId(groupInfoId);
        CardGroupInfo cardGroupInfo = suidRich.selectOne(groupInfo);
        if(cardGroupInfo==null||cardGroupInfo.getStatus()!=205){
            return  OutDTO.error500("待公示的组队不存在");
        }

        if(cardGroupInfo.getPaniniListId()==null&&reportFlag==1){
            return  OutDTO.error500("此组队不支持新版公示报告");
        }
        Integer[] statusArr=new Integer[]{100,3,2,1};
        CardGroupGoods goods = new CardGroupGoods();
        goods.setGroupInfoId(groupInfoId);
        Condition beeCondition = new ConditionImpl();
        beeCondition.op("status", Op.in,statusArr);
        beeCondition.start(0).size(1);
        List<CardGroupGoods> existGoods = suidRich.select(goods, beeCondition);
        if(!existGoods.isEmpty()){
            return  OutDTO.error500("此组队已存在公示信息,暂不支持切换!");
        }
        groupInfo.setReportFlag(reportFlag);
        suidRich.update(groupInfo);
        return OutDTO.ok().put("reportFlag",reportFlag);
    }

    @ApiLog(title = "根据条件查询卡密信息", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ResponseBody
    @ApiVersion(1.0)
    @RequestMapping(value = "/{version}/team/id", method = RequestMethod.POST)
    public OutDTO getGroupGoods(@RequestBody InDto inDto) {
        String team = inDto.getString("team");
        Integer groupInfoId = (Integer) inDto.get("groupInfoId");
        String idxStr = inDto.getString("idx");
        if (StringUtils.isEmpty(team) && StringUtils.isEmpty(idxStr) && groupInfoId == null) {
            return OutDTO.error500("参数为空");
        }
        CardGroupInfo cardGroupInfo = getCardGroupInfo(groupInfoId);
        if(cardGroupInfo==null){
            return OutDTO.error500("组队不存在");
        }
        boolean isNewGoods = cardGroupInfo.getGoodsType() == 1;
        GoodsQuery query = new GoodsQuery().setGroupInfoId(cardGroupInfo.getId()).setTeam(team).setIdStr(idxStr);
        List<GoodsSerialDto> goods = cardGroupGoodsService.selectGoods(isNewGoods, query);
        return OutDTO.ok().put("goods", goods);
    }

    private CardGroupInfo getCardGroupInfo(Integer groupInfoId) {
        CardGroupInfo info = new CardGroupInfo();
        info.setId(groupInfoId.longValue());
        CardGroupInfo cardGroupInfo = suidRich.selectOne(info);
        return cardGroupInfo;
    }

    @ApiLog(title = "预售订单获取卡密", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ApiOperation("预售订单获取卡密,参数:OpenCardParam")
    @ResponseBody
    @ApiVersion(1.0)
    @ApiLimitRule(seconds = 2,limitCount=20,type= LimitRule.ACT,msg="抱歉,开卡人数太多,请稍后再试!")
    @PostMapping("/{version}/order/open")
    public OutDTO openGoodsByOrder(@RequestBody InDto inDto) {
        AppUserInfoDto user = mineApiService.checkUserNew(inDto);
        OpenCardParam param = inDto.buildParam(new OpenCardParam());
        if(param.getNum()==null||param.getNum()<1||param.getOrderId()==null){
            return OutDTO.error500("参数不符合要求");
        }
        param.setUser(user);
        OpenCardDTO openCardDTO = allocateGoodsService.allocateUserGoodsByOrder(param);
        return OutDTO.ok().put("openCardDTO",openCardDTO);
    }

    @ApiLog(title = "查询panini卡密", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ApiOperation("查询panini卡密,参数:GoodsQuery")
    @ResponseBody
    @ApiVersion(2.0)
    @PostMapping("/{version}/panini/list")
    public OutDTO getMineGoodsByCond(@RequestBody InDto inDto) {
        GoodsQuery query = inDto.buildParam(new GoodsQuery());
        query.setPageNo(inDto.getPageNo()).setPageSize(inDto.getPageSize());
        List<PaniniCheckList> goods = groupApiService.selectPaniniList(query);
        return OutDTO.ok().put("goods",goods);
    }

    @ApiLog(title = "商家好卡查询", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ApiOperation("商家好卡查询")
    @ResponseBody
    @ApiVersion(2.0)
    @SensitiveData
    @PostMapping("/{version}/top")
    public OutDTO getMerchantTopCard(@RequestBody InDto inDto) {
        MerchantCardQuery cardQuery = inDto.buildParam(new MerchantCardQuery());
        if (cardQuery.getMerchantId() == null && cardQuery.getPaniniListId() == null) {
            return OutDTO.error500(MsgConstants.PARAM_EMPTY);
        }
        UserInfo user = UserUtils.getSimpleUserInfo();
        if (user == null && cardQuery.getPaniniListId() == null) {
            return OutDTO.error500(MsgConstants.NEED_LOGIN);
        }
        boolean isMerchantOwner=false;
        if (user != null) {
            cardQuery.setUserId(user.getId());
            isMerchantOwner = Objects.equals(user.getMerchantId(), cardQuery.getMerchantId());
            if (!isMerchantOwner && cardQuery.getStatus() == null) {
                cardQuery.setStatus(1);
            }
        }
        if (cardQuery.getPaniniListId() != null) {
            cardQuery.setStatus(1);
        }
        cardQuery.setPageNo(inDto.getPageNo());
        cardQuery.setPageSize(inDto.getPageSize());
        PageInfo<MerchantCardInfoDTO> cards = merchantActGoodsService.getMerchantTopCards(cardQuery);
        if (!isMerchantOwner && cardQuery.getMerchantId() != null && Objects.equals(cardQuery.getStatus(), 1)) {
            cards.setTotal(Math.min(cards.getTotal(), 100));
        }
        return OutDTO.ok().put("cards", cards);
    }

    @ApiLog(title = "商家编辑好卡展示和排序", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ApiOperation("商家编辑好卡展示和排序")
    @ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作太频繁,请稍后再试!")
    @ResponseBody
    @ApiVersion(2.0)
    @SensitiveData
    @PostMapping("/{version}/top/edit")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING})
    public OutDTO editCardShow(@RequestBody InDto inDto) {
        UserInfo user = UserUtils.getSimpleUserInfo(true);
        AppAssert.notNull(user, MsgConstants.NEED_LOGIN);
        Integer id = inDto.getIntegerParam("id");
        Integer sortValue = inDto.getIntegerParam("sortValue");
        Integer status = inDto.getIntegerParam("status");
        if (id == null || (status == null && sortValue == null)) {
            return OutDTO.error500(MsgConstants.PARAM_EMPTY);
        }
        MerchantActGoods editGoods = new MerchantActGoods().setId(id.longValue()).setMerchantId(user.getMerchantId()).setSortValue(sortValue).setStatus(status);
        merchantActGoodsService.updateMerchantActGoods(editGoods);
        return OutDTO.ok();
    }


    @ApiLog(title = "商家选择或者取消好卡", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
    @ApiOperation("商家选择或者取消好卡")
    @ApiLimitRule(seconds = 1, limitCount = 1, type = LimitRule.USER, msg = "操作太频繁,请稍后再试!")
    @ResponseBody
    @ApiVersion(2.0)
    @SensitiveData
    @PostMapping("/{version}/top/show")
    @RequireRoles(value = {UserType.USER_ROLE_SHIPPING})
    public OutDTO editGoodsTopShow(@RequestBody InDto inDto) {
        UserInfo user = UserUtils.getSimpleUserInfo(true);
        AppAssert.notNull(user, MsgConstants.NEED_LOGIN);
        Integer id = inDto.getIntegerParam("id");
        Integer topSort = inDto.getIntegerParam("topSort");
        if (id == null || topSort == null) {
            return OutDTO.error500(MsgConstants.PARAM_EMPTY);
        }
        Long infoId = cardGroupGoodsService.editGoodsTopShow(id, topSort, user.getMerchantId());
        if (infoId != null) {
            merchantActGoodsService.syncTopGoodsRecord(infoId);
        }
        return OutDTO.ok();
    }
}