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

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.checkData.entity.MovementRecordsMaster;
import org.jeecg.modules.checkData.entity.RailInspectionEquipmentItem;
import org.jeecg.modules.checkData.entity.RailInspectionEquipmentItemDetail;
import org.jeecg.modules.checkData.mapper.MovementRecordsMasterMapper;
import org.jeecg.modules.checkData.mapper.RailInspectionEquipmentItemDetailMapper;
import org.jeecg.modules.checkData.mapper.RailInspectionEquipmentItemMapper;
import org.jeecg.modules.checkData.service.IRailInspectionEquipmentItemService;
import org.jeecg.modules.checkData.vo.RailInspectionEquipmentItemDetailVO;
import org.jeecg.modules.checkData.vo.RailInspectionEquipmentItemVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 检查数据-动静态几何尺寸数据-轨检仪静态检查数据-检查项目 服务实现类
 * </p>
 *
 * @author hkl
 * @since 2023-07-16
 */
@Service
public class RailInspectionEquipmentItemServiceImpl extends ServiceImpl<RailInspectionEquipmentItemMapper, RailInspectionEquipmentItem> implements IRailInspectionEquipmentItemService {

    @Resource
    private RailInspectionEquipmentItemDetailMapper railInspectionEquipmentItemDetailMapper;

    @Resource
    private MovementRecordsMasterMapper movementRecordsMasterMapper;


    @Override
    public List<RailInspectionEquipmentItemVO> queryList(String masterId) {
        return this.baseMapper.queryList(masterId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadFile(String masterId, MultipartFile file) {
        try {
            //读取第一个sheet页的数据
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
            //读取Excel中所有的数据，以行保存
            List<List<Object>> rowRecords = reader.read();


            List<RailInspectionEquipmentItem> items = new ArrayList<>();
            List<RailInspectionEquipmentItemDetail> itemDetails = new ArrayList<>();
            int sort = 1;
            for (int i = 0; i < rowRecords.size(); ) {
                List<Object> cols = rowRecords.get(i);


                String titleHeader = Convert.toStr(cols.get(13));
                // 检查起始里程
                BigDecimal courseStartingMileage = Convert.toBigDecimal(cols.get(3));
                // 检查终点里程
                BigDecimal courseEndMileage = Convert.toBigDecimal(cols.get(6));
                if ((ObjectUtil.isNotEmpty(titleHeader) && titleHeader.contains("股道")) && (ObjectUtil.isNotEmpty(courseStartingMileage) && ObjectUtil.isNotEmpty(courseEndMileage))) {

                    // 曲线半径
                    BigDecimal curveRadius = null;
                    if (ObjectUtil.isNotEmpty(cols.get(18).toString().trim())) {
                        curveRadius = Convert.toBigDecimal(cols.get(18).toString().trim());
                    }
                    // 超高
                    BigDecimal superHigh = null;
                    if (ObjectUtil.isNotEmpty(cols.get(22).toString().trim())) {
                        superHigh = Convert.toBigDecimal(cols.get(22).toString().trim());
                    }
                    // 顺坡率
                    BigDecimal slopeRatio = null;
                    if (ObjectUtil.isNotEmpty(cols.get(28).toString().trim())) {
                        slopeRatio = Convert.toBigDecimal(cols.get(28).toString().trim());
                    }
                    RailInspectionEquipmentItem item = new RailInspectionEquipmentItem();
                    item.setId(UUIDGenerator.generate());
                    item.setCourseStartingMileage(courseStartingMileage);
                    item.setCourseEndMileage(courseEndMileage);
                    item.setCurveRadius(curveRadius);
                    item.setSuperHigh(superHigh);
                    item.setSlopeRatio(slopeRatio);
                    item.setRailInspectionEquipmentId(masterId);
                    item.setDelFlag("0");
                    item.setSort(sort);
                    items.add(item);

                    // 读取item详情
                    int skipRow = readItemDetail(i, titleHeader, item, rowRecords, itemDetails);
                    i = i + skipRow;
                    sort++;
                } else {
                    i++;
                }
            }

            // 项目信息-先删除,再导入
            this.lambdaUpdate().eq(RailInspectionEquipmentItem::getRailInspectionEquipmentId, masterId).remove();
            LambdaQueryWrapper<RailInspectionEquipmentItemDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentId, masterId);
            railInspectionEquipmentItemDetailMapper.delete(queryWrapper);

            railInspectionEquipmentItemDetailMapper.insertBatch(itemDetails);
            this.saveBatch(items);

        } catch (IOException io) {
            throw new JeecgBootException(io);
        }
    }

    private int readItemDetail(int rows, String titleHeader, RailInspectionEquipmentItem item, List<List<Object>> rowRecords, List<RailInspectionEquipmentItemDetail> itemDetails) {
        // 解析检查项目:1行:跳过2行不解析
        List<Object> checkItems = rowRecords.get(rows + 2);
        // 解析测点:1行
        List<Object> measurePoints = rowRecords.get(rows + 3);
        // 解析轨距:1行
        List<Object> trackGauges = rowRecords.get(rows + 4);
        // 解析水平 :1行
        List<Object> levels = rowRecords.get(rows + 5);
        // 解析三角坑:1行
        List<Object> triangularPits = rowRecords.get(rows + 6);
        // 解析轨向、高低及其它 1行
        List<Object> others = rowRecords.get(rows + 7);


        int sort = 1;
        for (int i = 2; i < 32; i++) {
            // 测点:测点8和9不保留
            Integer measurePoint = Convert.toInt(measurePoints.get(i));
            if (measurePoint == 8 || measurePoint == 9) {
                continue;
            }


            RailInspectionEquipmentItemDetail itemDetail = new RailInspectionEquipmentItemDetail();
            itemDetail.setId(UUIDGenerator.generate());
            itemDetail.setRailInspectionEquipmentId(item.getRailInspectionEquipmentId());
            itemDetail.setRailInspectionEquipmentItemId(item.getId());
            // 检查项目
            String checkItem = checkItems.get(i).toString();
            itemDetail.setCheckItem(checkItem);
            // 轨距
            String trackGauge = trackGauges.get(i).toString();
            itemDetail.setTrackGauge(trackGauge);
            // 水平
            String level = levels.get(i).toString();
            itemDetail.setLevel(level);
            // 三角坑
            String triangularPit = triangularPits.get(i).toString();
            itemDetail.setTriangularPit(triangularPit);
            //解析轨向、高低及其它
            String other = others.get(i).toString();
            itemDetail.setOther(other);

            // 测点值向后偏移一个
            itemDetail.setMeasurePoint(measurePoint + 1);


            // 获取登录用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (ObjectUtil.isNotEmpty(loginUser)) {
                itemDetail.setCreateBy(loginUser.getRealname());
                itemDetail.setUpdateBy(loginUser.getRealname());
            }
            itemDetail.setInfoSort(sort++);
            itemDetail.setDelFlag("0");
            itemDetail.setCreateTime(new Date());
            itemDetail.setUpdateTime(new Date());
            itemDetails.add(itemDetail);
        }


        // 解析临修日期及内容 1行:空白不解析
        // 解析轨  距 1行:空白不解析
        // 解析水  平 1行:空白不解析
        // 解析三角坑 1行:空白不解析
        // 解析轨向、高低及其它 1行:空白不解析
        // 解析临修日期及内容 1行:空白不解析

        // 如果是股道解析首轮检查负责人1行
        int skipRow = 14;
        if (titleHeader.contains("股道")) {
            skipRow = skipRow + 1;

        }
        return skipRow;
    }

    @Override
    public List<RailInspectionEquipmentItemDetailVO> detailList(String itemId) {

        return railInspectionEquipmentItemDetailMapper.detailList(itemId);
    }

    @Override
    public void saveRecord(RailInspectionEquipmentItem record) {
        // 中心里程 = (开始里程+结束里程) / 2
        BigDecimal startMileage = record.getCourseStartingMileage();
        BigDecimal endMileage = record.getCourseEndMileage();
        BigDecimal avgMileage = endMileage.subtract(startMileage).divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP);


        // 保存item表
        record.setId(UUIDGenerator.generate());
        record.setDelFlag("0");
        this.save(record);


        // 初始化明细表
        String checkItem = "检查项目：";
        List<RailInspectionEquipmentItemDetail> itemDetails = new ArrayList<>();
        int measurePoint = 0;
        int sort = 1;
        for (int i = 2; i < 32; i++) {
            if (measurePoint == 8) {
                measurePoint++;
                continue;
            }
            if (measurePoint == 9) {
                measurePoint = 0;
                startMileage = startMileage.add(avgMileage);
                continue;
            }

            measurePoint++;
            RailInspectionEquipmentItemDetail itemDetail = new RailInspectionEquipmentItemDetail();
            itemDetail.setId(UUIDGenerator.generate());
            itemDetail.setRailInspectionEquipmentId(record.getRailInspectionEquipmentId());
            itemDetail.setRailInspectionEquipmentItemId(record.getId());
            // 检查项目
            itemDetail.setCheckItem(checkItem + startMileage.add(avgMileage));
            //轨距
            itemDetail.setTrackGauge("");
            //水平
            itemDetail.setLevel("");
            //三角坑
            itemDetail.setTriangularPit("");
            //解析轨向、高低及其它
            itemDetail.setOther("");

            // 测点
            itemDetail.setMeasurePoint(measurePoint);
            itemDetail.setInfoSort(sort++);
            itemDetails.add(itemDetail);
        }
        itemDetails.forEach(itemDetail -> {
            railInspectionEquipmentItemDetailMapper.insert(itemDetail);
        });

    }

    @Override
    public void updateRecord(RailInspectionEquipmentItem record) {

        this.lambdaUpdate().set(RailInspectionEquipmentItem::getRemark, record.getRemark()).set(RailInspectionEquipmentItem::getCourseStartingMileage, record.getCourseStartingMileage()).set(RailInspectionEquipmentItem::getCourseEndMileage, record.getCourseEndMileage()).set(RailInspectionEquipmentItem::getCurveRadius, record.getCurveRadius()).set(RailInspectionEquipmentItem::getLongExtent, record.getLongExtent()).set(RailInspectionEquipmentItem::getSlopeRatio, record.getSlopeRatio()).set(RailInspectionEquipmentItem::getSuperHigh, record.getSuperHigh()).set(RailInspectionEquipmentItem::getWiden, record.getWiden()).eq(RailInspectionEquipmentItem::getId, record.getId()).update();
        // this.updateById(record);
    }

    @Override
    public void deleteRecord(String itemId) {
        this.removeById(itemId);

        LambdaUpdateWrapper<RailInspectionEquipmentItemDetail> wrapper = Wrappers.lambdaUpdate();
        railInspectionEquipmentItemDetailMapper.delete(wrapper.eq(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentItemId, itemId));
    }
}
