package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsentity.domain.FsFileDataListDo;
import com.bsentity.domain.FsFileDataListRecordDo;
import com.bsentity.domain.FsTrainingStaffDo;
import com.bsentity.domain.FsTrainingStaffRecordDo;
import com.bsentity.enums.ErrorCodeEnum;
import com.rongwei.bscommon.sys.dao.FsFileDataListRecordDao;
import com.rongwei.bscommon.sys.service.FsFileDataListRecordService;
import com.rongwei.bscommon.sys.service.FsFileDataListService;
import com.rongwei.bscommon.sys.service.FsTrainingStaffRecordService;
import com.rongwei.bscommon.sys.service.FsTrainingStaffService;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 奥克宁可——文件清单日志 服务实现类
 * </p>
 *
 * @author trj
 * @since 2023-07-17
 */
@Service
@Slf4j
public class FsFileDataListRecordServiceImpl extends ServiceImpl<FsFileDataListRecordDao, FsFileDataListRecordDo> implements FsFileDataListRecordService {

    @Autowired
    private FsFileDataListService fileDataListService;

    @Autowired
    private FsTrainingStaffService trainingStaffService;

    @Autowired
    private FsTrainingStaffRecordService trainingStaffRecordService;


    @Override
    @Transactional
    public synchronized R historyProduce(List<String> fileListIds) {
        //查询文件清单列表
        List<FsFileDataListDo> fileDataListList = new ArrayList<>(fileDataListService.listByIds(fileListIds));
        if (fileDataListList.size() == 0) {
            return R.error(ErrorCodeEnum.BT02.getMessage());
        }
        //查询培训人员清单
        List<FsTrainingStaffDo> trainingStaffList = getListByMasterId(fileListIds);
        //根据主表信息进行分组
        Map<String, List<FsTrainingStaffDo>> masterIdByTraining = trainingStaffList.stream()
                .collect(Collectors.groupingBy(FsTrainingStaffDo::getMasterid));
        //存文件清单记录列表集合
        List<FsFileDataListRecordDo> fileDataListRecordList = new ArrayList<>();
        //存培训人员清单列表集合
        List<FsTrainingStaffRecordDo> trainingStaffRecordList = new ArrayList<>();
        //循环文件清单
        for (FsFileDataListDo fileDataList : fileDataListList) {
            //创建文件清单日志
            FsFileDataListRecordDo fileDataListRecord = new FsFileDataListRecordDo();
            //复制人员清单日志
            BeanUtils.copyProperties(fileDataList, fileDataListRecord);
            //创建UUID
            String uuid = SecurityUtil.getUUID();
            //为当前文件订单更改主表Id和Id
            fileDataListRecord.setMasterid(fileDataList.getId())
                    .setId(uuid);
            //添加到文件清单记录列表集合
            fileDataListRecordList.add(fileDataListRecord);
            //获取当前文件下的所以培训人员
            List<FsTrainingStaffDo> fsTrainingStaffDos = masterIdByTraining.getOrDefault(fileDataList.getId(), new ArrayList<>());
            //判断是否未空
            if (fsTrainingStaffDos.size() == 0) {
                //为空结束本次循环
                continue;
            }
            //添加到培训人员清单列表集合
            trainingStaffRecordList.addAll(
                    //转移值
                    fsTrainingStaffDos.stream().map(info -> {
                        //创建培训人员日志
                        FsTrainingStaffRecordDo fsTrainingStaffRecordDo = new FsTrainingStaffRecordDo();
                        //复制人员清单的值到人员清单日志中
                        BeanUtils.copyProperties(info, fsTrainingStaffRecordDo);
                        //修改主表Id
                        fsTrainingStaffRecordDo.setMasterid(uuid)
                                .setId(SecurityUtil.getUUID());
                        return fsTrainingStaffRecordDo;
                    }).collect(Collectors.toList())
            );

        }
        List<FsFileDataListRecordDo> fsFileDataListRecordDoToPrevious = getFsFileDataListRecordDoToPrevious(fileDataListRecordList);
        log.info("上一版本数据：{}", fsFileDataListRecordDoToPrevious);
        //保存文件清单日志
        saveBatch(fileDataListRecordList);
        //保存培训人员清单日志
        trainingStaffRecordService.saveBatch(trainingStaffRecordList);
        return R.ok(fsFileDataListRecordDoToPrevious);
    }

    @Override
    public List<String> updateTrainingByMasterId(List<String> fileListIds) {
        List<String> fileDataListRecordIds = new ArrayList<>();
        for (String id : fileListIds) {
            LambdaQueryWrapper<FsFileDataListRecordDo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(FsFileDataListRecordDo::getMasterid, id)
                    .orderByDesc(FsFileDataListRecordDo::getModifydate)
                    .last("limit 1");
            fileDataListRecordIds.add(this.getOne(queryWrapper).getId());
        }

        return fileDataListRecordIds;
    }


    public List<FsTrainingStaffDo> getListByMasterId(List<String> fileListIds) {
        LambdaQueryWrapper<FsTrainingStaffDo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(FsTrainingStaffDo::getMasterid, fileListIds);
        return trainingStaffService.list(queryWrapper);
    }

    /**
     * 前端返回给前端数据
     * @param fileDataListRecordList
     * @return
     */
    public List<FsFileDataListRecordDo> getFsFileDataListRecordDoToPrevious(List<FsFileDataListRecordDo> fileDataListRecordList) {

        LambdaQueryWrapper<FsFileDataListRecordDo> queryWrapper = new LambdaQueryWrapper<>();
        return fileDataListRecordList.stream().map(info -> {
            String serialnumber = info.getSerialnumber();
            int i = Integer.parseInt(serialnumber) - 1;
            if (i >= 0) {
                if (i > 10){
                    serialnumber = String.valueOf(i);
                }else{
                    serialnumber = "0"+i;
                }
            }
            queryWrapper.eq(FsFileDataListRecordDo::getMasterid, info.getMasterid())
                    .eq(FsFileDataListRecordDo::getSerialnumber, serialnumber)
                    .eq(FsFileDataListRecordDo::getProcessinststatus , "20")
                    .last("limit 1");
            return this.getOne(queryWrapper);

        }).filter(ObjectUtil::isNotNull).collect(Collectors.toList());
    }
}
