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

import cn.com.tenlion.buildingpictures.dao.picturestemplate.IPicturesTemplateDao;
import cn.com.tenlion.buildingpictures.dao.picturestemplatearea.IPicturesTemplateAreaDao;
import cn.com.tenlion.buildingpictures.pojo.dtos.picturestemplate.PicturesTemplateBuildingDTO;
import cn.com.tenlion.buildingpictures.pojo.dtos.picturestemplate.PicturesTemplateDTO;
import cn.com.tenlion.buildingpictures.pojo.dtos.picturestemplatearea.PicturesTemplateAreaDTO;
import cn.com.tenlion.buildingpictures.pojo.vos.picturestemplate.PicturesTemplateContentVO;
import cn.com.tenlion.buildingpictures.pojo.vos.picturestemplate.PicturesTemplateVO;
import cn.com.tenlion.buildingpictures.service.picturestemplate.IPicturesTemplateService;
import cn.com.tenlion.buildingpictures.service.picturestemplatearea.IPicturesTemplateAreaService;
import cn.com.tenlion.buildingpictures.service.picturestemplatebuilding.IPicturesTemplateBuildingService;
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.module.dictionary.service.IDataService;
import ink.wgink.module.file.service.IFileService;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.pos.FilePO;
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.date.DateUtil;
import ink.wgink.util.map.HashMapUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: PicturesTemplateServiceImpl
 * @Description: 图片套版的模板管理
 * @Author: WenG
 * @Date: 2020-10-20 10:49
 * @Version: 1.0
 **/
@Primary
@Service
public class PicturesTemplateServiceImpl extends DefaultBaseService implements IPicturesTemplateService {

    @Autowired
    private IPicturesTemplateDao picturesTemplateDao;

    @Autowired
    private IPicturesTemplateAreaDao picturesTemplateAreaDao;

    @Autowired
    private IPicturesTemplateAreaService iPicturesTemplateAreaService;

    @Autowired
    private IPicturesTemplateBuildingService iPicturesTemplateBuildingService;

    @Autowired
    private IFileService iFileService;

    @Autowired
    private IDataService dataDictionaryServiceImpl;

    @Override
    public SuccessResult savePicturesTemplate(PicturesTemplateVO picturesTemplateVO) throws Exception {
        savePicturesTemplateInfo(null, picturesTemplateVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult savePicturesTemplateByToken(String token, PicturesTemplateVO picturesTemplateVO) throws Exception {
        savePicturesTemplateInfo(token, picturesTemplateVO);
        return new SuccessResult();
    }

    @Override
    public String savePicturesTemplateReturnId(PicturesTemplateVO picturesTemplateVO) throws Exception {
        return savePicturesTemplateInfoReturnId(null, picturesTemplateVO);
    }

    @Override
    public String savePicturesTemplateByTokenReturnId(String token, PicturesTemplateVO picturesTemplateVO) throws Exception {
        return savePicturesTemplateInfoReturnId(token, picturesTemplateVO);
    }

    /**
     * 新增图片套版的模板管理
     *
     * @param token
     * @param picturesTemplateVO
     * @throws Exception
     */
    private void savePicturesTemplateInfo(String token, PicturesTemplateVO picturesTemplateVO) throws Exception {
        savePicturesTemplateInfoReturnId(token, picturesTemplateVO);
    }

    /**
     * 新增图片套版的模板管理
     *
     * @param token
     * @param picturesTemplateVO
     * @return picturesTemplateId
     * @throws Exception
     */
    private String savePicturesTemplateInfoReturnId(String token, PicturesTemplateVO picturesTemplateVO) throws Exception {
        String picturesTemplateId = UUIDUtil.getUUID();
        /**
         * 判断编码是否已经存在
         */
        PicturesTemplateDTO dto = picturesTemplateDao.getPicturesTemplateByCode(picturesTemplateVO.getPicturesTemplateCode());
        if(dto != null) {
            throw new SaveException("该编码已经存在");
        }
        picturesTemplateVO.setPicturesTemplateContent("");

        Map<String, Object> query = new HashMap<String, Object>();
        query.put("fileId", picturesTemplateVO.getPicturesTemplateBackgroundImage());
        FilePO filePO = iFileService.getPO(query);
        File file = new File(filePO.getFilePath());
        BufferedImage image = ImageIO.read(file);
        picturesTemplateVO.setPicturesTemplateHeight(image.getHeight() + 0.0);
        picturesTemplateVO.setPicturesTemplateWidth(image.getWidth() + 0.0);


        // 自定义尺寸做判断
        if("-1".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            String size = picturesTemplateVO.getPicturesTemplateSize();
            if(StringUtils.isEmpty(size)) {
                throw new SaveException("自定义尺寸不能为空");
            }
            String[] arr = size.split("\\*");
            if(arr.length != 2) {
                throw new SaveException("自定义尺寸不合法");
            }
            if(!StringUtils.isNumeric(arr[0]) || !StringUtils.isNumeric(arr[1])) {
                throw new SaveException("自定义尺寸不合法");
            }
            /**
             * 判断自定义尺寸不能大于图片本身尺寸
             */
            if( image.getHeight()  < Integer.valueOf(arr[1])) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < Integer.valueOf(arr[0])) {
                throw new SaveException("自定义宽度不能大于底图");
            }
            picturesTemplateVO.setPicturesTemplateHeight(Integer.valueOf(arr[1]) + 0.0);
            picturesTemplateVO.setPicturesTemplateWidth(Integer.valueOf(arr[0]) + 0.0);
        }
        // A4尺寸(纵向)
        else if("4".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(1123.0);
            picturesTemplateVO.setPicturesTemplateWidth(794.0);
            if( image.getHeight()  < 1123.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 794.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A4尺寸(横向)
        else if("-4".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(794.0);
            picturesTemplateVO.setPicturesTemplateWidth(1123.0);
            if( image.getHeight()  < 794.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 1123.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A5尺寸(纵向)
        else if("5".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(794.0);
            picturesTemplateVO.setPicturesTemplateWidth(560.0);
            if( image.getHeight()  < 794.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 560.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A5尺寸(横向)
        else if("-5".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(560.0);
            picturesTemplateVO.setPicturesTemplateWidth(794.0);
            if( image.getHeight()  < 560.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 794.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A6尺寸(纵向)
        else if("6".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(545.0);
            picturesTemplateVO.setPicturesTemplateWidth(397.0);
            if( image.getHeight()  < 545.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 397.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A6尺寸(横向)
        else if("-6".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(397.0);
            picturesTemplateVO.setPicturesTemplateWidth(545.0);
            if( image.getHeight()  < 397.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 545.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        /**
         * 默认为不发布
         */
        picturesTemplateVO.setPicturesTemplatePublishStatus("0");
        Map<String, Object> params = HashMapUtil.beanToMap(picturesTemplateVO);
        params.put("picturesTemplateId", picturesTemplateId);
        if (StringUtils.isBlank(token)) {
            setSaveInfo(params);
        } else {
            setAppSaveInfo(token, params);
        }
        picturesTemplateDao.savePicturesTemplate(params);
        return picturesTemplateId;
    }

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

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

    /**
     * 删除图片套版的模板管理
     *
     * @param token
     * @param ids
     */
    private void removePicturesTemplateInfo(String token, String ids) {
        Map<String, Object> params = getHashMap(3);
        params.put("picturesTemplateIds", Arrays.asList(ids.split("_")));
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        picturesTemplateDao.removePicturesTemplate(params);
    }

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

    @Override
    public SuccessResult updatePicturesTemplate(String picturesTemplateId, PicturesTemplateVO picturesTemplateVO) throws Exception {
        updatePicturesTemplateInfo(null, picturesTemplateId, picturesTemplateVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updatePicturesTemplateByToken(String token, String picturesTemplateId, PicturesTemplateVO picturesTemplateVO) throws Exception {
        updatePicturesTemplateInfo(token, picturesTemplateId, picturesTemplateVO);
        return new SuccessResult();
    }

    /**
     * 修改图片套版的模板管理
     *
     * @param token
     * @param picturesTemplateId
     * @param picturesTemplateVO
     */
    private void updatePicturesTemplateInfo(String token, String picturesTemplateId, PicturesTemplateVO picturesTemplateVO) throws Exception {
        Map<String, Object> query = new HashMap<String, Object>();
        query.put("fileId", picturesTemplateVO.getPicturesTemplateBackgroundImage());
        FilePO filePO = iFileService.getPO(query);
        File file = new File(filePO.getFilePath());
        BufferedImage image = ImageIO.read(file);
        picturesTemplateVO.setPicturesTemplateHeight(image.getHeight() + 0.0);
        picturesTemplateVO.setPicturesTemplateWidth(image.getWidth() + 0.0);

        // 自定义尺寸做判断
        if("-1".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            String size = picturesTemplateVO.getPicturesTemplateSize();
            if(StringUtils.isEmpty(size)) {
                throw new SaveException("自定义尺寸不能为空");
            }
            String[] arr = size.split("\\*");
            if(arr.length != 2) {
                throw new SaveException("自定义尺寸不合法");
            }
            if(!StringUtils.isNumeric(arr[0]) || !StringUtils.isNumeric(arr[1])) {
                throw new SaveException("自定义尺寸不合法");
            }
            /**
             * 判断自定义尺寸不能大于图片本身尺寸
             */
            if( image.getHeight()  < Integer.valueOf(arr[1])) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < Integer.valueOf(arr[0])) {
                throw new SaveException("自定义宽度不能大于底图");
            }
            picturesTemplateVO.setPicturesTemplateHeight(Integer.valueOf(arr[1]) + 0.0);
            picturesTemplateVO.setPicturesTemplateWidth(Integer.valueOf(arr[0]) + 0.0);
        }
        // A4尺寸(纵向)
        else if("4".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(1123.0);
            picturesTemplateVO.setPicturesTemplateWidth(794.0);
            if( image.getHeight()  < 1123.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 794.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A4尺寸(横向)
        else if("-4".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(794.0);
            picturesTemplateVO.setPicturesTemplateWidth(1123.0);
            if( image.getHeight()  < 794.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 1123.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A5尺寸(纵向)
        else if("5".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(794.0);
            picturesTemplateVO.setPicturesTemplateWidth(560.0);
            if( image.getHeight()  < 794.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 560.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A5尺寸(横向)
        else if("-5".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(560.0);
            picturesTemplateVO.setPicturesTemplateWidth(794.0);
            if( image.getHeight()  < 560.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 794.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A6尺寸(纵向)
        else if("6".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(545.0);
            picturesTemplateVO.setPicturesTemplateWidth(397.0);
            if( image.getHeight()  < 545.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 397.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }
        // A6尺寸(横向)
        else if("-6".equals(picturesTemplateVO.getPicturesTemplateBack())) {
            picturesTemplateVO.setPicturesTemplateHeight(397.0);
            picturesTemplateVO.setPicturesTemplateWidth(545.0);
            if( image.getHeight()  < 397.0) {
                throw new SaveException("自定义高度不能大于底图");
            }
            if( image.getWidth()  < 545.0) {
                throw new SaveException("自定义宽度不能大于底图");
            }
        }

        Map<String, Object> params = HashMapUtil.beanToMap(picturesTemplateVO);
        params.put("picturesTemplateId", picturesTemplateId);
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        picturesTemplateDao.updatePicturesTemplate(params);
    }

    @Override
    public PicturesTemplateDTO getPicturesTemplateById(String picturesTemplateId) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("picturesTemplateId", picturesTemplateId);
        PicturesTemplateDTO dto = picturesTemplateDao.getPicturesTemplate(params);
        List<PicturesTemplateAreaDTO> areaList = iPicturesTemplateAreaService.getPicturesTemplateAreaByPicturesTemplateId(picturesTemplateId);
        dto.setAreaList(areaList);
        return dto;
    }

    @Override
    public List<PicturesTemplateDTO> listPicturesTemplate(Map<String, Object> params) throws SearchException {
        return picturesTemplateDao.listPicturesTemplate(params);
    }

    @Override
    public SuccessResultList<List<PicturesTemplateDTO>> listPagePicturesTemplate(ListPage page) throws SearchException {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<PicturesTemplateDTO> picturesTemplateDTOs = picturesTemplateDao.listPicturesTemplate(page.getParams());
        PageInfo<PicturesTemplateDTO> pageInfo = new PageInfo<>(picturesTemplateDTOs);
        return new SuccessResultList<>(picturesTemplateDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

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

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

    @Override
    public SuccessResult buiderPicturesTemplateByPicturesTemplateCode(String picturesTemplateCode) throws Exception {
        return new SuccessResult();
    }

    @Override
    public SuccessResult updatePicturesTemplatePublishStatus(String picturesTemplateId, Boolean picturesTemplatePublishStatus) throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(3);
        params.put("picturesTemplateId", picturesTemplateId);
        params.put("picturesTemplatePublishStatus", picturesTemplatePublishStatus ? "1" : "0");
        params.put("picturesTemplatePublishTime", DateUtil.getTime());
        setUpdateInfo(params);
        picturesTemplateDao.updatePicturesTemplatePublishStatus(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult buiderPicturesTemplateAll() throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(3);
        params.put("picturesTemplatePublishStatus", "1");
        List<PicturesTemplateDTO> dtos = listPicturesTemplate(params);
        for (PicturesTemplateDTO dto : dtos) {
            buiderPicturesTemplateByPicturesTemplateCode(dto.getPicturesTemplateCode());
        }
        return new SuccessResult();
    }

    @Override
    public SuccessResult updatePicturesTemplateContent(String picturesTemplateId, PicturesTemplateContentVO picturesTemplateContentVO) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("picturesTemplateId", picturesTemplateId);
        params.put("picturesModuleContent", picturesTemplateContentVO.getPicturesTemplateContent());
        if(StringUtils.isEmpty(picturesTemplateContentVO.getPicturesTemplateContent())) {
            throw new UpdateException("代码内容不能为空!");
        }
        setUpdateInfo(params);
        picturesTemplateDao.updatePicturesTemplateContent(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult copyPicturesTemplate(String id, String picturesTemplateCode, String picturesTemplateTitle) throws Exception {
        PicturesTemplateDTO dto = picturesTemplateDao.getPicturesTemplateByCode(picturesTemplateCode);
        if(dto != null) {
            throw new SaveException("该编码已经存在");
        }
        // 查出模板
        String picturesTemplateId = UUIDUtil.getUUID();
        // 查出区域
        PicturesTemplateDTO contentDto = getPicturesTemplateById(id);
        List<PicturesTemplateAreaDTO> areaList = contentDto.getAreaList();
        for (PicturesTemplateAreaDTO areaDTO : areaList) {
            // 新页面属性
            areaDTO.setPicturesTemplateId(picturesTemplateId);
            areaDTO.setPicturesTemplateTitle(picturesTemplateTitle);
            areaDTO.setPicturesTemplateAreaId(UUIDUtil.getUUID());
            Map<String, Object> params = HashMapUtil.beanToMap(areaDTO);
            setSaveInfo(params);
            picturesTemplateAreaDao.savePicturesTemplateArea(params);
        }
        contentDto.setPicturesTemplateCode(picturesTemplateCode);
        contentDto.setPicturesTemplateTitle(picturesTemplateTitle);
        contentDto.setPicturesTemplateId(picturesTemplateId);
        contentDto.setPicturesTemplateContent("");
        Map<String, Object> save = HashMapUtil.beanToMap(contentDto);
        setSaveInfo(save);
        picturesTemplateDao.savePicturesTemplate(save);
        return new SuccessResult();
    }

    @Override
    public PicturesTemplateDTO getPicturesTemplateByCode(String picturesTemplateCode) throws Exception {
        return picturesTemplateDao.getPicturesTemplateByCode(picturesTemplateCode);
    }

    @Override
    public SuccessResultData buiderPicturesTemplate(String picturesTemplateCode) throws Exception {
        String base64 = iPicturesTemplateBuildingService.buildingPictures(picturesTemplateCode, null);
        SuccessResultData<String> result = new  SuccessResultData<String>("");
        if(base64 != null ) {
            result.setData(base64);
            /**
             * 更新预览图
             */
            String picturesTemplatePictureUrl = iPicturesTemplateBuildingService.saveBase64ToFile(base64);
            PicturesTemplateDTO dto = picturesTemplateDao.getPicturesTemplateByCode(picturesTemplateCode);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("picturesTemplatePicture", base64);
            map.put("picturesTemplatePictureUrl", picturesTemplatePictureUrl);
            map.put("picturesTemplateId", dto.getPicturesTemplateId());
            picturesTemplateDao.updatePicturesTemplatePicture(map);
        }
        return result;
    }

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

    @Override
    public PicturesTemplateBuildingDTO get(Map<String, Object> queryParams){
        return picturesTemplateDao.get(queryParams);
    }
}