package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxCoupon;
import com.iformall.domain.po.WxCouponChannel;
import com.iformall.domain.vo.WxCouponCVo;
import com.iformall.domain.vo.WxCouponChannelAddVo;
import com.iformall.domain.vo.WxCouponChannelVo;
import com.iformall.domain.vo.WxMerchantVo;
import com.iformall.enums.*;
import com.iformall.mapper.*;
import com.iformall.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WxCouponChannelServiceImpl implements WxCouponChannelService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
    WxCouponChannelMapper wxCouponChannelMapper;
	@Autowired
    WxCouponService wxCouponService;
    @Autowired
    WxMerchantMapper wxMerchantMapper;
    @Autowired
    WxCouponMerchantMapper wxCouponMerchantMapper;
    @Autowired
    WxScreenAdService wxScreenAdService;
    @Autowired
    WxOrderService wxOrderService;
    @Autowired
    QrCodeService qrCodeService;
    @Autowired
    WxCardInfoMapper wxCardInfoMapper;
    @Autowired
    WxFloatingLayerMapper wxFloatingLayerMapper;

    /**
     * B端业务端
     * @param record
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<WxCouponChannel> listAsPage(WxCouponChannel record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponChannelMapper.findList(record));
    }

    @Override
    public WxCouponChannel getById(Long id) {
        return wxCouponChannelMapper.selectById(id);
    }

    @Override
    public ResultData saveOrUpdate(WxCouponChannel record) {
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
        	record.setId(idWorker.nextId());
            wxCouponChannelMapper.insert(record);
            return new ResultData(record);
        } else {
            if (record.getCouponId() != null && record.getStatus() != null) {
                WxCouponChannel orignal = getById(record.getId());
                if (orignal.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())
                        && record.getStatus().equals(EnumCouponChannelStatus.STATUS_THROW_IN.getCode())) {

                    WxCoupon wxCoupon = wxCouponService.getById(orignal.getCouponId());
                    if (wxCoupon == null)
                        return new ResultData(ErrorCode.COUPON_IS_EMPTY);
                    if (wxCoupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF))
                        return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF);

                    //查找是否该券 在该频道有其他上架
                    WxCouponChannel query = new WxCouponChannel();
                    query.setTenantId(orignal.getTenantId());
                    query.setCouponId(orignal.getCouponId());
                    query.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode());//已上架
                    query.setTargetAd(orignal.getTargetAd());
                    List<WxCouponChannel> list = wxCouponChannelMapper.findList(query);
                    if (list != null && list.size() > 0) {
                        return new ResultData(ErrorCode.COUPON_CHANNEL_IS_EXISTED);
                    }
                }
            }
            if (record.getStatus() != null) {
                WxCouponChannel orignal = getById(record.getId());
                if (orignal.getStatus().equals(EnumCouponChannelStatus.STATUS_THROW_IN.getCode())
                        && record.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())) {
                    wxScreenAdService.updateStatusByCouponChannelId(record.getId(),record.getTenantId(),EnumScreenAdStatus.INVALID.getCode());
                    //下架拼团券
                    wxOrderService.updateOrderGroupStatusByCouponChannelId(record.getId(), record.getTenantId(), EnumOrderStatus.ORDER_STATUS_COOPERATING_CANCEL.getCode());
                    //修改卡状态
                    wxCardInfoMapper.updateTransferStatusByCouponId(orignal.getCouponId());
                    //浮层下架
                    wxFloatingLayerMapper.updateStatus(orignal.getCouponId());
                }
            }
            record.setUpdateDate(new Date());
            wxCouponChannelMapper.updateById(record);
        }
        return new ResultData();
    }

    @Override
    public ResultData addBatch(String[] ids, String[] channelId, String tanantId, Date beginTime, Date endTime) {
        List<WxCouponChannelAddVo> errorList  = new ArrayList<>();
        for (String targetIdstr:channelId) {
            Integer targetId = Integer.parseInt(targetIdstr);
            for (String couponidstr:ids) {
                Long couponid = Long.parseLong(couponidstr);
                WxCouponChannelAddVo vo = addCouponChannel(couponid,targetId,tanantId,beginTime,endTime);
                if(!vo.isSuc()){
                    errorList.add(vo);
                }
            }
        }
        if(errorList.size()>0) {
            return new ResultData(errorList);
        }else {
            return new ResultData();
        }
    }

    @Override
    public void updateStatusByCouponId(Long couponId, String tenantId, int status) {
        WxCouponChannel wxCouponChannel = new WxCouponChannel();
        wxCouponChannel.setTenantId(tenantId);
        wxCouponChannel.setStatus(status);
        wxCouponChannel.setCouponId(couponId);
        wxCouponChannel.setUpdateDate(new Date());
        wxCouponChannelMapper.updateStatusByCouponId(wxCouponChannel);
    }

    @Override
    public ResultData change(WxCouponChannel record) {
        Long couponId = 0L;
        if (record.getCouponId() != null) {
            couponId = record.getCouponId();
            record.setCouponId(null);
        }
        List<WxCouponChannelVo> voList = wxCouponChannelMapper.findVoList(record);
        if (voList.isEmpty()) {
            return new ResultData(Result.SUCCESS, "查询成功", null);
        }
        Map<String, Object> data = new HashMap<>();
        if (voList.size() == 1) {
            data.put("size", 1);
            data.put("data", voList.get(0));
            return new ResultData(Result.SUCCESS, "查询成功", data);
        }
        Long finalCouponId = couponId;
        int size = voList.size();
        data.put("size", size);
        voList = voList.stream()
                .filter(wxCouponChannelVo -> !wxCouponChannelVo.getCouponId().equals(finalCouponId))
                .collect(Collectors.toList());
        size = voList.size();
        Random random = new Random();
        data.put("data", voList.get(random.nextInt(size)));
        return new ResultData(Result.SUCCESS, "查询成功", data);
    }

    private boolean isCouponMerchantValid(Long couponId) {
        Map paramMap = new HashMap<>();
        paramMap.put("productId",couponId);
        List<WxMerchantVo> merchantVoList = wxCouponMerchantMapper.findMerchantNameList(paramMap);
        if (merchantVoList.stream().anyMatch((cm->cm.getMerchantStatus().equals(EnumMerchantStatus.VALID.getCode())))){
            return true;
        }
        return false;
    }

    public WxCouponChannelAddVo addCouponChannel(Long couponid,Integer channelId,String tanantId,Date beginTime,Date endTime){

        WxCouponChannelAddVo vo = new WxCouponChannelAddVo();

        WxCoupon wxCoupon = wxCouponService.getById(couponid);
        if(wxCoupon==null){
            logger.debug(couponid+ErrorCode.COUPON_IS_EMPTY.getMessage());
            vo.toCouponChannnelVo(null,channelId);
            vo.setErrorMsg(ErrorCode.COUPON_IS_EMPTY.getMessage());
            return vo;
        }

        WxCouponChannel wxCouponChannelQuery = new WxCouponChannel();
        wxCouponChannelQuery.setTenantId(tanantId);
        wxCouponChannelQuery.setCouponId(couponid);
        wxCouponChannelQuery.setTargetAd(channelId);
        wxCouponChannelQuery.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode());
        List<WxCouponChannel> wxCouponChannels = wxCouponChannelMapper.findList(wxCouponChannelQuery);
        if(wxCouponChannels.size()>0){
            logger.debug(couponid+ErrorCode.COUPON_CHANNEL_IS_EXISTED.getMessage());
            vo.toCouponChannnelVo(wxCoupon,channelId);
            vo.setErrorMsg(ErrorCode.COUPON_CHANNEL_IS_EXISTED.getMessage());
            return vo;
        }

        if(wxCoupon.getStatus()!=EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode()) {
            logger.debug(wxCoupon.getId()+couponid+ErrorCode.COUPON_IS_TAKE_OFF.getMessage());
            vo.toCouponChannnelVo(wxCoupon,channelId);
            vo.setErrorMsg(ErrorCode.COUPON_IS_TAKE_OFF.getMessage());
            return vo;
        }

        if(!isCouponMerchantValid(wxCoupon.getId())) {
            logger.debug(wxCoupon.getId()+couponid+ErrorCode.MERCHANT_INFO_NOT_FOUND.getMessage());
            vo.toCouponChannnelVo(wxCoupon,channelId);
            vo.setErrorMsg(ErrorCode.MERCHANT_INFO_NOT_FOUND.getMessage());
            return vo;
        }

        // 投放渠道
        if(channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_LIST.getCode())  ||  // 列表
                channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_CARD.getCode()) ||  // 卡频道
                channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_PRESS.getCode()) || // 砍价
                channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_ORDER_GROUP.getCode()) || // 拼团
                channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_CREDIT.getCode())   // 积分商城
            ){
            // 默认投放结束时间为有效时间之后
            beginTime = new Date();
            endTime = wxCoupon.getValidEndDate();
        }

        if(channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())){ // 限时抢购
            if(wxCoupon.getValidEndDate()!=null&&wxCoupon.getValidEndDate().before(endTime)){
                logger.debug(wxCoupon.getId()+ErrorCode.COUPON_SEND_IS_INVALID_TIME.getMessage());
                vo.toCouponChannnelVo(wxCoupon,channelId);
                vo.setErrorMsg(ErrorCode.COUPON_SEND_IS_INVALID_TIME.getMessage());
                return vo;
            }
        }

        WxCouponChannel wxCouponChannel = new WxCouponChannel();
        wxCouponChannel.setEndTime(endTime);
        wxCouponChannel.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode());
        wxCouponChannel.setBeginTime(beginTime);
        wxCouponChannel.setCouponId(couponid);
        wxCouponChannel.setType(wxCoupon.getType());
        wxCouponChannel.setTargetAd(channelId);
        wxCouponChannel.setTenantId(tanantId);
        wxCouponChannel.setBusiness(wxCoupon.getBusiness());
        wxCouponChannel.setSubBusiness(wxCoupon.getSubBusiness());
        wxCouponChannel.setTitle(wxCoupon.getTitle());
        ResultData resultData = saveOrUpdate(wxCouponChannel);
        WxCouponChannel channel = (WxCouponChannel)resultData.data;
        vo.setId(channel.getId());
        vo.setType(channel.getType());
        vo.setSuc(true);

        String pageUrl = "pages/index/index";
        WxCouponChannel couponChannel = new WxCouponChannel();
        couponChannel.setId(vo.getId());
        couponChannel.setType(vo.getType());
        String param = couponChannel.getWeappScene();
        ResultData resultDataQ = qrCodeService.uploadQrcode(wxCoupon.getTenantId(),1,pageUrl,param,0,"","","卷");
        Map<String,String> map = (Map)resultDataQ.data;
        if(map!=null && map.get("url") !=null) {
            String url = map.get("url");
            couponChannel.setQrCode(url);
            wxCouponChannelMapper.updateById(couponChannel);
        }
        return vo;
    }

    /**
     * C端api使用,关联查找的券时已生效
     * @param record
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<WxCouponChannelVo> listPageCVo(WxCouponChannel record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponChannelMapper.findVoList(record));
    }

    @Override
    public WxCouponCVo findDetailVo(Long id) {
        return wxCouponChannelMapper.findVoDetail(id);
    }

    @Override
    public WxCouponCVo findVoStatusDetail(Long id) {
        return wxCouponChannelMapper.findVoStatusDetail(id);
    }

    @Override
    public List<WxCouponChannelVo> listVo(WxCouponChannel record) {
        return wxCouponChannelMapper.findVoList(record);
    }

    @Override
    public PageInfo<WxCouponChannelVo> listByMerchant(WxCouponChannel record, Integer pageNum, Integer pageSize) {
        return PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> wxCouponChannelMapper.findVoListByMerchant(record));
    }

}
