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

import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.google.zxing.WriterException;
import com.jojubanking.boot.framework.common.enums.CommonStatusEnum;
import com.jojubanking.boot.module.system.controller.admin.childitem.vo.ChilditemPageReqVO;
import com.jojubanking.boot.module.system.controller.admin.mzdm.vo.MzdmPageReqVO;
import com.jojubanking.boot.module.system.controller.admin.mzdm.vo.MzdmRespVO;
import com.jojubanking.boot.module.system.controller.admin.order.vo.OrderExportReqVO;
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.dal.dataobject.childitem.ChilditemDO;
import com.jojubanking.boot.module.system.dal.dataobject.mzdm.MzdmDO;
import com.jojubanking.boot.module.system.dal.dataobject.order.OrderDO;
import com.jojubanking.boot.module.system.dal.dataobject.xyrw.XyrwDO;
import com.jojubanking.boot.module.system.enums.common.SexEnum;
import com.jojubanking.boot.module.system.framework.tjfiles.TjfilesProperties;
import com.jojubanking.boot.module.system.service.childitem.ChilditemService;
import com.jojubanking.boot.module.system.service.mzdm.MzdmService;
import com.jojubanking.boot.module.system.service.order.OrderService;
import com.jojubanking.boot.module.system.service.xyrw.XyrwService;
import com.jojubanking.boot.module.system.util.xytj.DateDUtil;
import com.jojubanking.boot.module.system.util.xytj.Excel2PdfUtil;
import com.jojubanking.boot.module.system.util.xytj.VeDate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;

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.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.student.vo.*;
import com.jojubanking.boot.module.system.dal.dataobject.student.StudentDO;
import com.jojubanking.boot.module.system.convert.student.StudentConvert;
import com.jojubanking.boot.module.system.service.student.StudentService;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Api(tags = "管理后台 - 学生信息")
@RestController
@RequestMapping("/system/student")
@Validated
@Slf4j
public class StudentController {
    @Resource
    private TjfilesProperties tjfilesProperties;

    @Resource
    private StudentService studentService;
    @Resource
    private XyrwService xyrwService;
    @Resource
    private ChilditemService childitemService;
    @Resource
    private OrderService orderService;

    @PostMapping("/create")
    @ApiOperation("创建学生信息")
    @PreAuthorize("@ss.hasPermission('system:student:create')")
    public CommonResult<Long> createStudent(@Valid @RequestBody StudentCreateReqVO createReqVO) {
        //获取下园批次，只取开始状态的批次
        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
        xyrwListReqVO.setBatchStatus(1);
        List<XyrwDO> listXyrw = xyrwService.getXyrwSimpleList(xyrwListReqVO);

        createReqVO.setStatus(0);
        createReqVO.setFeeflag(0);
//        createReqVO.setDeleted(false);
//        createReqVO.setCreateTime(VeDate.getNowDate());
//        createReqVO.setUpdateTime(VeDate.getNowDate());
        createReqVO.setBatchno(listXyrw.get(0).getBatchno());
        createReqVO.setBatchname(listXyrw.get(0).getBatchName());
        createReqVO.setPatid("0");

        return success(studentService.createStudent(createReqVO));
    }

    @PutMapping("/update")
    @ApiOperation("更新学生信息")
    @PreAuthorize("@ss.hasPermission('system:student:update')")
    public CommonResult<Boolean> updateStudent(@Valid @RequestBody StudentUpdateReqVO updateReqVO) {
        studentService.updateStudent(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @ApiOperation("删除学生信息")
    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
    @PreAuthorize("@ss.hasPermission('system:student:delete')")
    public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
        studentService.deleteStudent(id);
        return success(true);
    }

    @GetMapping("/get")
    @ApiOperation("获得学生信息")
    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
    @PreAuthorize("@ss.hasPermission('system:student:query')")
    public CommonResult<StudentRespVO> getStudent(@RequestParam("id") Long id) {
        StudentDO student = studentService.getStudent(id);
        return success(StudentConvert.INSTANCE.convert(student));
    }

    @GetMapping("/list")
    @ApiOperation("获得学生信息列表")
    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
    @PreAuthorize("@ss.hasPermission('system:student:query')")
    public CommonResult<List<StudentRespVO>> getStudentList(@RequestParam("ids") Collection<Long> ids) {
        List<StudentDO> list = studentService.getStudentList(ids);
        return success(StudentConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/page")
    @ApiOperation("获得学生信息分页")
    @PreAuthorize("@ss.hasPermission('system:student:query')")
    public CommonResult<PageResult<StudentRespVO>> getStudentPage(@Valid StudentPageReqVO pageVO) {
        //获取下园批次，只取开始状态的批次
        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
        xyrwListReqVO.setBatchStatus(1);
        List<XyrwDO> listXyrw = xyrwService.getXyrwSimpleList(xyrwListReqVO);

        PageResult<StudentDO> pageResult = studentService.getStudentPage(pageVO, listXyrw.get(0));
        return success(StudentConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/hispage")
    @ApiOperation("获得学生信息分页")
    @PreAuthorize("@ss.hasPermission('system:student:queryhis')")
    public CommonResult<PageResult<StudentRespVO>> getStudentHisPage(@Valid StudentPageReqVO pageVO) {
        //获取下园批次，只取开始状态的批次
        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
        xyrwListReqVO.setBatchStatus(1);
        List<XyrwDO> listXyrw = xyrwService.getXyrwSimpleList(xyrwListReqVO);

        PageResult<StudentDO> pageResult = studentService.getStudentHisPage(pageVO, listXyrw.get(0));
        return success(StudentConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/importTemplate")
    @ApiOperation("获得导入用户模板")
    public void importTemplate(HttpServletResponse response) throws IOException {

        // 手动创建导出 demo
        List<StudentExcelBaseVO> list = Arrays.asList(
                StudentExcelBaseVO.builder().name("张树杰").mobile("13857185597").className("小一班")
                        .schoolName("天使幼儿园").nationId("652829199609161401").build(),
                StudentExcelBaseVO.builder().name("张树杰").mobile("13857185597").className("小一班")
                        .schoolName("天使幼儿园").nationId("652829199609161401").build()
        );

        // 输出
        ExcelUtils.write(response, "学生导入模板.xls", "用户列表", StudentExcelBaseVO.class, list);
    }


    @GetMapping("/export-excel")
    @ApiOperation("导出学生信息 Excel")
    @PreAuthorize("@ss.hasPermission('system:student:export')")
    @OperateLog(type = EXPORT)
    public void exportStudentExcel(@Valid StudentExportReqVO exportReqVO,
              HttpServletResponse response) throws IOException, WriterException {
//        List<StudentDO> list = studentService.getStudentList(exportReqVO);
        // 导出 Excel
//        List<StudentExcelVO> datas = StudentConvert.INSTANCE.convertList02(list);
//        ExcelUtils.write(response, "学生信息.xls", "数据", StudentExcelVO.class, datas);

        //获取下园批次，只取开始状态的批次
        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
        xyrwListReqVO.setBatchStatus(1);
        List<XyrwDO> listXyrw = xyrwService.getXyrwSimpleList(xyrwListReqVO);
        String xyrwname = listXyrw.get(0).getBatchName();

        log.info("start export");
        ChilditemPageReqVO pageVO = new ChilditemPageReqVO();
        pageVO.setPageSize(60);
        //目前就一个基础项目，直接获取，节约生成时间
        Double number = 0.00;
        DecimalFormat df = new DecimalFormat("0.00");
        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());
            number += Double.parseDouble(pageResult.getList().get(j).getItemprice());
            if(j < (pageResult.getList().size() - 1))
                strBaseXX = strBaseXX.concat("、");
        }
        log.info("basexx:" + strBaseXX);

        OrderExportReqVO OrderReqVO = new OrderExportReqVO();

        exportReqVO.setBatchno(listXyrw.get(0).getBatchno());
        List<StudentDO> listmains = studentService.getStudentListForXy(exportReqVO);

        // 拼接数据
        List<StudentExcelVO> datas = StudentConvert.INSTANCE.convertList02(listmains);

        for(int i=0; i<datas.size(); i++){
            BufferedImage image = insertWords(getBarCode(datas.get(i).getNationId()), datas.get(i).getNationId());
            // 将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);


            OrderReqVO.setPatid(datas.get(i).getPatid());
            OrderReqVO.setBatchno(listXyrw.get(0).getBatchno());
            OrderReqVO.setPackageflag(0);
            OrderReqVO.setPaystatus("1");
            List<OrderDO> xytjkxResult = orderService.getOrderList(OrderReqVO);

            String strkxmx = "";
            Double kxnumber = 0.00;
            for(int k=0; k<xytjkxResult.size(); k++){
                strkxmx = strkxmx.concat(xytjkxResult.get(k).getItemname());
                kxnumber += Double.parseDouble(xytjkxResult.get(k).getItemprice());
                if(k < (xytjkxResult.size() - 1))
                    strkxmx = strkxmx.concat("、");
            }
            log.info("strkxmx:" + strkxmx);

            if(xytjkxResult.size() != 0 ){
                datas.get(i).setTjkxmx(strkxmx);
                datas.get(i).setTjkxfee(df.format(kxnumber));
            }

            OrderReqVO.setPatid(datas.get(i).getPatid());
            OrderReqVO.setBatchno(listXyrw.get(0).getBatchno());
            OrderReqVO.setPackageflag(1);
            List<OrderDO> xytjStandResult = orderService.getOrderList(OrderReqVO);
            if(xytjStandResult.size() !=0 ){
                datas.get(i).setTjpkgmx(strBaseXX);
                datas.get(i).setTjpkgfee(df.format(number/100));
            }
        }

        // 导出 Excel
        String tjpath = tjfilesProperties.getTjfilespath();

        //String filename = tjpath + DateDUtil.getCurrentDateTime() + "体检信息";
        String filename = tjpath + DateDUtil.getCurrentDateTime() + "体检信息";
        String srcFilePath = filename + ".xlsx";
        ExcelUtils.writexytj(response, xyrwname, srcFilePath, "数据", StudentExcelVO.class, datas);

        String pdfFilePath = filename + ".pdf";
        Excel2PdfUtil.excel2pdf(srcFilePath, pdfFilePath);

        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType("application/pdf;charset=UTF-8");

        // 创建缓冲输入流
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilePath));
             OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;

            // 读取并写入文件
            while ((bytesRead = bis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        }

        log.info("end export");
    }


    @PostMapping("/import")
    @ApiOperation("导入学生")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class),
            @ApiImplicitParam(name = "updateSupport", value = "是否支持更新，默认为 true", example = "true", dataTypeClass = Boolean.class)
    })
    @PreAuthorize("@ss.hasPermission('system:student:import')")
    public CommonResult<StudentImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "true") Boolean updateSupport) throws Exception {
        //获取下园批次，只取开始状态的批次
        XyrwListReqVO xyrwListReqVO = new XyrwListReqVO();
        xyrwListReqVO.setBatchStatus(1);
        List<XyrwDO> listXyrw = xyrwService.getXyrwSimpleList(xyrwListReqVO);

        List<StudentImportExcelVO> list = ExcelUtils.read(file, StudentImportExcelVO.class);
        return success(studentService.importUsers(list, updateSupport, listXyrw));
    }

}
