package com.example.his.api.mis.service;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.example.his.api.common.utils.MinioUtil;
import com.example.his.api.db.dao.GoodsDao;
import com.example.his.api.db.pojo.GoodsEntity;
import com.example.his.api.exception.HisException;
import com.example.his.api.req.MisGoods.GoodsImportExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

@Service("MisGoodsServiceImpl")
@Slf4j
public class GoodsService {
    @Resource
    private MinioUtil minioUtil;

    @Resource
    private GoodsDao goodsDao;

    // 体检套餐-图片上传
    public String uploadImage(MultipartFile file) {
        //生成新的文件名
        String filename = IdUtil.simpleUUID() + ".jpg";
        String path = "front/goods/" + filename;
        minioUtil.uploadImage(path, file);
        return path;
    }

    // 体检套餐-分页查询
    public PageInfo<HashMap> searchGoodsByPage(Map param) {
        PageHelper.startPage(MapUtil.getInt(param, "pageNum"), MapUtil.getInt(param, "pageSize"));
        ArrayList<HashMap> list = goodsDao.searchGoodsByPage(param);
        PageInfo<HashMap> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    // 体检套餐-查询全部
    public ArrayList<HashMap> searchGoods() {
        ArrayList<HashMap> list = goodsDao.searchGoods();
        return list;
    }

    // 体检套餐-查询id
    @Cacheable(cacheNames = "goods", key = "#id")
    public HashMap searchGoodsById(Integer id) {
        HashMap param = new HashMap();
        param.put("id", id);
        HashMap goods = goodsDao.searchGoodsById(param);
        String[] columns = {"checkup_1", "checkup_2", "checkup_3", "checkup_4", "checkup_5", "tag"};
        for (String column : columns) {
            goods.replace(column, JSONUtil.parseArray(goods.get(column)));
        }
        return goods;
    }

    // 体检套餐-新增
    @Transactional
    public int insertGoods(GoodsEntity entity) {
        //计算商品信息的MD5值
        String md5 = this.genEntityMd5(entity);
        entity.setMd5(md5);
        //保存商品记录
        int rows = goodsDao.insertGoods(entity);
        return rows;
    }

    // 体检套餐-更新
    @CacheEvict(cacheNames = "goods", key = "#entity.id")
    public int updateGoods(GoodsEntity entity) {
        //计算商品信息的MD5值
        String md5 = this.genEntityMd5(entity);
        entity.setMd5(md5);
        //保存商品记录
        int rows = goodsDao.updateGoods(entity);
        return rows;
    }

    // 体检套餐-checkup
    @CacheEvict(cacheNames = "goods", key = "#id")
    public int updateGoodsCheckup(Integer id, MultipartFile file) {

        try {
            //创建空的ArrayList用于保存从Excel文档中解析出来的数据并读取文件内容
            List<GoodsImportExcel> list = EasyExcel.read(file.getInputStream())
                    .head(GoodsImportExcel.class)
                    .sheet()
                    .doReadSync();
            if (list.size() == 0) {
                throw new HisException("文档内容无效");
            }
            //把文件存储到Minio服务器
            String path = "goods/checkup/" + id + ".xlsx";
            minioUtil.uploadExcel(path, file);

            //根据商品ID查询商品记录，然后重新计算MD5值，更新商品记录的checkup和md5字段
            GoodsEntity goods = goodsDao.searchGoodsAllById(id);
            String checkup = JSONUtil.parseArray(list).toString();
            goods.setCheckup(checkup);
            String md5 = this.genEntityMd5(goods);
            HashMap map = new HashMap();
            map.put("id", id);
            map.put("md5", md5);
            map.put("checkup", checkup);
            return goodsDao.updateGoodsCheckup(map);
        } catch (Exception e) {
            throw new HisException("处理Excel文件失败", e);
        }

    }

    // 体检套餐-上下架
    @CacheEvict(cacheNames = "goods", key = "#param.get('id')", condition = "#param.get('status') == 0")
    public int updateGoodsStatus(Map param) {
        return goodsDao.updateGoodsStatus(param);
    }

    // 体检套餐-删除
    @CacheEvict(cacheNames = "goods", key = "#param.get('ids')")
    public int deleteBatchGoods(Map param) {
        // 删除记录之前先查询商品的封面
        ArrayList<String> imageList = goodsDao.deleteGoodsImage(param);
        // 删除记录
        int rows = goodsDao.deleteBatchGoods(param);
        if (rows > 1) {
            // 删除商品对应的封面图片
            imageList.forEach(image -> {
                minioUtil.deleteFile(image);
            });
        }
        return rows;
    }

    private String genEntityMd5(GoodsEntity entity) {
        JSONObject json = JSONUtil.parseObj(entity);
        //以下内容不属于计算商品信息MD5值范畴之内
        json.remove("id");
        json.remove("partId");
        json.remove("salesVolume");
        json.remove("status");
        json.remove("md5");
        json.remove("updateTime");
        json.remove("createTime");
        String md5 = MD5.create().digestHex(json.toString()).toUpperCase();
        return md5;
    }


}
