package com.iformall.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
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.WxAppinfo;
import com.iformall.domain.po.WxCampaign;
import com.iformall.domain.po.WxCouponChannel;
import com.iformall.domain.po.WxScreenAd;
import com.iformall.domain.vo.WxCouponCVo;
import com.iformall.enums.EnumCouponChannelType;
import com.iformall.enums.EnumCouponType;
import com.iformall.enums.EnumScreenAdType;
import com.iformall.mapper.WxCampaignMapper;
import com.iformall.mapper.WxCouponChannelMapper;
import com.iformall.mapper.WxScreenAdMapper;
import com.iformall.service.WxAppinfoService;
import com.iformall.service.WxScreenAdService;
import com.iformall.utils.MaUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class WxScreenAdServiceImpl implements WxScreenAdService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
    WxScreenAdMapper wxScreenAdMapper;

    @Autowired
    WxAppinfoService wxAppinfoService;

    @Autowired
    WxCouponChannelMapper wxCouponChannelMapper;

    @Autowired
    WxCampaignMapper wxCampaignMapper;

    @Override
    public PageInfo<WxScreenAd> listAsPage(WxScreenAd record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxScreenAdMapper.findList(record));
    }

    @Override
    public WxScreenAd getById(Long id) {
        return wxScreenAdMapper.selectByPrimaryKey(id);
    }

    @Override
    public ResultData saveOrUpdate(WxScreenAd record) {
        if (record.getId() == null) {
            if (record.getType() == null || record.getTargetId() == null) {
                return  new ResultData(ErrorCode.SYS_PARAMETER_ERROR);
            }
            if (record.getType().equals(EnumScreenAdType.COUPON.getCode())) {

                WxCouponCVo wxCouponCVo = wxCouponChannelMapper.findVoDetail(record.getTargetId());
                if (wxCouponCVo == null)
                    return  new ResultData(ErrorCode.COUPON_ORDER_IS_NULL);
                record.setCoverImg(wxCouponCVo.getCoverImg());
                record.setSubType(wxCouponCVo.getTargetAd());
                record.setTitle(wxCouponCVo.getTitle());

            } else if (record.getType().equals(EnumScreenAdType.COUPON.getCode())){
                WxCampaign wxCampaign = wxCampaignMapper.selectByPrimaryKey(record.getTargetId());
                if (wxCampaign == null)
                    return  new ResultData(ErrorCode.COUPON_ORDER_IS_NULL);
                record.setCoverImg(wxCampaign.getCoverImg());
                record.setTitle(wxCampaign.getTitle());
            }

            final IdWorker idWorker = IdWorker.get();
        	record.setId(idWorker.nextId());
        	record.setCreateDate(new Date());
            record.setUpdateDate(new Date());
            setQrcode(record);
            if (record.getQrcode() == null)
                return new ResultData(ErrorCode.DEVICE_QRCODE_GET_FAILED);

            wxScreenAdMapper.insertSelective(record);

        } else {
            record.setUpdateDate(new Date());
            setQrcode(record);
            wxScreenAdMapper.updateByPrimaryKeySelective(record);
        }
        return new ResultData();
    }

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

    @Override
    public List<WxScreenAd> findList(WxScreenAd wxTagsType) {
        return wxScreenAdMapper.findList(wxTagsType);
    }


    @Override
    public void updateStatusByCouponChannelId(Long couponChannelId, String tenantId, int status) {
        WxScreenAd wxScreenAd = new WxScreenAd();
        wxScreenAd.setTenantId(tenantId);
        wxScreenAd.setStatus(status);
        wxScreenAd.setTargetId(couponChannelId);
        wxScreenAd.setUpdateDate(new Date());
        wxScreenAdMapper.updateStatusByCouponChannelId(wxScreenAd);
    }

    @Override
    public void updateStatusByCouponId(Long couponId, String tenantId, int status) {

        WxCouponChannel wxCouponChannel = new WxCouponChannel();
        wxCouponChannel.setTenantId(tenantId);
        wxCouponChannel.setCouponId(couponId);

        List<WxCouponChannel> list = wxCouponChannelMapper.findList(wxCouponChannel);

        list.stream().forEach(cc->{
            WxScreenAd wxScreenAd = new WxScreenAd();
            wxScreenAd.setTenantId(tenantId);
            wxScreenAd.setStatus(status);
            wxScreenAd.setTargetId(cc.getId());
            wxScreenAd.setUpdateDate(new Date());
            wxScreenAdMapper.updateStatusByCouponChannelId(wxScreenAd);
        });
    }


    private void setQrcode(WxScreenAd record){
        if (record.getTargetId() != null &&
                record.getType() != null &&
                record.getTenantId() != null)
        try {
            record.setQrcode(getQrcode(record.getTargetId(),
                    record.getType().intValue(),
                    record.getSubType().intValue(),
                    wxAppinfoService.getCAppInfo(record.getTenantId())));
        }catch (Exception e) {
            logger.error("QRCODE set Error:"+e.getMessage());
        }
    }

    private static int QRCODE_WIDTH = 280;
    private static String QRCODE_PAGE_HOME = "pages/index/index";
    private static boolean QRCODE_AUTO_COLOR = false;
    private static boolean QRCODE_IS_HYALINE = true;
    //private static int QRCODE_LINCOLOR =;

    private static String QRCODE_JUMP_CMD_HOME = "JH";
    private static String QRCODE_JUMP_CMD_COUPON = "JC";
    private static String QRCODE_JUMP_CMD_GROUP = "JG";
    private static String QRCODE_JUMP_CMD_CAMPGIN = "JB";
    private byte[] getQrcode(Long id, int type, int subType, WxAppinfo appInfo) throws Exception {
        if(appInfo == null) {
            logger.error("QRCODE get error: appinfo is null");
            return null;
        }
        WxMaService wxMaService = MaUtil.getWeappService(appInfo);

        String scene = "";
        if (EnumScreenAdType.COUPON.getCode().equals(type)) {
            if (EnumCouponChannelType.COUPON_CHANNEL_ID_ORDER_GROUP.getCode().equals(subType)) {
                scene = QRCODE_JUMP_CMD_GROUP + ":" + id.toString();
            } else {
                scene = QRCODE_JUMP_CMD_COUPON + ":" + id.toString();
            }
        }
        else if (EnumScreenAdType.CAMPAIGN.getCode().equals(type))
            scene = QRCODE_JUMP_CMD_CAMPGIN+":"+id.toString();
        else
            scene = QRCODE_JUMP_CMD_HOME+":"+"0";

        try {
            return wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(scene, QRCODE_PAGE_HOME, QRCODE_WIDTH, QRCODE_AUTO_COLOR, null, QRCODE_IS_HYALINE);
        }catch (WxErrorException e) {
            logger.error("QRCODE get error: " + e.getMessage());
        }
        return null;
    }
}
