package com.jojubanking.boot.module.system.controller.admin.xymain;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.jojubanking.boot.framework.common.util.collection.MapUtils;
import com.jojubanking.boot.module.system.controller.admin.childitem.vo.ChilditemPageReqVO;
import com.jojubanking.boot.module.system.controller.admin.childitem.vo.ChilditemRespVO;
import com.jojubanking.boot.module.system.controller.admin.item.vo.ItemPageReqVO;
import com.jojubanking.boot.module.system.controller.admin.item.vo.ItemRespVO;
import com.jojubanking.boot.module.system.controller.admin.student.vo.StudentPageItemRespVO;
import com.jojubanking.boot.module.system.controller.admin.user.vo.user.UserExcelVO;
import com.jojubanking.boot.module.system.controller.admin.user.vo.user.UserImportExcelVO;
import com.jojubanking.boot.module.system.controller.admin.user.vo.user.UserImportRespVO;
import com.jojubanking.boot.module.system.controller.app.xytjinfo.vo.XyrwListReqVO;
import com.jojubanking.boot.module.system.convert.item.ItemConvert;
import com.jojubanking.boot.module.system.convert.student.StudentConvert;
import com.jojubanking.boot.module.system.convert.user.UserConvert;
import com.jojubanking.boot.module.system.dal.dataobject.childitem.ChilditemDO;
import com.jojubanking.boot.module.system.dal.dataobject.dept.DeptDO;
import com.jojubanking.boot.module.system.dal.dataobject.deptxq.DeptXqDO;
import com.jojubanking.boot.module.system.dal.dataobject.item.ItemDO;
import com.jojubanking.boot.module.system.dal.dataobject.student.StudentDO;

import com.jojubanking.boot.module.system.dal.dataobject.user.AdminUserDO;
import com.jojubanking.boot.module.system.dal.dataobject.xyrw.XyrwDO;
import com.jojubanking.boot.module.system.service.childitem.ChilditemService;
import com.jojubanking.boot.module.system.service.deptxq.DeptXqService;
import com.jojubanking.boot.module.system.service.item.ItemService;

import com.jojubanking.boot.module.system.service.xyrw.XyrwService;
import com.jojubanking.boot.module.system.util.xytj.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;

import javax.imageio.ImageIO;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.*;
import java.io.IOException;
import java.util.List;

import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;

import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;

import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;

import static com.jojubanking.boot.framework.common.util.collection.CollectionUtils.convertList;
import static com.jojubanking.boot.framework.common.util.collection.CollectionUtils.convertSet;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.*;
import static com.jojubanking.boot.module.system.util.xytj.BarCodeUtils.getBarCode;
import static com.jojubanking.boot.module.system.util.xytj.BarCodeUtils.insertWords;

import com.jojubanking.boot.module.system.controller.admin.xymain.vo.*;
import com.jojubanking.boot.module.system.dal.dataobject.xymain.xyMainDO;
import com.jojubanking.boot.module.system.convert.xymain.xyMainConvert;
import com.jojubanking.boot.module.system.service.xymain.xyMainService;
import org.springframework.web.multipart.MultipartFile;

@Api(tags = "管理后台 - 体检信息")
@RestController
@RequestMapping("/system/xy-main")
@Validated
@Slf4j
public class xyMainController {

    @Resource
    private xyMainService xyMainService;
    @Resource
    private DeptXqService deptXpService;
    @Resource
    private XyrwService xyrwService;
    @Resource
    private ChilditemService childitemService;

    @PostMapping("/create")
    @ApiOperation("创建体检信息")
    @PreAuthorize("@ss.hasPermission('system:xy-main:create')")
    public CommonResult<Long> createxyMain(@Valid @RequestBody xyMainCreateReqVO createReqVO) {
        return success(xyMainService.createxyMain(createReqVO));
    }

    @PutMapping("/update")
    @ApiOperation("更新体检信息")
    @PreAuthorize("@ss.hasPermission('system:xy-main:update')")
    public CommonResult<Boolean> updatexyMain(@Valid @RequestBody xyMainUpdateReqVO updateReqVO) {
        xyMainService.updatexyMain(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @ApiOperation("删除体检信息")
    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
    @PreAuthorize("@ss.hasPermission('system:xy-main:delete')")
    public CommonResult<Boolean> deletexyMain(@RequestParam("id") Long id) {
        xyMainService.deletexyMain(id);
        return success(true);
    }

    @GetMapping("/get")
    @ApiOperation("获得体检信息")
    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
    @PreAuthorize("@ss.hasPermission('system:xy-main:query')")
    public CommonResult<xyMainRespVO> getxyMain(@RequestParam("id") Long id) {
        xyMainDO xyMain = xyMainService.getxyMain(id);
        return success(xyMainConvert.INSTANCE.convert01(xyMain));
    }

    @GetMapping("/list")
    @ApiOperation("获得体检信息列表")
    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
    @PreAuthorize("@ss.hasPermission('system:xy-main:query')")
    public CommonResult<List<xyMainRespVO>> getxyMainList(@RequestParam("ids") Collection<Long> ids) {
        List<xyMainDO> list = xyMainService.getxyMainList(ids);
        return success(xyMainConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/page")
    @ApiOperation("获得体检信息分页")
    @PreAuthorize("@ss.hasPermission('system:xy-main:query')")
    public CommonResult<PageResult<xyMainPageItemRespVO>> getxyMainPage(@Valid xyMainPageReqVO pageVO) {
//        PageResult<xyMainDO> pageResult = xyMainService.getxyMainPage(pageVO);
//        return success(xyMainConvert.INSTANCE.convertPage(pageResult));
        // 获得用户分页列表
        PageResult<xyMainDO> pageResult = xyMainService.getxyMainPage(pageVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal())); // 返回空
        }

        // 获得拼接需要的数据
        Collection<Long> deptIds = convertList(pageResult.getList(), xyMainDO::getDeptId);
        Map<Long, DeptXqDO> deptMap = deptXpService.getDeptMap(deptIds);
        // 拼接结果返回
        List<xyMainPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size());
        pageResult.getList().forEach(user -> {
            xyMainPageItemRespVO respVO = xyMainConvert.INSTANCE.convert01(user);
            respVO.setDept(xyMainConvert.INSTANCE.convert(deptMap.get(user.getDeptId())));
            userList.add(respVO);
        });
        return success(new PageResult<>(userList, pageResult.getTotal()));
    }

    @GetMapping("/export-excel")
    @ApiOperation("导出体检信息 Excel")
    @PreAuthorize("@ss.hasPermission('system:xy-main:export')")
    @OperateLog(type = EXPORT)
    public void exportxyMainExcel(@Valid xyMainExportReqVO exportReqVO,
              HttpServletResponse response) throws IOException, WriterException {

//        log.info("start export");
//        ChilditemPageReqVO pageVO = new ChilditemPageReqVO();
//        pageVO.setPageSize(60);
//        //目前就一个基础项目，直接获取，节约生成时间
//        pageVO.setPackageno("666");
//        String strBaseXX = "";
//        PageResult<ChilditemDO> pageResult = childitemService.getChilditemPage(pageVO);
//        for(int j=0; j<pageResult.getList().size(); j++){
//            strBaseXX = strBaseXX.concat(pageResult.getList().get(j).getItemname());
//            if(j < (pageResult.getList().size() - 1))
//                strBaseXX = strBaseXX.concat("、");
//        }
//        log.info("basexx:" + strBaseXX);
//
//        TJOrderPageReqVO xytjkxVO =new TJOrderPageReqVO();
//        xytjkxVO.setPageSize(60);
//
//        //获取下园批次，只取开始状态的批次
//        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
//        xyrwListReqVO.setBatchStatus(1);
//        List<XyrwDO> list = xyrwService.getXyrwSimpleList(xyrwListReqVO);
//        String xyrwname = list.get(0).getBatchName();
//
//        List<xyMainDO> listmains = xyMainService.getxyMainList(exportReqVO);
//
//        // 拼接数据
//        List<xyMainExcelVO> datas = xyMainConvert.INSTANCE.convertList02(listmains);
//
//        for(int i=0; i<datas.size(); i++){
//            BufferedImage image = insertWords(getBarCode("123456789"), "123456789");
//            // 将BufferedImage保存为ByteArrayOutputStream
//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//            ImageIO.write(image, "png", outputStream);
//
//            // 获取ByteArrayOutputStream中的字节数组
//            byte[] qrCodeBytes = outputStream.toByteArray();
//
//            datas.get(i).setTjQrcode(qrCodeBytes);
//            WriteCellData<Void> writeCellData = new WriteCellData<>();
//            datas.get(i).setWriteCellDataFile(writeCellData);
//            // 这里可以设置为 EMPTY 则代表不需要其他数据了
//            writeCellData.setType(CellDataTypeEnum.EMPTY);
//            List<ImageData> imageDataList = new ArrayList<>();
//            ImageData imageData = new ImageData();
//            imageDataList.add(imageData);
//            writeCellData.setImageDataList(imageDataList);
//            // 放入2进制图片
//            imageData.setImage(qrCodeBytes);
//            // 图片类型
//            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
//            // 上 右 下 左 需要留空
//            // 这个类似于 css 的 margin
//            // 这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
//            imageData.setTop(2);
//            imageData.setRight(2);
//            imageData.setBottom(2);
//            imageData.setLeft(2);
//
//            xytjkxVO.setOrderno(datas.get(i).getTjorderno());
//            xytjkxVO.setPackageno("0");
//            PageResult<TJOrderDO> xytjkxResult = tJOrderService.getTJOrderPage(xytjkxVO);
//
//            String strkxmx = "";
//            for(int k=0; k<xytjkxResult.getList().size(); k++){
//                strkxmx = strkxmx.concat(xytjkxResult.getList().get(k).getItemname());
//                if(k < (xytjkxResult.getList().size() - 1))
//                    strkxmx = strkxmx.concat("、");
//            }
//            log.info("strkxmx:" + strkxmx);
//
//            datas.get(i).setTjkxmx(strkxmx);
//            datas.get(i).setTjpkgmx(strBaseXX);
//        }
//
//
////        BufferedImage image = insertWords(getBarCode("123456789"), "123456789");
////        ImageIO.write(image, "jpg", new File("D://abc.jpg"));
//
//        // 导出 Excel
//        ExcelUtils.writexytj(response, xyrwname,"体检信息.xls", "数据", xyMainExcelVO.class, datas);
//        log.info("end export");

    }

    public void QRCodeGenerator() throws WriterException, IOException {
        String text = "Hello World!"; // 要编码为二维码的文本内容

        int width = 300; // 设置二维码图片的宽度
        int height = 100; // 设置二维码图片的高度
        /** 加文字 条形码 */
        int WORDHEIGHT = 75;
        String format = "png"; // 设置输出格式（这里选择PNG）

        File outputFile = new File("d:\\output.png"); // 指定输出路径及名称

        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符集编码类型
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 设置错误校正等级

        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.CODE_128, width, height, hints);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (bitMatrix.get(x, y)) {
                    image.setRGB(x, y, Color.BLACK.getRGB());
                } else {
                    image.setRGB(x, y, Color.WHITE.getRGB());
                }
            }
        }

        ImageIO.write(image, format, outputFile);

        System.out.println("已生成一维码并保存到" + outputFile.getName() + "文件中！");
    }

    @PostMapping("/import")
    @ApiOperation("导入体检信息 Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class),
            @ApiImplicitParam(name = "updateSupport", value = "是否支持更新，默认为 false", example = "true", dataTypeClass = Boolean.class)
    })
    @PreAuthorize("@ss.hasPermission('system:xy-main:import')")
    public void importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
        //return success(userService.importUsers(list, updateSupport));

        return;
    }

}
