package com.ruoyi.gysl.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ChangeExcelUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.gysl.entity.*;
import com.ruoyi.gysl.entity.request.AuditRequest;
import com.ruoyi.gysl.entity.request.BasicInformationPageReq;
import com.ruoyi.gysl.entity.response.BasicInformationResponse;
import com.ruoyi.gysl.entity.response.ProjectBuildingExcel;
import com.ruoyi.gysl.entity.response.ProjectExcelInfo;
import com.ruoyi.gysl.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;

/**
 * 基本信息(BasicInformation)表控制层
 *
 * @author makejava
 * @since 2025-02-24 09:25:51
 */
@Api(tags = "基本信息")
@RestController
@RequestMapping("/gysl/basicInformation")
public class BasicInformationController extends BaseController {
    /**
     * 服务对象
     */
    @Resource

    /**
     * 基本信息
     */
    private BasicInformationService basicInformationService;

    /**
     * 规划信息
     */
    @Resource
    private PlanInformationService planInformationService;

    /**
     * 模型信息
     */
    @Resource
    private MxService mxService;

    /**
     * 五要素模型信息
     */
    @Resource
    private WysmxInformationService wysmxInformationService;


    /**
     * 企业入驻信息
     */
    @Resource
    private QyrzInformationService qyrzInformationService;

    /**
     * 分页查询所有数据
     *
     * @param page                    分页对象
     * @param basicInformationPageReq 查询实体
     * @return 所有数据
     */
    @ApiOperation(value = "分页查询所有数据", response = BasicInformation.class)
    @GetMapping("/page")
    public AjaxResult selectAll(Page<BasicInformation> page, BasicInformationPageReq basicInformationPageReq) {
        // 获取当前登录用户是否是企业端
        try {
            if (SecurityUtils.hasRole("company")) {
                basicInformationPageReq.setTyshxydm(SecurityUtils.getUsername());
            }
        } catch (Exception ignored) {
        }
        return success(basicInformationService.page(page, basicInformationPageReq));
    }

    /**
     * 企业端提交填报
     */
    @PreAuthorize("@ss.hasAnyRoles('company')")
    @ApiOperation(value = "企业端提交填报")
    @PostMapping("/fill")
    public AjaxResult fill(@RequestBody AuditRequest req) {
        return success(basicInformationService.audit(req,2));
    }

    /**
     * 政务端审核
     */
    @PreAuthorize("@ss.hasAnyRoles('admin,common')")
    @ApiOperation(value = "政务端审核")
    @PostMapping("/audit")
    public AjaxResult audit(@RequestBody AuditRequest req) {
        return success(basicInformationService.audit(req,3));
    }


    /**
     * 通过主键查询单条项目所有数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @ApiOperation(value = "通过主键查询单条项目所有数据",response = BasicInformationResponse.class)
    @GetMapping("/{id}")
    public AjaxResult selectOne(@PathVariable Long id) {
        return success(basicInformationService.selectOne(id));
    }


    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @ApiOperation("删除数据")
    @DeleteMapping("/delete")
    public AjaxResult delete(@RequestParam("idList") List<Long> idList) {
        //要删除其余所有表对应的数据
        basicInformationService.removeByXmIds(idList);
        return success();
    }

    /**
     * 项目基本信息批量导入
     */
    @ApiOperation(value = "项目基本信息批量导入")
//    @PreAuthorize("@ss.hasAnyRoles('admin,common')")
    @PostMapping(value = "/import", consumes = "multipart/form-data")
    public AjaxResult importTemplateProject(@RequestPart("file") MultipartFile file) throws Exception {
        ExcelUtil<BasicInformation> util = new ExcelUtil<>(BasicInformation.class);
        List<BasicInformation> proList = util.importExcel(file.getInputStream());
        StringBuilder successMsg = new StringBuilder();
        if (proList == null || proList.isEmpty()) {
            throw new ServiceException("项目导入数据不能为空");
        } else {
            basicInformationService.saveBatch(proList);
            List<Mx> list = mxService.list();
            proList.forEach(x -> {
                x.setStatus(1);
                //添加项目规划信息
                PlanInformation planInformation = new PlanInformation();
                planInformation.setXmId(x.getId());
                planInformationService.save(planInformation);
                //添加五要素模型信息
                List<WysmxInformation> wys = new ArrayList<>();
                list.forEach(y -> {
                    WysmxInformation wysmxInformation = new WysmxInformation();
                    wysmxInformation.setYsmc(y.getName());
                    wysmxInformation.setZdname(y.getName());
                    wysmxInformation.setXmId(x.getId());
                    wys.add(wysmxInformation);
                });
                wysmxInformationService.saveBatch(wys);
                //企业入驻信息
                QyrzInformation qyrzInformation = new QyrzInformation();
                qyrzInformation.setXmId(x.getId());
                qyrzInformationService.save(qyrzInformation);
                //基本信息
                String[] otherInfo = {"改造前容积率","改造后容积率","亩均税收(万元/每亩)","亩均销售(万元/每亩)","贷款情况","荣誉情况"};
                List<ProjectOtherInfo> saveOther = new ArrayList<>();
                Arrays.asList(otherInfo).forEach(y->{
                    ProjectOtherInfo projectOtherInfo = new ProjectOtherInfo();
                    projectOtherInfo.setXmId(x.getId());
                    projectOtherInfo.setZdname(y);
                    saveOther.add(projectOtherInfo);
                });
            });
            successMsg.append("导入成功");
        }
        return AjaxResult.success(successMsg);
    }

    /**
     * 动态导出基本信息
     */
    @PreAuthorize("@ss.hasAnyRoles('admin,common')")
    @ApiOperation("动态导出基本信息")
    @PostMapping("/exportInfo")
    public void exportInfo(HttpServletResponse response, @RequestParam List<Long> idList) throws NoSuchFieldException, IOException, IllegalAccessException {
        //获取对应的基本信息的列表
        List<ProjectExcelInfo> info = basicInformationService.selectList(idList);
        System.out.println(info);
        //excel 第一层单元格
        List<String> yc = new ArrayList<>();
        //excel 第二层单元格
        List<String> ec = new ArrayList<>();
        //excel 第三层单元格
        List<String> sc = new ArrayList<>();
        //项目建筑信息数据所有字段数量
        int sczdData = 0;
        //一共有几组厂房,不包括重复
        int cfsl = 0;
        //动态存储每个分组对应的字段数量
        Map<String, Integer> zdsl = new LinkedHashMap<>();
        Class<?> clazz = ProjectExcelInfo.class;
        Class<?> classBuilding = ProjectBuildingExcel.class;
        // 遍历除了建筑获取其他字段注解
        for (int i = 0; i < info.size(); i++) {
            if (i == 0) {
                for (Field field : clazz.getDeclaredFields()) {
                    Excel excelColumn = field.getAnnotation(Excel.class);
                    if (excelColumn != null) {
                        if (yc.contains(excelColumn.group())) {
                            yc.add("");
                        } else {
                            yc.add(excelColumn.group());
                        }
                        if ("id".equals(excelColumn.name())) {
                            sc.add("");
                        } else {
                            sc.add(excelColumn.name());
                        }
                        if (!Objects.equals(excelColumn.group(), "序号")) {
                            zdsl.merge(excelColumn.group(), 1, Integer::sum);
                        }
                        ec.add("");
                    }
                }
            }
            for (ProjectBuildingExcel xmjzxx : info.get(i).getXmjzxx()) {
                switch (xmjzxx.getFloor()) {
                    case 1:
                        if (!ec.contains("一层厂房")) {
                            ec.add("一层厂房");
                            cfsl += 1;
                        }
                        break;
                    case 2:
                        if (!ec.contains("双层厂房")) {
                            ec.add("双层厂房");
                            cfsl += 1;
                        }
                        break;
                    case 3:
                        if (!ec.contains("三层厂房")) {
                            ec.add("三层厂房");
                            cfsl += 1;
                        }
                        break;
                    case 4:
                        if (!ec.contains("四层厂房")) {
                            ec.add("四层厂房");
                            cfsl += 1;
                        }
                        break;
                    case 5:
                        if (!ec.contains("五层厂房")) {
                            ec.add("五层厂房");
                            cfsl += 1;
                        }
                        break;
                    default:
                        if (!ec.contains("六层及以上厂房")) {
                            ec.add("六层及以上厂房");
                            cfsl += 1;
                        }
                }
                for (Field field : classBuilding.getDeclaredFields()) {
                    Excel excelColumn = field.getAnnotation(Excel.class);
                    if (excelColumn != null) {
                        if (!yc.contains("项目建筑信息")) {
                            yc.add("项目建筑信息");
                        } else {
                            yc.add("");
                        }
                        ec.add("");
                        sc.add(excelColumn.name());
                        sczdData += 1;
                    }
                }
                ec.remove(ec.size() - 1);
            }
        }
        //=======================sheet处理
        // 第一步，创建一个Workbook，对应一个Excel文件
        XSSFWorkbook wb = new XSSFWorkbook();
        // 第二步，在Workbook中添加一个sheet,对应Excel文件中的sheet
        XSSFSheet sheet = wb.createSheet("sheet");
        // 第三步，设置样式以及字体样式
        XSSFCellStyle titleStyle = ChangeExcelUtil.createTitleCellStyle(wb);
        XSSFCellStyle headerStyle = ChangeExcelUtil.createHeadCellStyle(wb);
        XSSFCellStyle contentStyle = ChangeExcelUtil.createContentCellStyle(wb);
        // 行号
        int rowNum = 0;
        // 创建第一页的第一行，索引从0开始
        XSSFRow row0 = sheet.createRow(rowNum++);
        row0.setHeight((short) 600);// 设置行高
        sheet.setColumnWidth(1, 6000);
        sheet.setColumnWidth(2, 6000);
        //第二行
        XSSFRow row1 = sheet.createRow(rowNum++);
        row1.setHeight((short) 500);
        //第三行
        XSSFRow row2 = sheet.createRow(rowNum++);
        row2.setHeight((short) 1000);
        //合并单元格:excel,除了项目建筑信息的其余字段数量,项目建筑信息数据所有字段数量,一共有几组厂房,不包括重复
        ChangeExcelUtil.extracted(sheet, zdsl, sczdData, cfsl);

        // 创建第一行单元格
        for (int i = 0; i < yc.size(); i++) {
            XSSFCell c00 = row0.createCell(i);
            c00.setCellValue(yc.get(i));
            c00.setCellStyle(headerStyle);
        }
        // 创建第二行单元格
        for (int i = 0; i < ec.size(); i++) {
            XSSFCell tempCell = row1.createCell(i);
            tempCell.setCellValue(ec.get(i));
            tempCell.setCellStyle(headerStyle);
        }
        // 创建第三行单元格
        for (int i = 0; i < sc.size(); i++) {
            XSSFCell tempCell = row2.createCell(i);
            tempCell.setCellValue(sc.get(i));
            tempCell.setCellStyle(headerStyle);
        }
        //填充数据
        basicInformationService.approvalMethodfillInData(sheet, contentStyle, rowNum, info, sc, ec, sczdData / cfsl);

        // 1. 设置响应头（必须）
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        // 设置文件名（解决中文乱码）
        String fileName = URLEncoder.encode("项目信息.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        try (ServletOutputStream out = response.getOutputStream()) {
            // 3. 将 Workbook 写入响应流
            wb.write(out);
            out.flush();
        } finally {
            wb.close();
        }
    }


    /**
     * 模板信息
     */
    @ApiOperation("导出基本信息模板")
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<BasicInformation> util = new ExcelUtil<>(BasicInformation.class);
        util.importTemplateExcel(response, "项目数据");
    }
}

