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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.devchange.domain.MaDevInfoXlsx;
import com.bonus.material.devchange.mapper.MaDevInfoMapper;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.domain.vo.DevInfoVo;
import com.bonus.material.index.domain.CompanyDevToolStatisticsExport;
import com.bonus.material.index.domain.MaDevInfoXlsxExport;
import com.bonus.material.index.domain.ToolLedgerEntityExport;
import com.bonus.material.index.mapper.IndexMapper;
import com.bonus.material.index.service.IndexService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;

@Service
@Slf4j
public class IndexServiceImpl implements IndexService {
    @Resource
    private IndexMapper mapper;
    @Resource
    private MaDevInfoMapper maDevInfoMapper;

    /**
     * 数据总览
     *
     * @return
     */
    @Override
    public AjaxResult getDeviceNum() {
        try {
            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            Long userId = SecurityUtils.getLoginUser().getUserid();
            // 管理员和省公司可查看所有数据
            Map<String, Object> map = new HashMap<>();
            if (userId != null && deptId != null
                    && !userId.equals(ADMIN_ID)
                    && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {

                map = mapper.getDeviceNum(String.valueOf(deptId));
            } else {
                map = mapper.getDeviceNum(null);
            }

            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }

    }

    /**
     * 使用情况
     *
     * @return
     */
    @Override
    public AjaxResult getUseDeviceNum() {
        try {
            Map<String, Object> map = mapper.getUseDeviceNum();
            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * 实时情况
     *
     * @return
     */
    @Override
    public AjaxResult getReal() {
        try {
            List<Map<String, Object>> map = mapper.getReal();
            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @return
     */
    @Override
    public AjaxResult getDeviceByDept() {
        try {
            List<Map<String, Object>> map = mapper.getDeviceByDept();
            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @return
     */
    @Override
    public AjaxResult getMaQc() {
        try {
            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            Long userId = SecurityUtils.getLoginUser().getUserid();
            // 管理员和省公司可查看所有数据
            Map<String, Object> map = new HashMap<>();
            if (userId != null && deptId != null
                    && !userId.equals(ADMIN_ID)
                    && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {

                map = mapper.getMaQc(String.valueOf(deptId));
            } else {
                map = mapper.getMaQc(null);
            }

            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @return
     */
    @Override
    public AjaxResult getDeviceNumByMonth() {
        try {
            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            Long userId = SecurityUtils.getLoginUser().getUserid();
            // 管理员和省公司可查看所有数据
            Map<String, Object> map = new HashMap<>();
            if (userId != null && deptId != null
                    && !userId.equals(ADMIN_ID)
                    && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {

                map = mapper.getDeviceNumByMonth(String.valueOf(deptId));
            } else {
                map = mapper.getDeviceNumByMonth(null);
            }

            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @return
     */
    @Override
    public AjaxResult getApprover() {
        try {
            Long userId = SecurityUtils.getLoginUser().getUserid();
            Set<String> roles = SecurityUtils.getLoginUser().getRoles();
            // 管理员和省公司可查看所有数据
            List<Map<String, Object>> map = new ArrayList<>();
            if (userId != null
                    && !userId.equals(ADMIN_ID)) {

                map = mapper.getApprover(String.valueOf(userId), roles);
            } else {
                map = mapper.getApprover(null, null);
            }

            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @return
     */
    @Override
    public AjaxResult getShare() {
        try {
            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            Long userId = SecurityUtils.getLoginUser().getUserid();
            // 管理员和省公司可查看所有数据
            Map<String, Object> map = new HashMap<>();
            if (userId != null && deptId != null
                    && !userId.equals(ADMIN_ID)
                    && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {

                map = mapper.getShare(String.valueOf(deptId));
            } else {
                map = mapper.getShare(null);
            }

            return AjaxResult.success(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error();
        }
    }

    /**
     * @param response
     */
    @Override
    public void export(HttpServletResponse response) {
        // 1. 准备数据（省略，同前文）
        List<CompanyDevToolStatisticsExport> companyDevToolStatistics = mapper.getDeviceByDeptEX();
        List<MaDevInfoXlsxExport> maDevInfoXlsxExports = mapper.listXlsx();


        if (!maDevInfoXlsxExports.isEmpty()) {
            // 2. 收集所有主表ID（用于批量查关联属性）
            List<Integer> mainIds = maDevInfoXlsxExports.stream()
                    .map(MaDevInfoXlsxExport::getMaId) // 假设主表主键是id（Long类型，根据实际字段调整）
                    .filter(Objects::nonNull) // 过滤空ID，防止查询异常
                    .collect(Collectors.toList());

            // 3. 一次性批量查询所有关联属性（1次查询，替代原N次循环查询）
            List<DevInfoPropertyVo> allProperties = maDevInfoMapper.batchGetProperties(mainIds);

            // 4. 用Map分组关联属性：key=主表ID，value=该主表对应的所有属性（内存关联核心）
            Map<Integer, List<DevInfoPropertyVo>> propertyMap = allProperties.stream()
                    .collect(Collectors.groupingBy(DevInfoPropertyVo::getMaId)); // 按关联字段（dev_id）分组

            // 5. 批量给主表对象设置属性列表（无循环查库，纯内存操作）
            maDevInfoXlsxExports.forEach(main -> {
                // 若主表ID无对应属性，返回空集合（避免null）
                List<DevInfoPropertyVo> properties = propertyMap.getOrDefault(main.getMaId(), Collections.emptyList());
                main.setPropertyVoList(properties);
                // 自动填充 propertyName1~9 和 propertyValue1~9（适配Excel导出）
                main.fillPropertyFields();
            });
        }

        List<ToolLedgerEntityExport> toolLedgerEntityExports = mapper.listToolLedgerEntity();
        // 2. 初始化ExcelWriter
        ExcelWriter writer = ExcelUtil.getWriter();
        // 3. 写入多Sheet数据（省略）
        writer.setSheet("统计");
        writer.write(companyDevToolStatistics);

        writer.setSheet("装备信息");
        writer.write(maDevInfoXlsxExports);

        writer.setSheet("工具信息");
        writer.write(toolLedgerEntityExports);

        Workbook workbook = writer.getWorkbook();
        // 遍历Sheet，删除名称为Sheet1/Sheet0的空Sheet（Hutool默认名称）
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            String sheetName = sheet.getSheetName();
            // 判断是否为默认空Sheet（名称为Sheet1/Sheet0，且行数为0）
            if (("sheet1".equals(sheetName) || "sheet0".equals(sheetName)) && sheet.getLastRowNum() == -1) {
                workbook.removeSheetAt(i);
                break; // 只删除一个默认空Sheet，跳出循环
            }
        }
        // 4. 设置响应头（修复编码异常）
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = null;
        try {
            // 捕获UnsupportedEncodingException异常
            fileName = URLEncoder.encode("多Sheet页导出", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 5. 写入输出流并关闭
            writer.flush(response.getOutputStream(), true);
            writer.close();

        } catch (Exception e) {
            // 异常处理：使用默认名称，或抛出运行时异常
            log.error(e.getMessage());
        }

    }


}
