package com.bonus.material.basic.service.impl;

import java.io.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.bonus.common.biz.config.BackstageApplication;
import com.bonus.common.biz.config.DateTimeHelper;
import com.bonus.common.biz.config.QrCodeUtils;
import com.bonus.common.biz.domain.purchase.PurchaseDto;
import com.bonus.common.biz.enums.HttpCodeEnum;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.purchase.domain.vo.PurchaseVo;
import com.google.zxing.WriterException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bonus.material.basic.mapper.BmQrcodeInfoMapper;
import com.bonus.material.basic.domain.BmQrcodeInfo;
import com.bonus.material.basic.service.IBmQrcodeInfoService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

/**
 * 二维码管理Service业务层处理
 * 
 * @author xsheng
 * @date 2024-09-26
 */
@Service
public class BmQrcodeInfoServiceImpl implements IBmQrcodeInfoService 
{
    @Resource
    private BmQrcodeInfoMapper bmQrcodeInfoMapper;

    /**
     * 查询二维码管理
     * 
     * @param qrId 二维码管理主键
     * @return 二维码管理
     */
    @Override
    public BmQrcodeInfo selectBmQrcodeInfoByQrId(Long qrId)
    {
        return bmQrcodeInfoMapper.selectBmQrcodeInfoByQrId(qrId);
    }

    /**
     * 查询二维码管理列表
     * 
     * @param bmQrcodeInfo 二维码管理
     * @return 二维码管理
     */
    @Override
    public List<BmQrcodeInfo> selectBmQrcodeInfoList(BmQrcodeInfo bmQrcodeInfo)
    {
        return bmQrcodeInfoMapper.selectBmQrcodeInfoList(bmQrcodeInfo);
    }

    /**
     * 新增二维码管理
     * 
     * @param bmQrcodeInfo 二维码管理
     * @return 结果
     */
    @Override
    public AjaxResult insertBmQrcodeInfo(BmQrcodeInfo bmQrcodeInfo)
    {
        bmQrcodeInfo.setCreateTime(DateUtils.getNowDate());
        bmQrcodeInfo.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
        String genMonth = DateTimeHelper.getNowMonth();
        List<BmQrcodeInfo> list = bmQrcodeInfoMapper.selectByMonth(genMonth);
        BmQrcodeInfo bean = null;
        int num = 0;
        int result = 0;
        if (list != null && list.size() > 0) {
            bean = list.get(0);
            num = Integer.parseInt(bean.getQrCode().split("-")[1]);
        }
        for (int j = 1; j <= bmQrcodeInfo.getQrNum(); j++) {
            genMonth = genMonth.replace("-", "");
            String code = genMonth + "-" + String.format("%5d", num + j).replace(" ", "0");
            // 新购管理-二维码打印-新增
            String url = BackstageApplication.getUrl() + "backstage/machine/qrCodePage?qrcode=" + code;
            // // 二维码的图片格式
            String format = "jpg";
            //设置路径
            String mkdirsName = "images";
            // linux 系统路径
            String saveDirectory = "/data/imw/" + mkdirsName + "/";
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("win")) {
                //本地路径
                saveDirectory = "D://files/" + mkdirsName + "/";
            }
            // 生成二维码
            File files = new File(saveDirectory);
            if (!files.exists()) {
                files.mkdirs();
            }
            QrCodeUtils.generateQRImage(url, saveDirectory, code + ".jpg", format);
            String qrUrl = saveDirectory + code + ".jpg";
            bmQrcodeInfo.setQrCode(code);
            bmQrcodeInfo.setQrUrl(qrUrl);
            bmQrcodeInfo.setQrType("盘点");
            result += bmQrcodeInfoMapper.insertBmQrcodeInfo(bmQrcodeInfo);
        }
        if (result > 0) {
            return AjaxResult.success("二维码生成成功");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 修改二维码管理
     * 
     * @param bmQrcodeInfo 二维码管理
     * @return 结果
     */
    @Override
    public int updateBmQrcodeInfo(BmQrcodeInfo bmQrcodeInfo)
    {
        bmQrcodeInfo.setUpdateTime(DateUtils.getNowDate());
        return bmQrcodeInfoMapper.updateBmQrcodeInfo(bmQrcodeInfo);
    }

    /**
     * 批量删除二维码管理
     * 
     * @param qrIds 需要删除的二维码管理主键
     * @return 结果
     */
    @Override
    public int deleteBmQrcodeInfoByQrIds(Long[] qrIds)
    {
        return bmQrcodeInfoMapper.deleteBmQrcodeInfoByQrIds(qrIds);
    }

    /**
     * 删除二维码管理信息
     * 
     * @param qrId 二维码管理主键
     * @return 结果
     */
    @Override
    public int deleteBmQrcodeInfoByQrId(Long qrId)
    {
        return bmQrcodeInfoMapper.deleteBmQrcodeInfoByQrId(qrId);
    }

    /**
     * 下载二维码
     * @param bmQrcodeInfo
     * @param response
     */
    @Override
    public void download(BmQrcodeInfo bmQrcodeInfo, HttpServletResponse response) {
        if (bmQrcodeInfo == null || CollectionUtils.isEmpty(bmQrcodeInfo.getQrIds())) {
            throw new RuntimeException("下载二维码信息不能为空");
        }
        Set<String> addedEntries = new HashSet<>();
        try (OutputStream os = response.getOutputStream();
             ZipOutputStream zos = new ZipOutputStream(os)) {
            //二维码下载
            handlePurchaseId(addedEntries, bmQrcodeInfo, zos);
            zos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理二维码下载
     * @param addedEntries
     * @param bmQrcodeInfo
     * @param zos
     */
    private void handlePurchaseId(Set<String> addedEntries, BmQrcodeInfo bmQrcodeInfo, ZipOutputStream zos) throws IOException {
        List<BmQrcodeInfo> details = bmQrcodeInfoMapper.getDetails(bmQrcodeInfo.getQrIds());
        if (CollectionUtils.isNotEmpty(details)) {
            for (BmQrcodeInfo detail : details) {
                String typeName = detail.getTypeName();
                String typeModelName = detail.getTypeModelName();
                String path = detail.getQrUrl();
                String qrCode = detail.getQrCode();
                path = path.replace("filePath", "/data/imw");
                extractedQrCode(qrCode);
                extracted(addedEntries, zos, typeName, typeModelName, qrCode, path);
            }
        }
    }

    /**
     * 二维码生产方法抽取
     * @param qrCode
     */
    private void extractedQrCode(String qrCode) {
        // 新购管理-二维码打印-新增
        String url = BackstageApplication.getUrl() + "backstage/machine/qrCodePage?qrcode=" + qrCode;
        // // 二维码的图片格式
        String format = "jpg";
        //设置路径
        String mkdirsName = "images";
        // linux 系统路径
        String saveDirectory = "/data/imw/" + mkdirsName + "/";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            //本地路径
            saveDirectory = "D://files/" + mkdirsName + "/";
        }
        // 生成二维码
        File files = new File(saveDirectory);
        if (!files.exists()) {
            files.mkdirs();
        }
        QrCodeUtils.generateQRImage(url, saveDirectory, qrCode + ".jpg", format);
    }

    /**
     * 二维码下载方法抽取
     * @param zos
     * @param typeName
     * @param typeModelName
     * @param code
     * @param path
     * @throws IOException
     */
    private void extracted(Set<String> addedEntries, ZipOutputStream zos, String typeName, String typeModelName, String code, String path) throws IOException {
        // 判断路径是否存在
        File imageFile = new File(path);
        if (!imageFile.exists()) {
            return;
        }
        String entryName = "[" + typeName + "-" + typeModelName + "]" + code + ".jpg";
        if (addedEntries.contains(entryName)) {
            System.out.println("Duplicate entry skipped: " + entryName);
            return;
        }
        addedEntries.add(entryName);
        zos.setLevel(0);
        zos.putNextEntry(new ZipEntry(entryName));
        try (InputStream fis = new FileInputStream(imageFile)) {
            byte[] buffer = new byte[1024];
            int r;
            while ((r = fis.read(buffer)) != -1) {
                zos.write(buffer, 0, r);
            }
        }
        zos.closeEntry();
    }
}

