package cn.wisenergy.service.app.impl;

import cn.wisenergy.common.constant.CommonAttributes;
import cn.wisenergy.common.utils.DateUtil;
import cn.wisenergy.common.utils.R;
import cn.wisenergy.common.utils.StringUtil;
import cn.wisenergy.mapper.AntiFakeMapper;
import cn.wisenergy.model.app.AntiFake;
import cn.wisenergy.model.dto.AntiFakeQuery;
import cn.wisenergy.model.dto.CreateCodeVo;
import cn.wisenergy.model.vo.ReportCodeVo;
import cn.wisenergy.service.Manager.AntiFakeManger;
import cn.wisenergy.service.app.AntiFakeService;
import cn.wisenergy.service.util.CodeUtils;
import cn.wisenergy.service.util.FileUtils;
import cn.wisenergy.service.util.QRCodeUtils;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 86187
 */
@Service
@Slf4j
public class AntiFakeServiceImpl extends ServiceImpl<AntiFakeMapper, AntiFake> implements AntiFakeService {

    private static final String DEST_PATH = "/opt/upload/video";

    private static final String REQUEST_URL = "http://localhost:81/shop-mall/admin/scanCode?shaValue=";
    @Autowired
    private AntiFakeMapper antiFakeMapper;

    @Autowired
    private AntiFakeManger antiFakeManger;

    @Override
    public R<Boolean> createCode(CreateCodeVo codeVo) throws ParseException {
        log.info("AntiFakeServiceImpl[]createCode[]input.param.codeVo:" + codeVo);
        if (null == codeVo || StringUtils.isBlank(codeVo.getProduceTime())) {
            return R.error("入参不能为空!");
        }

        int number;
        if (null == codeVo.getNumber()) {
            number = 1000;
        } else {
            number = codeVo.getNumber();
        }

        //获取最大批次号
        String batch = antiFakeMapper.getByBestBigNumber();
        String batchNumber = "";
        if (StringUtils.isBlank(batch)) {
            batchNumber = "10000001";
        } else {
            Integer sum = Integer.parseInt(batch) + 1;
            batchNumber = String.valueOf(sum);
        }

        int initBatchNo = 10000000;
        String realTime = DateUtil.getTime(new Date(), "yyyy-MM-dd");
        List<AntiFake> list = new ArrayList<>();

        for (int i = 0; i < number; i++) {
            int batchNo = initBatchNo + i + 1;
            AntiFake antiFake = new AntiFake();
            antiFake.setBatchNumber(batchNumber);
            antiFake.setProduceTime(realTime);

            //生成产品编码
            String productNo = CodeUtils.createProductNo(batchNumber, String.valueOf(batchNo), codeVo.getProduceTime());
            antiFake.setProductNo(productNo);
            antiFake.setStatus(0);
            antiFake.setUseStatus(0);

            String sha = DigestUtils.sha1Hex(productNo).substring(0, 16);
            antiFake.setShaValue(sha);
            antiFake.setScanNumber(0);
            antiFake.setProduceTime(codeVo.getProduceTime());
            antiFake.setCompanyAddress("東京都千代田区東神田2丁目6番7号608");
            antiFake.setCompanyName("日本西田森製薬株式会社");
            antiFake.setCompanyUrl("www.nishidamori.co.jp");
            antiFake.setLogisticsUrl("中国国际货运航空 https://www.airchinacargo.com/en/search_order.php");
            antiFake.setBrand("西田森");
            antiFake.setProductCountry(codeVo.getProductCountry());
            antiFake.setRecordNumber(codeVo.getRecordNumber());
            antiFake.setTrackingNumber(codeVo.getTrackingNumber());
            antiFake.setValidTime(codeVo.getValidTime());
            antiFake.setSpecification(codeVo.getSpecification());
            antiFake.setBrandName(codeVo.getBrandName());
            list.add(antiFake);
        }

        //批量添加二维码
        int count = antiFakeMapper.creates(list);
        if (count != list.size()) {
            return R.error("生成防伪二维码失败!");
        }
        return R.ok(0, true);
    }

    @Override
    public R<String> uploadImage() throws Exception {
        log.info("上传二维码防伪图测试");
        //生成二维码
        String url = QRCodeUtils.encode("2021-04022", DEST_PATH);
        return R.ok(url);
    }

    @Override
    public R<String> scanCode(String shaValue) {
        log.info("AntiFakeServiceImpl[]scanCode[]input.param.shaValue:" + shaValue);
        if (StringUtils.isBlank(shaValue)) {
            return R.error("入参不能为空!");
        }

        //获取二维码信息
        AntiFake antiFake = antiFakeMapper.getByShaValue(shaValue);
        if (null == antiFake) {
            return R.error("无效二维码");
        }

        if (antiFake.getStatus() == 1) {
            antiFake.setScanNumber(antiFake.getScanNumber() + 1);
            int count = antiFakeMapper.edit(antiFake);
            if (count == 0) {
                return R.error("扫描失败!");
            }
            return R.ok("防伪码号" + antiFake.getShaValue() + "的产品为非正品," +
                    "第一次扫描时间为:" + antiFake.getScanTime() + ",共扫描过" + antiFake.getScanNumber() + "池码");
        }

        antiFake.setStatus(1);
        antiFake.setScanTime(new Date());
        antiFake.setScanNumber(antiFake.getScanNumber() + 1);
        int count = antiFakeMapper.edit(antiFake);
        if (count == 0) {
            return R.error("扫描失败!");
        }
        return R.ok("防伪码号" + antiFake.getShaValue() + "的产品为正品," +
                "第一次扫描时间为:" + antiFake.getScanTime() + ",共扫描过" + antiFake.getScanNumber() + "池码");
    }

    @Override
    public R<PageInfo<AntiFake>> getList(AntiFakeQuery query) {
        log.info("AntiFakeServiceImpl[]getList[]input.param.query:" + query);
        if (null == query) {
            return R.error("入参不能为空!");
        }

        pageHandle(query);

        Map<String, Object> map = new HashMap<>(8);
        int total = antiFakeMapper.count(map);

        map.put("startNum", query.getStartNum());
        map.put("endNum", query.getEndNum());
        List<AntiFake> list = antiFakeMapper.getList(map);
        PageInfo<AntiFake> info = new PageInfo<>();
        info.setPageSize(query.getPageSize());
        info.setPageNum(query.getPageNo());
        info.setTotal(total);
        info.setList(list);
        return R.ok(info);
    }

    @Override
    public R<Boolean> report(String str, HttpServletResponse response) {
        log.info("AntiFakeServiceImpl[]report[]input.param.str:" + str);
        if (StringUtils.isBlank(str)) {
            return R.error("入参不能为空!");
        }

        //把字符转化为数字
        List<Long> array = StringUtil.strToLongArray(str);
        if (CollectionUtils.isEmpty(array)) {
            return R.ok(false);
        }

        //获取防伪二维码生产码
        List<AntiFake> result = antiFakeMapper.getProductNos(array);
        for (AntiFake anti : result) {
            String url = REQUEST_URL + anti.getShaValue();
            anti.setShaValue(url);
        }

        //生成Excel
        try {
            //  设置内容格式 以及 编码方式
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            //  使用java8新特性的stream流去处理数据，把空的数据过滤掉
            List<ReportCodeVo> resultBo = result.stream().filter(Objects::nonNull)
                    .map(t -> {
                        return ReportCodeVo.builder()
                                .shaValue(t.getShaValue())
                                .build();
                    }).collect(Collectors.toList());

            //创建文件名称
            long lon = System.currentTimeMillis();

            response.setHeader("Content-disposition", "attachment;filename=" + lon + ".xlsx");

            //  sheet名称
            EasyExcel.write(response.getOutputStream(), ReportCodeVo.class).sheet(Long.toString(lon)).doWrite(resultBo);
            //修改二维码使用状态
            boolean bool = antiFakeManger.updateAntiFake(array);
            if (!bool) {
                return R.error("更新二维码使用状态失败！");
            }
            return R.ok(0, true);
        } catch (Exception e) {
            return R.ok(1, false);
        }
    }

    /**
     * 分页处理方法
     *
     * @param schemeVo 参数
     */
    private void pageHandle(AntiFakeQuery schemeVo) {
        Integer pageNum = schemeVo.getPageNo();
        Integer pageSize = schemeVo.getPageSize();
        if (null == pageSize || pageSize == 0) {
            pageSize = 10;
        }
        if (null == pageNum || pageNum == 0) {
            pageNum = 1;
        }
        Integer endNum = pageSize;
        Integer startNum = (pageNum - CommonAttributes.NUM_ONE) * pageSize;
        schemeVo.setEndNum(endNum);
        schemeVo.setStartNum(startNum);
        schemeVo.setPageNo(pageNum);
        schemeVo.setPageSize(pageSize);
    }
}
