package com.kcim.web;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.Result;
import com.kcim.common.util.UserContext;
import com.kcim.common.util.excel.ExcelStyleUtil;
import com.kcim.common.util.excel.entity.ProductTemplateEntity;
import com.kcim.dao.model.*;
import com.kcim.dao.repository.ResponsibilityDepartmentRepository;
import com.kcim.service.*;
import com.kcim.service.impl.DepartmentServiceImpl;
import com.kcim.service.impl.ProductServiceImpl;
import com.kcim.vo.ResponsibilityDepartIdVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 相关导入导出操作
 */
@Slf4j
@Api(tags = "excel导入导出")
@RestController
@RequestMapping("excel")
public class ExcelController extends AbstractController {

    //    @Value("${file.filelocal}")
//    private String hospProfitReportUrl;
//
//    @Value("${file.serverUrl}")
//    private String serverUrl;
    private final UserService userService;

    private final DepartmentServiceImpl departmentService;

    private final ProductServiceImpl productService;

    private final AccountingService accountingService;

    private final AccountingProductService accountingProductService;

    private final ResponsibilityDepartmentRepository responsibilityDepartmentRepository ;

    private final CostShareParamService costShareParamService;

    private final CostIncomeGroupService costIncomeGroupService;

    private final CostCostingGroupService costCostingGroupService;

    private final ShareParamValueService shareParamValueService;

    private final CostCostingCollectionService costCostingCollectionService;

    private final AllocationService allocationService;

    private final CostDepartmentProfitService costDepartmentProfitService;

    private final CostShareLevelService shareLevelService;

    public ExcelController(UserService userService, DepartmentServiceImpl departmentService, ProductServiceImpl productService,
                           AccountingService accountingService, AccountingProductService accountingProductService,
                           ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CostShareParamService costShareParamService, CostIncomeGroupService costIncomeGroupService,
                           CostCostingGroupService costCostingGroupService, ShareParamValueService shareParamValueService,
                           CostCostingCollectionService costCostingCollectionService, AllocationService allocationService,
                           CostDepartmentProfitService costDepartmentProfitService, CostShareLevelService shareLevelService) {
        this.userService = userService;
        this.departmentService = departmentService;
        this.productService = productService;
        this.accountingService = accountingService;
        this.accountingProductService = accountingProductService;
        this.responsibilityDepartmentRepository = responsibilityDepartmentRepository;
        this.costShareParamService = costShareParamService;
        this.costIncomeGroupService = costIncomeGroupService;
        this.costCostingGroupService = costCostingGroupService;
        this.shareParamValueService = shareParamValueService;
        this.costCostingCollectionService = costCostingCollectionService;
        this.allocationService = allocationService;
        this.costDepartmentProfitService = costDepartmentProfitService;
        this.shareLevelService = shareLevelService;
    }

    @ApiOperation("用户导出模板设置")
    @GetMapping("/getcurrentTemplate")
    public void getImportUserTemplate(HttpServletResponse response) throws IOException {

        // TODO: 2021/7/26 暂时没有登录
        String uuid = UUID.randomUUID().toString();
        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
        FileUtil.del(FileUtil.file(url));

        ExcelWriter writer = new ExcelWriter(url);
        // 样式
        Sheet sheet = writer.getSheet();
        // 内容
        writer.merge(0, 1, 0, 4, "为了保证成功导入，请勿修改模板格式", false);
        writer.passCurrentRow();
        writer.passCurrentRow();
        writer.merge(2, 2, 0, 4, "测试医院用户导入", false);
        writer.passCurrentRow();
        writer.writeRow(Arrays.asList("院区", "姓名", "工号", "密码", "手机号码"));

        // 写入响应
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
        ServletOutputStream out = null;

        out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    @PostMapping("/importUser")
    @ApiOperation("导入用户")
    public Result importUser(@RequestParam("file") MultipartFile file) {
//        InputStream in;
//        try {
//            in = file.getInputStream();
//            ExcelReader reader = ExcelUtil.getReader(in);
//            List<List<Object>> read = reader.read();
//            log.info("最开始：read={}", read);
//            log.info("-------------------------------假装我是个分割线------------------------------------");
//            return userService.importUser(read);
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw new CostException(500, "导入失败");
//        }
        return null;
    }

    /**
     * 科室模板导出功能设置
     */
    @ApiOperation("科室导出模板设置")
    @GetMapping("/getDepartmentTemplate")
    public void getImportDepartmentTemplate(HttpServletResponse response) throws IOException {
        String uuid = UUID.randomUUID().toString();
        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
        FileUtil.del(FileUtil.file(url));

        ExcelWriter writer = new ExcelWriter(url);
        // 样式
        Sheet sheet = writer.getSheet();
        // 内容
        writer.merge(0, 1, 0, 2, "为了保证成功导入，请勿修改模板格式", false);
        writer.passCurrentRow();
        writer.passCurrentRow();
        writer.merge(2, 2, 0, 2, "医院科室批量导入", false);
        writer.passCurrentRow();
        writer.setColumnWidth(0, 20);
        writer.setColumnWidth(1, 15);
        writer.setColumnWidth(2, 15);
        writer.writeRow(Arrays.asList("院区", "科室名称", "科室代码"));

        // 写入响应
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
        ServletOutputStream out = null;

        out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 批量导入科室信息
     */
    @PostMapping("/importDepartment")
    @ApiOperation("导入科室信息")
    public Result importDepartment(@RequestParam("file") MultipartFile file) {
//        InputStream in;
//        try {
//            in = file.getInputStream();
//            ExcelReader reader = ExcelUtil.getReader(in);
//            List<List<Object>> read = reader.read();
//            log.info("最开始：read={}", read);
//            log.info("-------------------------------------------------------------------");
//            User user = getUser();
//            Long hospId = user.getHospId();
//            return departmentService.importDepartment(read, hospId);
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw new CostException(500, "导入失败");
//        }
        return null;
    }

    /**
     * 收入成本项目批量导入模板
     */
    @ApiOperation("成本项目导出模板设置")
    @GetMapping("/getImportProductTemplate")
    public Object getImportProductTemplate(HttpServletResponse response) throws IOException {
//        String uuid = UUID.randomUUID().toString();
//        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
//        FileUtil.del(FileUtil.file(url));
//
//        ExcelWriter writer = new ExcelWriter(url);
//        // 样式
//        Sheet sheet = writer.getSheet();
//        // 内容
//        writer.merge(0, 1, 0, 2, "为了保证成功导入，请勿修改模板格式", false);
//        writer.passCurrentRow();
//        writer.passCurrentRow();
//        writer.merge(2, 2, 0, 2, "医院成本收入批量导入", false);
//        writer.passCurrentRow();
//        writer.setColumnWidth(0, 20);
//        writer.setColumnWidth(1, 15);
//        writer.setColumnWidth(2, 15);
//        writer.writeRow(Arrays.asList("院区", "成本项目名", "成本项目编号"));
//
//        // 写入响应
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
//        ServletOutputStream out = null;
//
//        out = response.getOutputStream();
//        writer.flush(out, true);
//        writer.close();
//        IoUtil.close(out);

        try {
            //获取项目类别字典
            //配置excel 文件信息
            ExportParams params = new ExportParams();

            params.setTitle("说明：为了保证成功导入，请勿修改模板格式");
            //设置导出样式
            params.setStyle(ExcelStyleUtil.class);
            params.setHeaderHeight(10);

            //设置sheetName
            params.setSheetName("会计收入项目");
//            params.setHeaderColor();
//            params.setFreezeCol(2);
//            FileOutputStream outputStream = new FileOutputStream("E:\\会计收入项目导入模版.xlsx");

            Workbook workbook = ExcelExportUtil.exportExcel(params, ProductTemplateEntity.class, new ArrayList<>());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel");
            String fileName = "会计收入项目导入模版";
            response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
//                workbook.write(outputStream);
//                outputStream.close();
            workbook.close();
        } catch (FileNotFoundException e) {
            throw new CostException(e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return response.getOutputStream();
    }


    /**
     * 收入成本项目批量导入
     */
    @PostMapping("/importProduct")
    @ApiOperation("批量导入成本项目信息")
    public Result importProduct(@RequestParam("file") MultipartFile file) {
//        InputStream in;
//        try {
////            in = file.getInputStream();
////            ExcelReader reader = ExcelUtil.getReader(in);
////            List<List<Object>> read = reader.read();
////            log.info("最开始：read={}", read);
////            log.info("-------------------------------------------------------------------");
////            Long hospId = UserContext.getHospId();
////            return productService.importProduct(read, hospId);
//            return productService.importProduct(file);
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw new CostException(500, "导入失败");
//        }
        return productService.importProduct(file);

    }

    /**
     * 收入成本数据导出模板
     */
    @ApiOperation("收入数据导出模板设置")
    @GetMapping("/getImportIncomeProductAccountTemplate")
    public void getImportProductAccountTemplate(HttpServletResponse response, String token) throws IOException {
        Long hospId = UserContext.getHospId();
//        String uuid = UUID.randomUUID().toString();
//        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
//        FileUtil.del(FileUtil.file(url));

        ExcelWriter writer = new ExcelWriter();
        // 样式
        Sheet sheet = writer.getSheet();
        // 内容
        writer.merge(0, 1, 0, 16, "为了保证成功导入，请勿修改模板格式", false);
        writer.passCurrentRow();
        writer.passCurrentRow();
        writer.merge(2, 2, 0, 16, "医院收入数据批量导入", false);
        writer.passCurrentRow();
        // 冻结前四行
        writer.setFreezePane(4);
        writer.writeRow(Arrays.asList("收入项目代码", "收入项目名称", "开单科室", "开单科室代码", "执行科室", "执行科室代码", "医生编码", "开单医生",
                "病人ID", "住院号/门诊号", "患者姓名", "病人费别", "收据费别", "数量", "单位", "金额", "费用发生时间"));
        int accountType = NumberConstant.ONE;
        int column = NumberConstant.FOUR;
//        FileOutputStream outputStream = new FileOutputStream("E:\\收入数据导出模板设置.xlsx");

//        getProductByAccountType(hospId, writer, accountType, column);
        writer.setColumnWidth(0, 20);
        writer.setColumnWidth(1, 20);
        writer.setColumnWidth(2, 10);
        writer.setColumnWidth(3, 13);
        writer.setColumnWidth(4, 10);
        writer.setColumnWidth(5, 13);
        writer.setColumnWidth(6, 10);
        writer.setColumnWidth(7, 10);
        writer.setColumnWidth(8, 10);
        writer.setColumnWidth(9, 15);
        writer.setColumnWidth(10, 10);
        writer.setColumnWidth(11, 10);
        writer.setColumnWidth(12, 10);
        writer.setColumnWidth(13, 10);
        writer.setColumnWidth(14, 10);
        writer.setColumnWidth(15, 10);
        writer.setColumnWidth(16, 15);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        String fileName = "收入数据导入模板";
        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
        ServletOutputStream out = null;
        out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 成本数据导出模板
     */
    @GetMapping("/getImportCostProductAccountTemplate")
    @ApiOperation("成本数据导出模板设置")
    public void getImportCostProductAccountTemplate(HttpServletResponse response, String token) throws IOException {
        exportCostProductAccountTemplate(response);
        //        int userId = jwtUtil.getUserId(token);
//        User user = userService.getById(userId);
//        if (Objects.isNull(user)){
//            throw new CostException(500,"用户不存在");
//        }
//        Long hospId = UserContext.getHospId();
////        String uuid = UUID.randomUUID().toString();
////        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
////        FileUtil.del(FileUtil.file(url));
//        //todo 下一个改这里
//        ExcelWriter writer = new ExcelWriter();
//        // 样式s
//        // 所有科室里面对应存在责任中心对应的科室
//        List<Department> departmentLinkedList = getDepartments(hospId);
//        // 设置科室的代码集合
//        List<String> departmentCodeList = departmentLinkedList.stream().map(Department::getDepartmentCode).collect(Collectors.toList());
//        List<String> departmentNameList = departmentLinkedList.stream().map(Department::getDepartmentName).collect(Collectors.toList());
//        Sheet sheet = writer.getSheet();
//        writer.merge(0, 1, 0, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 2, "为了保证成功导入，请勿修改模板格式", false);
//        writer.passCurrentRow();
//        writer.passCurrentRow();
//        writer.merge(2, 2, 0, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 2, "医院成本数据批量导入", false);
//        writer.passCurrentRow();
//        writer.merge(3, 3, 2, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 2, "科室", false);
//        writer.passCurrentRow();
//        departmentCodeList.add(0, null);
//        departmentCodeList.add(1, null);
//        departmentCodeList.add("-1");
//        writer.writeRow(departmentCodeList);
//        departmentNameList.add(0, "成本项目代码");
//        departmentNameList.add(1, "成本项目名称");
//        departmentNameList.add("总计");
//        writer.writeRow(departmentNameList);
//        // 设置科室名称的集合
//        writer.setFreezePane(5);
//        int accountType = NumberConstant.TWO;
//        int column = NumberConstant.SIX;
//        getProductByAccountType(hospId, writer, accountType, column);
//        writer.setColumnWidth(0, 15);
//        writer.setColumnWidth(1, 15);
////        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
////        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
//        response.setCharacterEncoding("UTF-8");
//        response.setContentType("application/vnd.ms-excel");
//        String fileName = "成本数据导入模板";
//        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
//        ServletOutputStream out = null;
//        out = response.getOutputStream();
//        writer.flush(out, true);
//        writer.close();
//        IoUtil.close(out);
    }

    private void exportCostProductAccountTemplate(HttpServletResponse response) throws IOException {
//        FileOutputStream outputStream = new FileOutputStream("D:\\成本数据导入模板.xlsx");


//        List<ExcelExportEntity> colList = new ArrayList<ExcelExportEntity>();
//        colList.add(new ExcelExportEntity("成本分摊参数代码", "shareCode"));
//        colList.add(new ExcelExportEntity("成本分摊参数名称", "ShareName"));
        ExportParams params = new ExportParams("", "成本数据", ExcelType.XSSF);
        params.setTitle("医院成本数据批量导入\n" +
                "说明：为了保证成功导入，请勿修改模板格式");
        //设置导出样式
        params.setStyle(ExcelStyleUtil.class);
        params.setTitleHeight(Short.parseShort("15"));
        params.setHeaderHeight(10);
        Long hospId = UserContext.getHospId();
        List<Department> departmentLinkedList = getDepartments(hospId);
        // 设置科室的代码集合
//        List<CostShareParam> costShareParamList = costShareParamService.list(new QueryWrapper<CostShareParam>().lambda().eq(CostShareParam::getHospId, hospId));

        List<Product> products = getProducts(hospId, NumberConstant.TWO);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Product product : products) {
            Map<String, Object> map = new HashMap<>();
            map.put("productCode",product.getProductCode());
            map.put("productName",product.getProductName());
            map.put("department","科室");
            list.add(map);
        }
        ExcelExportEntity productCode = new ExcelExportEntity("成本项目代码", "productCode");
        ExcelExportEntity productName = new ExcelExportEntity("成本项目名称", "productName");
        List<ExcelExportEntity> exportList = new ArrayList<>();
        List<ExcelExportEntity> entityList = new ArrayList<>();
        for (Department department : departmentLinkedList) {
            ExcelExportEntity a = new ExcelExportEntity(department.getDepartmentCode());
            ExcelExportEntity a1 = new ExcelExportEntity(department.getDepartmentName());
            a1.setWidth((short)15);
            a.setList(Collections.singletonList(a1));
            entityList.add(a);
        }
        //添加总计
        ExcelExportEntity a = new ExcelExportEntity("-1");
        ExcelExportEntity a1 = new ExcelExportEntity("总计");
        a.setList(Collections.singletonList(a1));
        entityList.add(a);
        exportList.add(productCode);
        exportList.add(productName);
        exportList.addAll(entityList);
        exportList.forEach(x->x.setWidth((short)15));
        Workbook workbook = ExcelExportUtil.exportExcel(params,exportList, list);
        //设置sheetName
//        Sheet sheet = workbook.getSheetAt(0);
//        setSizeColumn(sheet);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        String fileName = "成本数据导入模板";
        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
//        ServletOutputStream outputStream = null;
//        outputStream = response.getOutputStream();
        workbook.write(response.getOutputStream());

//        outputStream.close();
//        workbook.write(outputStream);

        workbook.close();

    }

    //    /**
//     * 测试模板数据导出
//     */
//    @ApiOperation("分摊报表输出")
//    @GetMapping("/getShareReportTemplateTwo")
//    public void getShareReportTemplateTwo(HttpServletResponse response,Integer shareNumber,String token) throws IOException {
//        int userId = jwtUtil.getUserId(token);
//        User user = userService.getById(userId);
//        if (Objects.isNull(user)){
//            throw new CostException(500,"用户不存在");
//        }
//        Long hospId = user.getHospId();
//        String uuid = UUID.randomUUID().toString();
//        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
//        FileUtil.del(FileUtil.file(url));
//        ExcelWriter writer = new ExcelWriter(url);
//        Sheet sheet = writer.getSheet();
//        // 第几次分摊
//        writer= costCostingCollectionService.getShareReportTemplate(writer,shareNumber,sheet);
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
//        ServletOutputStream out = null;
//        out = response.getOutputStream();
//        writer.flush(out, true);
//        writer.close();
//        IoUtil.close(out);
//
//    }
    @ApiOperation("分摊报表输出2.0")
    @GetMapping("/getTemplate")
    public void getTemplate(HttpServletResponse response, Integer levelSort, String token, Integer year, Integer month, Long shareLevelId) throws IOException {
//        int userId = jwtUtil.getUserId(token);
//        User user = userService.getById(userId);
//        if (Objects.isNull(user)){
//            throw new CostException(500,"用户不存在");
//        }
        Long hospId = UserContext.getHospId();
//        String uuid = UUID.randomUUID().toString();
//        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
//        FileUtil.del(FileUtil.file(url));
        ExcelWriter writer = new ExcelWriter();
        Sheet sheet = writer.getSheet();

        CostShareLevel service = shareLevelService.getById(shareLevelId);        // 第几次分摊
        writer = allocationService.getShareReportTemplate(writer, levelSort, sheet, year, month, shareLevelId);
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        String fileName = service.getShareName() + "分摊";
        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
        ServletOutputStream out = null;
        out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

    }

    @ApiOperation("分摊报表输出")
    @GetMapping("/getShareReportTemplate")
    public void getShareReportTemplate(HttpServletResponse response, Integer levelSort, Integer year, Integer month, Long shareLevelId) throws IOException {

        ExcelWriter writer =ExcelUtil.getWriter(true);
        Sheet sheet = writer.getSheet();
        CostShareLevel service = shareLevelService.getById(shareLevelId);        // 第几次分摊
        writer = allocationService.getShareReportTemplate(writer, levelSort, sheet, year, month, shareLevelId);

        String fileName = service.getShareName() + "分摊.xlsx";
        String headerKey = "Content-Disposition";
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
        // 设置响应头
        response.setCharacterEncoding("UTF-8");
        //设置文件格式为.xlsx
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader(headerKey, encodedFileName);

        // 获取响应的输出流
        ServletOutputStream out = response.getOutputStream();

        // 将Excel内容写入响应的输出流中
        writer.flush(out, true);

        // 关闭ExcelWriter和输出流
        writer.close();
        out.close();
    }

    /**
     * 获取执行类型的成本项目
     *
     * @param hospId      医院Id
     * @param writer      操作流
     * @param accountType 会计科目类型 1 收入  2支出(成本)
     * @param column      控制第几列
     */
    private void getProductByAccountType(Long hospId, ExcelWriter writer, Integer accountType, Integer column) {
        List<Product> products = getProducts(hospId, accountType);
        // 写入响应第二列 第三列的数据
        for (int j = 0; j < products.size(); j++) {
            writer.writeCellValue(0, j + column, products.get(j).getProductCode());
            writer.writeCellValue(1, j + column, products.get(j).getProductName());
        }
    }

    private List<Product> getProducts(Long hospId, Integer accountType) {
        // 所有的成本项目
        List<Product> productList = productService.list(new QueryWrapper<Product>().lambda().eq(Product::getHospId, hospId));
        // 所有成本会计对照数据
        List<AccountingProduct> accountingProductList = accountingProductService.list(new QueryWrapper<AccountingProduct>().lambda().eq(AccountingProduct::getHospId, hospId));
        // 所有会计科目列表数据
        List<Accounting> accountingList = accountingService.list(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId));
        List<Product> products = new ArrayList<>();
        Map<Long, List<AccountingProduct>> accountProductMap = accountingProductList.stream().collect(Collectors.groupingBy(AccountingProduct::getProductId));
        Map<Long, List<Accounting>> accountMap = accountingList.stream().collect(Collectors.groupingBy(Accounting::getId));
        productList.forEach(i -> {
            Long productId = i.getId();
            List<AccountingProduct> accountingProducts = accountProductMap.get(productId);
            if (CollUtil.isNotEmpty(accountingProducts)) {
                Long accountingId = accountingProducts.get(0).getAccountingId();
                List<Accounting> accountings = accountMap.get(accountingId);
                if (CollUtil.isNotEmpty(accountings) && accountType.equals(accountings.get(0).getAccountingType())) {
                    products.add(i);
                }
            }
        });
        return products;
    }

    /**
     * 科室损益计算导出
     */
    @GetMapping("/getDepartmentProfit")
    @ApiOperation("科室损益计算导出")
    public void getDepartmentProfit(HttpServletResponse response, String token, String date) throws IOException {
//        int userId = jwtUtil.getUserId(token);
//        User user = userService.getById(userId);
//        if (Objects.isNull(user)){
//            throw new CostException(500,"用户不存在");
//        }
//        Long hospId = user.getHospId();
        String uuid = UUID.randomUUID().toString();
        String time = DateUtil.format(DateUtil.date(), "yyyy年MM月dd日HH时mm分ss秒");
        //todo:后面调整为上传到文件服务器，先启动确认环境
        String fileName = "全院损益" + time + ".xlsx";
        ExcelWriter writer = ExcelUtil.getWriter(fileName);
        Sheet sheet = writer.getSheet();
        costDepartmentProfitService.getDepartmentProfit(writer, sheet, date);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
        ServletOutputStream out = null;
        out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 成本分摊参数导出模板
     */
    @GetMapping("/getShareParamTemplate")
    @ApiOperation("成本分摊参数值导出模板")
    public void getShareParamTemplate(HttpServletResponse response, String token) throws IOException {
        export(response);
//        int userId = jwtUtil.getUserId(token);
//        User user = userService.getById(userId);
//        if (Objects.isNull(user)){
//            throw new CostException(500,"用户不存在");
//        }
//        Long hospId = UserContext.getHospId();
//        String uuid = UUID.randomUUID().toString();
//        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
//        FileUtil.del(FileUtil.file(url));
//
//        ExcelWriter writer = new ExcelWriter(url);
//
//
//
//        // 样式
//        // 所有科室里面对应存在责任中心对应的科室进行显示
//        List<Department> departmentLinkedList = getDepartments(hospId);
//        // 设置科室的代码集合
//        List<String> departmentCodeList = departmentLinkedList.stream().map(Department::getDepartmentCode).collect(Collectors.toList());
//        List<String> departmentNameList = departmentLinkedList.stream().map(Department::getDepartmentName).collect(Collectors.toList());
//        List<CostShareParam> costShareParamList = costShareParamService.list(new QueryWrapper<CostShareParam>().lambda().eq(CostShareParam::getHospId, hospId));
//        Sheet sheet = writer.getSheet();
//        writer.merge(0, 1, 0, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 1, "为了保证成功导入，请勿修改模板格式", false);
//        writer.passCurrentRow();
//        writer.passCurrentRow();
//        writer.merge(2, 2, 0, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 1, "医院成本分摊参数数据批量导入", false);
//        writer.passCurrentRow();
//        writer.merge(3, 3, 2, departmentCodeList.size() == 0 ? 3 : departmentCodeList.size() + 1, "科室", true);
//        writer.passCurrentRow();
//        departmentCodeList.add(0, null);
//        departmentCodeList.add(1, null);
//        writer.writeRow(departmentCodeList);
//        departmentNameList.add(0, "成本分摊参数代码");
//        departmentNameList.add(1, "成本分摊参数名称");
//        writer.writeRow(departmentNameList);
//        // 设置科室名称的集合
//        writer.setFreezePane(5);
//        // 为第一列和第二列设置成本分摊参数的列表数据
//
//        for (int j = 0; j < costShareParamList.size(); j++) {
//            writer.writeCellValue(0, j + 6, costShareParamList.get(j).getShareParamCode());
//            writer.writeCellValue(1, j + 6, costShareParamList.get(j).getShareParamName());
//        }
//        writer.setColumnWidth(0, 15);
//        writer.setColumnWidth(1, 22);
//
//
//        response.setCharacterEncoding("UTF-8");
//        response.setContentType("application/vnd.ms-excel");
//        String fileName = "成本分摊参数值导入模板";
//        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
//
//
//        ServletOutputStream out = null;
//        out = response.getOutputStream();
//        writer.flush(out, true);
//        writer.close();
//        IoUtil.close(out);
    }

    private void export(HttpServletResponse response) throws IOException {
//        FileOutputStream outputStream = new FileOutputStream("D:\\成本分摊参数值导入模板.xlsx");


//        List<ExcelExportEntity> colList = new ArrayList<ExcelExportEntity>();
//        colList.add(new ExcelExportEntity("成本分摊参数代码", "shareCode"));
//        colList.add(new ExcelExportEntity("成本分摊参数名称", "ShareName"));
        ExportParams params = new ExportParams("", "成本分摊参数数据", ExcelType.XSSF);
        params.setTitle("医院成本分摊参数数据批量导入\n" +
                "说明：为了保证成功导入，请勿修改模板格式");
        //设置导出样式
        params.setStyle(ExcelStyleUtil.class);
        params.setTitleHeight(Short.parseShort("15"));
        params.setHeaderHeight(10);

        Long hospId = UserContext.getHospId();
        List<Department> departmentLinkedList = getDepartments(hospId);
        // 设置科室的代码集合
        List<CostShareParam> costShareParamList = costShareParamService.list(new QueryWrapper<CostShareParam>().lambda().eq(CostShareParam::getHospId, hospId));


        List<Map<String, Object>> list = new ArrayList<>();
        for (CostShareParam costShareParam : costShareParamList) {
            Map<String, Object> map = new HashMap<>();
            map.put("shareParamCode",costShareParam.getShareParamCode());
            map.put("shareParamName",costShareParam.getShareParamName());
            map.put("department","科室");
            list.add(map);
        }

        ExcelExportEntity shareParamCode = new ExcelExportEntity("成本分摊参数代码", "shareParamCode");
        ExcelExportEntity shareParamName = new ExcelExportEntity("成本分摊参数名称", "shareParamName");
        List<ExcelExportEntity> exportList = new ArrayList<>();

        List<ExcelExportEntity> entityList = new ArrayList<>();
        for (Department department : departmentLinkedList) {
            ExcelExportEntity a = new ExcelExportEntity(department.getDepartmentCode());
            ExcelExportEntity a1 = new ExcelExportEntity(department.getDepartmentName());
            a.setList(Collections.singletonList(a1));
            entityList.add(a);
        }
        exportList.add(shareParamCode);
        exportList.add(shareParamName);
        exportList.addAll(entityList);
        Workbook workbook = ExcelExportUtil.exportExcel(params,exportList, list);
        //设置sheetName


        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        String fileName = "成本分摊参数值导入模板";
        response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
//        ServletOutputStream outputStream = null;
//        outputStream = response.getOutputStream();
        workbook.write(response.getOutputStream());
        workbook.close();
//        outputStream.close();
    }

    private List<Department> getDepartments(Long hospId) {


        List<Department> departmentLinkedList = new LinkedList<>();
        List<Department> departmentList = departmentService.getDepartments();
//        List<Department> departmentList = departmentService.list(new QueryWrapper<Department>().lambda().eq(Department::getHospId, hospId).orderByDesc(Department::getCreateTime));
        List<ResponsibilityDepartIdVO> responsibility = responsibilityDepartmentRepository.getResponsibility(hospId);
        Map<Long, List<ResponsibilityDepartIdVO>> collect = responsibility.stream().collect(Collectors.groupingBy(ResponsibilityDepartIdVO::getDepartmentId));
//        Map<Long, List<ResponsibilityDepartment>> responsibilityDepartmentMap = responsibilityDepartmentList.stream().collect(Collectors.groupingBy(ResponsibilityDepartment::getDepartmentId));
        departmentList.forEach(i -> {
            Long id = i.getId();
            if (!CollectionUtils.isEmpty(collect.get(id))) {
                // TODO 暂时先不考虑关联的责任中心是否存在
                departmentLinkedList.add(i);
            }
        });
        return departmentLinkedList;
    }

    /**
     * 导入 收入数据导入
     *
     * @param
     */
    @PostMapping("/importDataByFileType")
    @ApiOperation("收入数据导入")
    public Result importProductAccount(@RequestParam("file") MultipartFile file, Integer fileType, String dateTime) {
        if (Objects.isNull(file)) {
            throw new CostException(500, "请选择文件");
        }
        InputStream in;
        // 导入的是收入数据
        try {
            in = file.getInputStream();
            ExcelReader reader = ExcelUtil.getReader(in);
            List<List<Object>> read = reader.read();
            log.info("最开始：read={}", read);
            log.info("-------------------------------------------------------------------");
            return costIncomeGroupService.importIncomeGroup(read, file, dateTime, fileType);
        } catch (IOException e) {
            e.printStackTrace();
            ;
            throw new CostException(500, "导入失败");
        }
    }

    @PostMapping("/importCostingGroup")
    @ApiOperation("成本数据导入")

    public Result importCostingGroup(@RequestParam("file") MultipartFile file, Integer fileType, String dateTime) {
        if (Objects.isNull(file)) {
            throw new CostException(500, "请选择文件");
        }
        InputStream in;
        // 导入的是收入数据
        try {
            in = file.getInputStream();
            ExcelReader reader = ExcelUtil.getReader(in);
            List<List<Object>> read = reader.read();
            log.info("最开始：read={}", read);
            log.info("-------------------------------------------------------------------");
            return costCostingGroupService.importCostingGroup(read, file, dateTime, fileType);
        } catch (IOException e) {
            e.printStackTrace();
            ;
            throw new CostException(500, "导入失败");
        }
    }

    @PostMapping("/importShareParamGroup")
    @ApiOperation("成本分摊参数值导入")

    public Result importShareParamGroup(@RequestParam("file") MultipartFile file, Integer fileType, String dateTime) {
        if (Objects.isNull(file)) {
            throw new CostException(500, "请选择文件");
        }
        InputStream in;
        // 导入的是收入数据
        try {
            in = file.getInputStream();
            ExcelReader reader = ExcelUtil.getReader(in);
            List<List<Object>> read = reader.read();
            log.info("最开始：read={}", read);
            log.info("-------------------------------------------------------------------");
            return shareParamValueService.importShareParamGroup(read, file, dateTime, fileType);
        } catch (IOException e) {
            e.printStackTrace();
            ;
            throw new CostException(500, "导入失败");
        }
    }

    // 自适应宽度(中文支持)
    private void setSizeColumn(Sheet sheet) {
        int maxColumn = sheet.getRow(0).getPhysicalNumberOfCells();
        for(int i = 0; i < maxColumn; i++){
            sheet.autoSizeColumn(i);
        }
        for (int i = 0; i < maxColumn; i++) {
            int orgWidth = sheet.getColumnWidth(i);
            sheet.autoSizeColumn(i, true);
            int newWidth = (int) (sheet.getColumnWidth(i) + 100);
            int maxWith = 256*255;
            //限制下最大宽度
            if(newWidth > maxWith) {
                sheet.setColumnWidth(i, maxWith);
            }else if (newWidth > orgWidth) {
                sheet.setColumnWidth(i, newWidth);
            } else {
                sheet.setColumnWidth(i, orgWidth);
            }
        }
    }

}
