package com.iformall.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.enums.EnumAppType;
import com.iformall.mapper.WxAppinfoMapper;
import com.iformall.service.WxAppinfoService;
import com.iformall.utils.Constant;
import com.iformall.utils.MaUtil;
import com.iformall.utils.QRCodeUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.iformall.common.IdWorker;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

@Service
public class WxAppinfoServiceImpl implements WxAppinfoService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
    WxAppinfoMapper wxAppinfoMapper;

	@Override
    public WxAppinfo getCAppInfo(String tenantId) {
        WxAppinfo appInfo = null;
        WxAppinfo appinfoQ = new WxAppinfo();
        appinfoQ.setTenantId(tenantId);
        appinfoQ.setType(EnumAppType.C.getCode());
        List<WxAppinfo> appList = wxAppinfoMapper.select(appinfoQ);
        if (appList.size() > 0) {
            appInfo = appList.get(0);
        }
        return appInfo;
    }

    @Override
    public WxAppinfo getByAppId(String appId) {
        return wxAppinfoMapper.findByAppId(appId);
    }

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

    @Override
    public List<WxAppinfo> getList(WxAppinfo record) {
	    return wxAppinfoMapper.findList(record);
    }

    @Override
    public WxAppinfo getById(Long id) {
        return wxAppinfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public void saveOrUpdate(WxAppinfo record) {
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
        	record.setId(idWorker.nextId());
            wxAppinfoMapper.insertSelective(record);
        } else {
            wxAppinfoMapper.updateByPrimaryKeySelective(record);
        }
    }

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


    /**
     * 租户c端小程序更新token
     * @param tenantId
     */
    @Override
    public void ctokenUpdate(String tenantId) {
        WxAppinfo appQ = new WxAppinfo();
        appQ.setTenantId(tenantId);
        appQ.setType(EnumAppType.C.getCode());
        List<WxAppinfo> appList = wxAppinfoMapper.findList(appQ);
        if (appList.size() <= 0) {
            return;
        }
        WxAppinfo appinfo = appList.get(0);
        if(appinfo == null) {
            return;
        }
        // get access_token
        WxMaService wxMaService = MaUtil.getWeappService(appinfo);
        if(wxMaService == null) {
            return;
        }

        String access_token = "";
        try{
            access_token = wxMaService.getAccessToken();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        Date date = new Date();
        // update db
        appinfo.setAccessToken(access_token);
        appinfo.setLastTokenTime(date);
        wxAppinfoMapper.updateByPrimaryKeySelective(appinfo);
    }

    private void downFile(String filePath, String filename, HttpServletResponse response, HttpServletRequest req) throws IOException {
        try {
            response.reset();
            response.setContentType("bin");
            String agent = req.getHeader("user-agent");
            if (agent.contains("Firefox")) {
                response.setHeader("Content-disposition",
                        "attachment; filename="
                                + new String(filename.getBytes("GB2312"),"ISO-8859-1"));
            } else {
                response.setHeader("Content-disposition",
                                "attachment; filename="
                                        + java.net.URLEncoder.encode(filename,"UTF-8"));
            }
            // 循环取出流中的数据
            byte[] b = new byte[1024];
            int len;
            InputStream inStream = new FileInputStream(filePath);
            while ((len = inStream.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inStream.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    @Override
    public void exportQrcode(HttpServletRequest request, HttpServletResponse response,
                             String tenantId, int type, String pageUrl, String sceneParam,
                             int withText, String text1, String text2 ) {
        // type 0 有限二维码, 1 无限制二维码
        // withText 0 不带字 1. 带下面的字，2 带下面的两行字
        WxAppinfo appQ = new WxAppinfo();
        appQ.setTenantId(tenantId);
        appQ.setType(EnumAppType.C.getCode());
        List<WxAppinfo> appList = wxAppinfoMapper.findList(appQ);
        if (appList.size() <= 0) {
            return;
        }
        WxAppinfo appinfo = appList.get(0);
        boolean autoColor = false;
        boolean isHyaline = true;
        WxMaCodeLineColor color = new WxMaCodeLineColor("0", "0", "0");

        WxMaInMemoryConfig config = new WxMaInMemoryConfig();
        config.setAppid(appinfo.getAppId());
        config.setSecret(appinfo.getSecret());
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);

        String pathStr = "";
        if (StringUtils.isNotBlank(sceneParam)) {
            pathStr = pageUrl + "?scene="+sceneParam;
        } else {
            pathStr = pageUrl;
        }


        String filepath = Constant.fileDirectory;
        String fileName = sceneParam + ".png";
        String destPath1 = filepath + "1_" + fileName;
        String destPath = filepath + fileName;

        File dest = new File(destPath);
        File pDest = dest.getParentFile();
        if (!pDest.exists()) {
            pDest.mkdirs();
        }
        try {
            Date imgDate = new Date();
            if(type == 0) {
                final File codeFile = wxMaService.getQrcodeService().createQrcode(pathStr, QRCodeUtils.QR_WIDTH);
                if (withText == 1) {
                    File dest1 = new File(destPath1);
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest1);
                    QRCodeUtils.graphicsGeneration(dest1, dest, text1);
                    org.apache.commons.io.FileUtils.forceDelete(dest1);
                } else if (withText == 2) {
                    File dest1 = new File(destPath1);
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest1);
                    QRCodeUtils.graphicsGeneration2(dest1, dest, text1, text2);
                    org.apache.commons.io.FileUtils.forceDelete(dest1);
                } else {
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest);
                }
                org.apache.commons.io.FileUtils.forceDelete(codeFile);
            } else {
                final File codeFile = wxMaService.getQrcodeService().createWxaCodeUnlimit(sceneParam, pageUrl, QRCodeUtils.QR_WIDTH, autoColor, color, isHyaline);
                if (withText == 1) {
                    File dest1 = new File(destPath1);
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest1);
                    QRCodeUtils.graphicsGeneration(dest1, dest, text1);
                    org.apache.commons.io.FileUtils.forceDelete(dest1);
                } else if (withText == 2) {
                    File dest1 = new File(destPath1);
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest1);
                    QRCodeUtils.graphicsGeneration2(dest1, dest, text1, text2);
                    org.apache.commons.io.FileUtils.forceDelete(dest1);
                } else {
                    org.apache.commons.io.FileUtils.copyFile(codeFile, dest);
                }
                org.apache.commons.io.FileUtils.forceDelete(codeFile);
            }

        } catch (WxErrorException e) {
            logger.error(e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        try {
            downFile(destPath, fileName, response, request);
            org.apache.commons.io.FileUtils.forceDelete(dest);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }

    }
}
