package org.jeecg.modules.toolSheet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.tool.entity.Tool;
import org.jeecg.modules.tool.mapper.ToolMapper;
import org.jeecg.modules.toolSheet.entity.ToolExcelDTO;
import org.jeecg.modules.toolSheet.entity.ToolSheet;
import org.jeecg.modules.toolSheet.mapper.ToolSheetMapper;
import org.jeecg.modules.toolSheet.service.IToolSheetService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Objects;

/**
 * @Description: 工器具台账
 * @Author: jeecg-boot
 * @Date:   2025-01-15
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class ToolSheetServiceImpl extends ServiceImpl<ToolSheetMapper, ToolSheet> implements IToolSheetService {
    private final ToolMapper toolMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(ToolSheet entity) {
        Tool tool = toolMapper.selectById(entity.getToolId());
        // 只有在值不相等时才更新
        if (!Objects.equals(tool.getInVirtual(), entity.getInVirtual())) {
            tool.setInVirtual(entity.getInVirtual());
            toolMapper.updateById(tool);
        }
        entity.setType(tool.getType());
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        int successCount = 0;
        int failCount = 0;

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> eentity : fileMap.entrySet()) {
            // 获取上传文件对象
            MultipartFile file = eentity.getValue();
            Workbook workbook = null;
            try (InputStream is = file.getInputStream()) {
                // 自动识别 xls/xlsx
                workbook = WorkbookFactory.create(is);
                Sheet sheet = workbook.getSheetAt(0); // 默认读第一个 sheet

                // 跳过表头（第0行）
                for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                    Row row = sheet.getRow(i);
                    if (row == null) {
                        failCount++;
                        continue;
                    }

                    try {
                        ToolExcelDTO dto = parseRow(row);
                        if (dto == null || StringUtils.isBlank(dto.getName()) || StringUtils.isBlank(dto.getModel())) {
                            failCount++;
                            continue;
                        }

                        String code = dto.getCode();
                        if (StringUtils.isNotBlank(code) && baseMapper.selectCount(new LambdaQueryWrapper<ToolSheet>().eq(ToolSheet::getCode, code)) > 0) {
                            successCount++;
                            continue;
                        }

                        // 查询 tool_id
                        Tool tool = toolMapper.selectOne(new LambdaQueryWrapper<Tool>().eq(Tool::getName, dto.getName()).eq(Tool::getModel, dto.getModel()));
                        if (tool == null) {
                            failCount++;
                            continue;
                        }


                        ToolSheet entity = new ToolSheet();
                        entity.setCode(dto.getCode());
                        entity.setNum(dto.getNum());
                        entity.setModel(dto.getModel());
                        entity.setBrand(dto.getBrand());
                        entity.setType(1);
                        entity.setInVirtual("1");
                        entity.setToolId(tool.getId());

                        super.save(entity);
                        successCount++;

                    } catch (Exception e) {
                        log.error("解析或保存第 {" + i + 1 + "} 行失败: " + e.getMessage());
                        failCount++;
                    }
                }

            } catch (Exception e) {
                log.error("Excel 文件读取异常", e);
                return Result.ok(Map.of("success", 0, "fail", -1, "message", "文件解析失败: " + e.getMessage()));
            } finally {
                if (workbook != null) {
                    try {
                        workbook.close();
                    } catch (IOException e) {
                        log.warn("关闭 workbook 失败" + e.getMessage());
                    }
                }
            }
        }

        return Result.ok(Map.of(
                "success", successCount,
                "fail", failCount
        ));
    }

    private ToolExcelDTO parseRow(Row row) {
        ToolExcelDTO dto = new ToolExcelDTO();

        // 根据你的 Excel 列顺序（从0开始）：
        // 序号|名称|工器具编号|单位|数量|规格型号|品牌|...
        // 所以：
        // 名称 → col 1
        // 工器具编号 → col 2
        // 数量 → col 4
        // 规格型号 → col 5
        // 品牌 → col 6

        Cell nameCell = row.getCell(1);
        Cell codeCell = row.getCell(2);
        Cell numCell = row.getCell(4);
        Cell modelCell = row.getCell(5);
        Cell brandCell = row.getCell(6);

        dto.setName(getCellValueAsString(nameCell));
        dto.setCode(getCellValueAsString(codeCell));
        dto.setNum(getCellValueAsInteger(numCell));
        dto.setModel(getCellValueAsString(modelCell));
        dto.setBrand(getCellValueAsString(brandCell));

        return dto;
    }

    private String getCellValueAsString(Cell cell) {
        if (cell == null) return null;
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                // 尝试判断是否为整数（如编号可能是数字但应转字符串）
                double val = cell.getNumericCellValue();
                if (val == Math.floor(val)) {
                    return String.valueOf((long) val);
                } else {
                    return String.valueOf(val);
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }

    private Integer getCellValueAsInteger(Cell cell) {
        if (cell == null) return null;
        try {
            if (cell.getCellType() == CellType.NUMERIC) {
                return (int) cell.getNumericCellValue();
            } else if (cell.getCellType() == CellType.STRING) {
                String str = cell.getStringCellValue().trim();
                return str.isEmpty() ? null : Integer.parseInt(str);
            }
        } catch (NumberFormatException e) {
            log.warn("无法解析数量字段: {}"+cell);
        }
        return null;
    }
}
