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.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.WxCouponChannelMapper;
import com.iformall.mapper.WxCouponMerchantMapper;
import com.iformall.mapper.WxMerchantMapper;
import com.iformall.service.WxCouponChannelService;
import com.iformall.service.WxCouponService;
import com.iformall.service.WxOrderService;
import com.iformall.service.WxScreenAdService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@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;
    /**
     * 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.selectByPrimaryKey(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.insertSelective(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());
                }
            }
            record.setUpdateDate(new Date());
            wxCouponChannelMapper.updateByPrimaryKeySelective(record);
        }
        return new ResultData();
    }

    @Override
    public void deleteById(Long id) {
        wxCouponChannelMapper.deleteByPrimaryKey(id);
    }

    @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 != null){
                    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);
    }

    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())){ //列表默认投放结束时间为有效时间之后
            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());
        saveOrUpdate(wxCouponChannel);
        return null;
    }

    /**
     * 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 List<WxCouponChannelVo> listVo(WxCouponChannel record) {
        return wxCouponChannelMapper.findVoList(record);
    }

}
