package cn.com.tenlion.buildingpictures.service.picturestemplatearea.impl;

import cn.com.tenlion.buildingpictures.dao.picturestemplatearea.IPicturesTemplateAreaDao;
import cn.com.tenlion.buildingpictures.pojo.dtos.picturestemplatearea.PicturesTemplateAreaBuildingDTO;
import cn.com.tenlion.buildingpictures.pojo.dtos.picturestemplatearea.PicturesTemplateAreaDTO;
import cn.com.tenlion.buildingpictures.pojo.vos.picturestemplatearea.PicturesTemplateAreaAllVO;
import cn.com.tenlion.buildingpictures.pojo.vos.picturestemplatearea.PicturesTemplateAreaPiointVO;
import cn.com.tenlion.buildingpictures.pojo.vos.picturestemplatearea.PicturesTemplateAreaVO;
import cn.com.tenlion.buildingpictures.service.picturestemplatearea.IPicturesTemplateAreaService;
import cn.com.tenlion.buildingpictures.service.picturestemplatebuilding.IPicturesTemplateBuildingService;
import cn.com.tenlion.buildingpictures.util.BaiDuMapUtil;
import cn.com.tenlion.buildingpictures.util.BarCodeUtils;
import cn.com.tenlion.buildingpictures.util.CreateImageBean;
import cn.com.tenlion.buildingpictures.util.WeiXinBarCodeUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.UpdateException;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultData;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.map.HashMapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName: PicturesTemplateAreaServiceImpl
 * @Description: 图片套版模板的区域设置
 * @Author: WenG
 * @Date: 2020-10-20 15:08
 * @Version: 1.0
 **/
@Primary
@Service
public class PicturesTemplateAreaServiceImpl extends DefaultBaseService implements IPicturesTemplateAreaService {

    @Autowired
    private IPicturesTemplateAreaDao picturesTemplateAreaDao;

    @Autowired
    private IPicturesTemplateBuildingService iPicturesTemplateBuildingService;

    @Override
    public SuccessResult savePicturesTemplateArea(PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        savePicturesTemplateAreaInfo(null, picturesTemplateAreaVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult savePicturesTemplateAreaByToken(String token, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        savePicturesTemplateAreaInfo(token, picturesTemplateAreaVO);
        return new SuccessResult();
    }

    @Override
    public String savePicturesTemplateAreaReturnId(PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        return savePicturesTemplateAreaInfoReturnId(null, picturesTemplateAreaVO);
    }

    @Override
    public String savePicturesTemplateAreaByTokenReturnId(String token, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        return savePicturesTemplateAreaInfoReturnId(token, picturesTemplateAreaVO);
    }

    /**
     * 新增图片套版模板的区域设置
     *
     * @param token
     * @param picturesTemplateAreaVO
     * @throws Exception
     */
    private void savePicturesTemplateAreaInfo(String token, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        savePicturesTemplateAreaInfoReturnId(token, picturesTemplateAreaVO);
    }

    /**
     * 新增图片套版模板的区域设置
     *
     * @param token
     * @param picturesTemplateAreaVO
     * @return picturesTemplateAreaId
     * @throws Exception
     */
    private String savePicturesTemplateAreaInfoReturnId(String token, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        String picturesTemplateAreaId = UUIDUtil.getUUID();

        picturesTemplateAreaVO.setTemplateAreaLeft(10.0);
        picturesTemplateAreaVO.setTemplateAreaDown(0.0);
        picturesTemplateAreaVO.setTemplateAreaRight(0.0);
        picturesTemplateAreaVO.setTemplateAreaTop(10.0);
        picturesTemplateAreaVO.setTemplateAreaHeight(300.0);
        picturesTemplateAreaVO.setTemplateAreaWidth(300.0);
        /**
         * 判断字段标识, 相同模板不能出现同样的字段标识
         */
        Map<String, Object> params = HashMapUtil.beanToMap(picturesTemplateAreaVO);
        params.put("picturesTemplateAreaId", picturesTemplateAreaId);
        if (StringUtils.isBlank(token)) {
            setSaveInfo(params);
        } else {
            setAppSaveInfo(token, params);
        }
        if (StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaSource())) {
            throw  new SaveException("标识不能为空");
        }
        picturesTemplateAreaVO.setTemplateAreaSource(picturesTemplateAreaVO.getTemplateAreaSource().trim());
        char[] c = picturesTemplateAreaVO.getTemplateAreaSource().toCharArray();
        for(int i = 0; i < c.length; i ++) {
            String len = Integer.toBinaryString(c[i]);
            if(len.length() > 8) {
                throw  new SaveException("标识中不能含有中文");
            }
        }
        if(!Character.isLowerCase(c[0])) {
            throw  new SaveException("首字母需要小写");
        }
        if("1".equals(picturesTemplateAreaVO.getTemplateAreaServerLink())) {
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFontValue())) {
                throw  new SaveException("示例文字不能为空");
            }
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFontSize())) {
                throw  new SaveException("字体大小不能为空");
            }
            if(!StringUtils.isNumeric(picturesTemplateAreaVO.getTemplateAreaFontSize())) {
                throw  new SaveException("字体大小输入不合法");
            }
            Integer size = Integer.valueOf(picturesTemplateAreaVO.getTemplateAreaFontSize());
            if(size > 100 || size < 1) {
                throw  new SaveException("字体大小范围为1-100");
            }
        }
        if("2".equals(picturesTemplateAreaVO.getTemplateAreaServerLink())) {
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFile())) {
                throw  new SaveException("示例图片不能为空");
            }
        }
        Map<String, Object> query = new HashMap<String, Object>();
        query.put("picturesTemplateId", picturesTemplateAreaVO.getPicturesTemplateId() );
        query.put("templateAreaSource", picturesTemplateAreaVO.getTemplateAreaSource());
        List<PicturesTemplateAreaDTO>  dto = picturesTemplateAreaDao.getPicturesTemplateAreaByPicturesTemplateId(query);
        if(dto != null && dto.size() > 0) {
            throw  new SaveException("当前标识已存在");
        }
        picturesTemplateAreaDao.savePicturesTemplateArea(params);
        return picturesTemplateAreaId;
    }

    @Override
    public SuccessResult removePicturesTemplateArea(String ids) throws RemoveException {
        removePicturesTemplateAreaInfo(null, ids);
        return new SuccessResult();
    }

    @Override
    public SuccessResult removePicturesTemplateAreaByToken(String token, String ids) throws RemoveException {
        removePicturesTemplateAreaInfo(token, ids);
        return new SuccessResult();
    }

    /**
     * 删除图片套版模板的区域设置
     *
     * @param token
     * @param ids
     */
    private void removePicturesTemplateAreaInfo(String token, String ids) {
        Map<String, Object> params = getHashMap(3);
        params.put("picturesTemplateAreaIds", Arrays.asList(ids.split("_")));
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        picturesTemplateAreaDao.removePicturesTemplateArea(params);
    }

    @Override
    public void deletePicturesTemplateArea(String ids) throws RemoveException {
        Map<String, Object> params = getHashMap(3);
        params.put("picturesTemplateAreaIds", Arrays.asList(ids.split("_")));
        picturesTemplateAreaDao.deletePicturesTemplateArea(params);
    }

    @Override
    public SuccessResult updatePicturesTemplateArea(String picturesTemplateAreaId, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        updatePicturesTemplateAreaInfo(null, picturesTemplateAreaId, picturesTemplateAreaVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updatePicturesTemplateAreaByToken(String token, String picturesTemplateAreaId, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        updatePicturesTemplateAreaInfo(token, picturesTemplateAreaId, picturesTemplateAreaVO);
        return new SuccessResult();
    }

    /**
     * 修改图片套版模板的区域设置
     *
     * @param token
     * @param picturesTemplateAreaId
     * @param picturesTemplateAreaVO
     */
    private void updatePicturesTemplateAreaInfo(String token, String picturesTemplateAreaId, PicturesTemplateAreaVO picturesTemplateAreaVO) throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(picturesTemplateAreaVO);
        params.put("picturesTemplateAreaId", picturesTemplateAreaId);
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        if (StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaSource())) {
            throw  new SaveException("标识不能为空");
        }
        picturesTemplateAreaVO.setTemplateAreaSource(picturesTemplateAreaVO.getTemplateAreaSource().trim());
        char[] c = picturesTemplateAreaVO.getTemplateAreaSource().toCharArray();
        for(int i = 0; i < c.length; i ++) {
            String len = Integer.toBinaryString(c[i]);
            if(len.length() > 8) {
                throw  new SaveException("标识中不能含有中文");
            }
        }
        if(!Character.isLowerCase(c[0])) {
            throw  new SaveException("首字母需要小写");
        }
        if("1".equals(picturesTemplateAreaVO.getTemplateAreaServerLink())) {
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFontValue())) {
                throw  new SaveException("示例文字不能为空");
            }
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFontSize())) {
                throw  new SaveException("字体大小不能为空");
            }
            if(!StringUtils.isNumeric(picturesTemplateAreaVO.getTemplateAreaFontSize())) {
                throw  new SaveException("字体大小输入不合法");
            }
            Integer size = Integer.valueOf(picturesTemplateAreaVO.getTemplateAreaFontSize());
            if(size > 100 || size < 1) {
                throw  new SaveException("字体大小范围为1-100");
            }
        }
        if("2".equals(picturesTemplateAreaVO.getTemplateAreaServerLink())) {
            if(StringUtils.isEmpty(picturesTemplateAreaVO.getTemplateAreaFile())) {
                throw  new SaveException("示例图片不能为空");
            }
        }
        Map<String, Object> query = new HashMap<String, Object>();
        query.put("picturesTemplateId", picturesTemplateAreaVO.getPicturesTemplateId() );
        query.put("templateAreaSource", picturesTemplateAreaVO.getTemplateAreaSource());
        List<PicturesTemplateAreaDTO>  dto = picturesTemplateAreaDao.getPicturesTemplateAreaByPicturesTemplateId(query);
        if(dto != null && dto.size() > 0) {
            if(dto.size() == 1) {
                if(!dto.get(0).getPicturesTemplateAreaId().equals(picturesTemplateAreaId)) {
                    throw  new SaveException("当前标识已存在");
                }
            }else{
                throw  new SaveException("当前标识已存在");
            }
        }
        picturesTemplateAreaDao.updatePicturesTemplateArea(params);
    }

    @Override
    public PicturesTemplateAreaDTO getPicturesTemplateAreaById(String picturesTemplateAreaId) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("picturesTemplateAreaId", picturesTemplateAreaId);
        return picturesTemplateAreaDao.getPicturesTemplateArea(params);
    }

    @Override
    public List<PicturesTemplateAreaDTO> listPicturesTemplateArea(Map<String, Object> params) throws SearchException {
        return picturesTemplateAreaDao.listPicturesTemplateArea(params);
    }

    @Override
    public SuccessResultList<List<PicturesTemplateAreaDTO>> listPagePicturesTemplateArea(ListPage page) throws SearchException {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<PicturesTemplateAreaDTO> picturesTemplateAreaDTOs = picturesTemplateAreaDao.listPicturesTemplateArea(page.getParams());
        PageInfo<PicturesTemplateAreaDTO> pageInfo = new PageInfo<>(picturesTemplateAreaDTOs);
        return new SuccessResultList<>(picturesTemplateAreaDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public Integer countNumberPicturesTemplateArea(Map<String, Object> params) throws SearchException {
        Integer count = picturesTemplateAreaDao.countPicturesTemplateArea(params);
        return count == null ? 0 : count;
    }

    @Override
    public SuccessResultData<Integer> countPicturesTemplateArea(Map<String, Object> params) throws SearchException {
        return new SuccessResultData<>(countNumberPicturesTemplateArea(params));
    }

    @Override
    public List<PicturesTemplateAreaDTO> getPicturesTemplateAreaByPicturesTemplateId(String picturesTemplateId) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("picturesTemplateId", picturesTemplateId);
        return picturesTemplateAreaDao.getPicturesTemplateAreaByPicturesTemplateId(params);
    }

    @Override
    public SuccessResult updatePicturesTemplateAreaPoint(String picturesTemplateAreaId, PicturesTemplateAreaPiointVO picturesTemplateAreaPiointVO) throws Exception {
        /**
         * 算出下，与 右
         */
        Double down = picturesTemplateAreaPiointVO.getTemplateAreaLeft() + picturesTemplateAreaPiointVO.getTemplateAreaWidth();
        picturesTemplateAreaPiointVO.setTemplateAreaDown(down);
        Double right = picturesTemplateAreaPiointVO.getTemplateAreaTop() + picturesTemplateAreaPiointVO.getTemplateAreaHeight();
        picturesTemplateAreaPiointVO.setTemplateAreaRight(right);
        Map<String, Object> params = HashMapUtil.beanToMap(picturesTemplateAreaPiointVO);
        params.put("picturesTemplateAreaId", picturesTemplateAreaId);
        setUpdateInfo(params);
        picturesTemplateAreaDao.updatePicturesTemplateAreaPoint(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult copyPicturesTemplateAreaPoint(String picturesTemplateAreaId, String templateAreaSource) throws Exception {
        PicturesTemplateAreaDTO dto = getPicturesTemplateAreaById(picturesTemplateAreaId);
        if(dto == null) {
            throw new UpdateException("需要复制的区域不存在");
        }
        if (StringUtils.isEmpty(templateAreaSource)) {
            throw  new SaveException("标识不能为空");
        }
        templateAreaSource = templateAreaSource.trim();
        char[] c = templateAreaSource.toCharArray();
        for(int i = 0; i < c.length; i ++) {
            String len = Integer.toBinaryString(c[i]);
            if(len.length() > 8) {
                throw  new SaveException("标识中不能含有中文");
            }
        }
        if(!Character.isLowerCase(c[0])) {
            throw  new SaveException("首字母需要小写");
        }
        Map<String, Object> query = new HashMap<String, Object>();
        query.put("picturesTemplateId", dto.getPicturesTemplateId() );
        query.put("templateAreaSource", templateAreaSource);
        List<PicturesTemplateAreaDTO>  dtoList = picturesTemplateAreaDao.getPicturesTemplateAreaByPicturesTemplateId(query);
        if(dto != null && dtoList.size() > 0) {
            throw  new SaveException("当前标识已存在");
        }
        String newPicturesTemplateAreaId = UUIDUtil.getUUID();
        dto.setTemplateAreaLeft(10.0);
        dto.setTemplateAreaDown(0.0);
        dto.setTemplateAreaRight(0.0);
        dto.setTemplateAreaTop(10.0);
        dto.setTemplateAreaHeight(300.0);
        dto.setTemplateAreaWidth(300.0);
        dto.setTemplateAreaSource(templateAreaSource);
        dto.setPicturesTemplateAreaId(newPicturesTemplateAreaId);
        Map<String, Object> params = HashMapUtil.beanToMap(dto);
        setSaveInfo(params);
        picturesTemplateAreaDao.savePicturesTemplateArea(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updatePicturesTemplateAreaPointModuleData(String picturesTemplateAreaId, String templateAreaModuleData) throws Exception {
        PicturesTemplateAreaDTO dto = getPicturesTemplateAreaById(picturesTemplateAreaId);
        if(dto == null) {
            throw new UpdateException("需要更改的区域不存在");
        }
        Map<String, Object> params = new HashMap();
        params.put("picturesTemplateAreaId", picturesTemplateAreaId);
        params.put("templateAreaModuleData", templateAreaModuleData);
        setUpdateInfo(params);
        picturesTemplateAreaDao.updatePicturesTemplateAreaPointModuleData(params);
        return new SuccessResult();
    }

    @Override
    public List<PicturesTemplateAreaDTO> getPicturesTemplateAreaByPicturesTemplateCode(String picturesTemplateCode) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("picturesTemplateCode", picturesTemplateCode);
        return picturesTemplateAreaDao.getPicturesTemplateAreaByPicturesTemplateCode(params);
    }

    @Override
    public SuccessResult updatePicturesTemplateAreaAll(String picturesTemplateId, PicturesTemplateAreaAllVO vo) throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(vo);
        params.put("picturesTemplateId", picturesTemplateId);
        setUpdateInfo(params);
        picturesTemplateAreaDao.updatePicturesTemplateAreaAll(params);
        return new SuccessResult();
    }

    @Override
    public List<PicturesTemplateAreaBuildingDTO> list(Map<String, Object> queryParams) {
        return picturesTemplateAreaDao.list(queryParams);
    }

    @Override
    public SuccessResultData<String> saveCreateFile(String picturesTemplateAreaId, String content) throws SaveException {
        PicturesTemplateAreaDTO areaDTO = getPicturesTemplateAreaById(picturesTemplateAreaId);
        if(!"3".equals(areaDTO.getTemplateAreaServerLink()) && !"4".equals(areaDTO.getTemplateAreaServerLink()) && !"5".equals(areaDTO.getTemplateAreaServerLink()) && !"6".equals(areaDTO.getTemplateAreaServerLink()) ) {
            throw new SearchException("不支持该操作");
        }
        CreateImageBean bean = new CreateImageBean();
        bean.setType(areaDTO.getTemplateAreaServerLink());
        bean.setContent(content);
        bean.setWidth(areaDTO.getTemplateAreaWidth().intValue());
        bean.setHeight(areaDTO.getTemplateAreaHeight().intValue());
        String newColor = areaDTO.getTemplateAreaFontColor().substring(4, areaDTO.getTemplateAreaFontColor().length() -1);
        String[] colorArr = newColor.split(",");
        int[] colorIntArr = new int[4];
        for (int i = 0; i < colorArr.length; i++) {
            colorIntArr[i] = Integer.valueOf(colorArr[i].trim());
        }
        bean.setColor(colorIntArr);
        bean.setX(areaDTO.getTemplateAreaLeft().intValue());
        bean.setY(areaDTO.getTemplateAreaTop().intValue());
        // 条形码
        if("3".equals(bean.getType())) {
            Pattern pattern1 = Pattern.compile("\\w+$");
            Matcher matcher1 = pattern1.matcher(bean.getContent());
            if(!matcher1.find()) {
                throw new SaveException("条形码不能包含中文与符号");
            }
            BufferedImage barcode = BarCodeUtils.getBarcode(bean.getContent(), bean.getWidth(), bean.getHeight(), new Color(bean.getColor()[0],bean.getColor()[1],bean.getColor()[2]));
            if(barcode != null) {
                String fileId = iPicturesTemplateBuildingService.saveBufferImageToFile(barcode);
                return new SuccessResultData<String>(fileId);
            }
        }
        // 二维码
        if("4".equals(bean.getType())) {
            BufferedImage rq = BarCodeUtils.getRQ(bean.getContent(), bean.getWidth(), bean.getHeight(), new Color(bean.getColor()[0],bean.getColor()[1],bean.getColor()[2]));
            if(rq != null) {
                String fileId = iPicturesTemplateBuildingService.saveBufferImageToFile(rq);
                return new SuccessResultData<String>(fileId);
            }
        }
        // 地图坐标
        if("5".equals(bean.getType())) {
            try{
                BufferedImage map = BaiDuMapUtil.getImage(bean.getContent(), bean.getWidth(), bean.getHeight());
                if(map != null) {
                    String fileId = iPicturesTemplateBuildingService.saveBufferImageToFile(map);
                    return new SuccessResultData<String>(fileId);
                }
            }catch(Exception e) {
                throw new SaveException("无法生成");
            }
        }
        // 小程序二维码
        if("6".equals(bean.getType())) {
            try{
                BufferedImage weiXinImage = WeiXinBarCodeUtils.getBarCodeImage(bean.getContent(),bean.getColor()[0],bean.getColor()[1],bean.getColor()[2]);
                if(weiXinImage != null) {
                    // 对二维码压缩裁剪
                    BufferedImage img = thumbnailBufferdImage(weiXinImage, bean.getWidth(), bean.getHeight());
                    String fileId = iPicturesTemplateBuildingService.saveBufferImageToFile(img);
                    return new SuccessResultData<String>(fileId);
                }
            }catch(Exception e) {
                throw new SaveException("无法生成");
            }
        }
        return new SuccessResultData<String>("");
    }


    /**
     * 图片压缩-按照固定宽高原图压缩
     * @Title : thumbnail
     * @功能描述 : TODO
     * @设定文件 : @param img 本地图片地址
     * @设定文件 : @param width 图片宽度
     * @设定文件 : @param height 图片高度
     * @设定文件 : @return
     * @设定文件 : @throws IOException
     * @返回类型 : Image
     * @throws :
     */
    private BufferedImage thumbnailBufferdImage(BufferedImage BI, int width, int height) throws IOException {
        Image image = BI.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.setColor(Color.RED);
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return tag;
    }

}