/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.gpsboot.service.maintain.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.tofly.api.UserClent;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.system.*;
import com.tofly.gpsboot.util.WordUtil;
import com.tofly.pojo.comm.dto.AuditDto;
import com.tofly.pojo.maintain.dto.RepairorderDto;
import com.tofly.pojo.maintain.dto.RepairrecordDto;
import com.tofly.pojo.maintain.vo.RepairrecordVo;
import com.tofly.pojo.plan.dto.ReportAuditDto;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.maintain.RepairrecordMapper;
import com.tofly.gpsboot.service.comm.IFileInfoService;
import com.tofly.gpsboot.service.maintain.*;
import com.tofly.gpsboot.service.report.IReportRepairRecordServer;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.maintain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 抢维修处理记录表
 *
 * @author admin
 * @date Tue Apr 06 00:00:00 CST 2021
 */
@Service("repairrecordService")
public class RepairrecordServiceImpl extends ServiceImpl<RepairrecordMapper, Repairrecord> implements RepairrecordService {

    @Autowired
    private UserClent userClent;

    @Autowired
    private IFileInfoService iFileInfoService;

    @Value("${xrty.ftp.repairrecord}")
    private String repairRecordFilePath;

    @Autowired
    private RepairgoodsService repairgoodsService;

    @Autowired
    private IReportRepairRecordServer iReportRepairRecordServer;

    @Autowired
    private RepairorderService repairorderService;

    @Autowired
    private RepairuserService repairuserService;

    @Autowired
    private RepairtypeService repairtypeService;

    @Override
    public List<RepairrecordVo> viewConversion(List<Repairrecord> infoList) {
        List<RepairrecordVo> infoVoList = new ArrayList<>();
        infoList.forEach(dto -> {
            RepairrecordVo baseInfo = JSON.parseObject(JSON.toJSONString(dto), RepairrecordVo.class);

            baseInfo.setFlag(IsValidEnum.getCodeForValue(dto.getFlag()));
            List<Repairgoods> list = repairgoodsService.list(new QueryWrapper<Repairgoods>().lambda().eq(Repairgoods::getRecordId, baseInfo.getId()));
            if (null != list && list.size() > 0) {
                baseInfo.setRepairgoodsVoList(repairgoodsService.viewConversion(list));
            }
            if (!StringUtils.isEmpty(dto.getFileIdsOne())) {
                baseInfo.setFilePathOneList(iFileInfoService.getFilePathList(Arrays.stream(dto.getFileIdsOne().split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                        .collect(Collectors.toList())));
            }
            if (!StringUtils.isEmpty(dto.getFileIdsTow())) {
                baseInfo.setFilePathTowList(iFileInfoService.getFilePathList(Arrays.stream(dto.getFileIdsTow().split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                        .collect(Collectors.toList())));
            }
            if (!StringUtils.isEmpty(dto.getFileIdsThree())) {
                baseInfo.setFilePathThreeList(iFileInfoService.getFilePathList(Arrays.stream(dto.getFileIdsThree().split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                        .collect(Collectors.toList())));
            }
            Long repairType = dto.getRepairType();
            if(null!=repairType){
                Repairtype byId = repairtypeService.getById(repairType);
                if(null!=byId){
                    baseInfo.setRepairTypeName(WordUtil.transform(byId.getName()));
                }
            }
            baseInfo.setBore(WordUtil.transform(dto.getBore()));
            baseInfo.setNotes(WordUtil.transform(dto.getNotes()));
            baseInfo.setState(AuditSateEnum.getCodeForValue(dto.getState()));
            infoVoList.add(baseInfo);
        });
        return infoVoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savaRepairrecordInfo(List<MultipartFile> fileList, RepairrecordDto parDto) throws BusinessException {
        // 判断当前过程上报是否达到维修数量,若大于则不允许新增
        Long userPlanId = parDto.getRepairUserid();
        Long planNum = repairuserService.getById(userPlanId).getPlanNum();
        // 当前个人任务下 未失效的数据
        long count = this.list(new QueryWrapper<Repairrecord>().lambda().in(Repairrecord::getRepairUserid, userPlanId).eq(Repairrecord::getFlag, IsValidEnum.IS_VALID_YES.getCode())).size();
        if (planNum <= count) {
            throw new BusinessException(Constant.REPAIR_RECORD_ADD_ERROR_CODE, Constant.REPAIR_RECORD_ADD_ERROR);
        }
        // 根据文件id反射填充对象
        Repairrecord info = JSONObject.parseObject(JSON.toJSONString(parDto), Repairrecord.class);
        if (null != fileList && fileList.size() > 0) {
            Map<String, String> stringListMap = new HashMap<>(12);
            Map<String, List<MultipartFile>> fileMap = new HashMap<>(12);
            String key1 = "1";
            String key2 = "2";
            String key3 = "3";
            fileList.forEach(file -> {
                // 分层 前/中/后 文件名称前缀分别新增1 2 3
                String originalFilename = file.getOriginalFilename();
                String[] split = originalFilename.split(Constant.DATE_TILDE);
                String flag = split[0];
                if (key1.equals(flag)) {
                    disposeFile(fileMap, key1, file);
                } else if (key2.equals(flag)) {
                    disposeFile(fileMap, key2, file);
                } else {
                    disposeFile(fileMap, key3, file);
                }

            });
            fileMap.forEach((k, v) -> {
                StringBuilder builder = iFileInfoService.saveFileList(v, repairRecordFilePath, FileTableEnum.TF_YWPN_RECORD_W.getTableName());
                stringListMap.put(k, builder.toString());
            });
            info.setFileIdsOne(stringListMap.get(key1));
            info.setFileIdsTow(stringListMap.get(key2));
            info.setFileIdsThree(stringListMap.get(key3));
            info.setState(AuditSateEnum.AUDIT_UNCOMMITTED.getCode());
        }

        // 对象入库
        this.save(info);
        // 在个人任务里新增设备/工地信息
        Long repairUserid = parDto.getRepairUserid();
        Repairuser repairuser = repairuserService.getById(repairUserid);
        repairuser.setRegionCode(parDto.getRegionCode());
        repairuser.setRegionName(parDto.getRegionName());
        BigDecimal overNum = repairuser.getOverNum() == null ? BigDecimal.ZERO : BigDecimal.valueOf(repairuser.getOverNum());
        // 完成+1
        repairuser.setOverNum(overNum.add(BigDecimal.ONE).longValue());
        long end = count + 1;
        Repairorder repairOrder = repairorderService.getById(repairuser.getRepairId());
        if(planNum <= end){
            // 修改用户的处理完成上报时间为现在/状态为未审核
            repairuser.setOverTime(DateTimeUtil.convertLDTToDate(LocalDateTime.now()));
            repairuser.setState(OrderStateEnum.ORDER_STATE_NOT_AUDIT.getCode());
            // 计算实际处理用时
            repairuser.setRealTime(Double.valueOf(DateTimeUtil.differHours(DateTimeUtil.fromLong2LocalDateTime(repairOrder.getStartTime().getTime()), LocalDateTime.now())));
        }
        repairuserService.updateById(repairuser);
        // 主体完成率

        repairOrder.setOverNum(repairuser.getOverNum());
        repairOrder.setPercent(BigDecimal.valueOf(repairOrder.getOverNum()).divide(BigDecimal.valueOf(repairOrder.getNum()), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).floatValue());
        repairorderService.updateById(repairOrder);
        // 新增抢维修耗材记录列表
        List<Repairgoods> goods = parDto.getGoods();
        if (null != goods && goods.size() > 0) {
            goods.forEach(g -> {
                g.setRecordId(info.getId());
                g.setRepairUserid(info.getRepairUserid());
                repairgoodsService.save(g);
            });
        }

        Long num  = repairOrder.getNum();
        // 判断当前过程上报是否为最后的维修数量提交
        if (num <= end) {
            // 自动上报
            ReportAuditDto reportAuditDto = new ReportAuditDto();
            reportAuditDto.setId(repairOrder.getId());
            reportAuditDto.setReportId(SecurityUtils.getUserId());


            // 若月份不为空则获取派发人id,否则获取创建工单用户id
            Long dispatchingId = null;
            String orderSource = repairOrder.getOrderSource();
            // 判断当前工单是否是热线工单
            if(OrderSourceEnum.ORDER_SOURCE_HOTLINE.getCode().equals(orderSource)){
                dispatchingId = parDto.getHotlineAuditUserId();
            }else {
                if (!StringUtils.isEmpty(repairOrder.getMonth())) {
                    dispatchingId = repairorderService.getDispatchingId(repairOrder.getYearId(), repairOrder.getMonth());
                } else {
                    dispatchingId = repairOrder.getCreateUser();
                }
            }


            reportAuditDto.setRepairorderDto(JSONObject.parseObject(JSON.toJSONString(repairOrder), RepairorderDto.class));
            reportAuditDto.setAuditId(dispatchingId);

            // 塞审核链
            AuditDto auditDto = new AuditDto();
            auditDto.setAuditPlanId(repairOrder.getId());
            auditDto.setAuditType(AuditTypeEnum.AUDIT_TYPE_REPAIR_RECORD.getCode());
            auditDto.setAuditLevel(0);
            auditDto.setAuditUser(dispatchingId);
            auditDto.setAuditState(AuditSateEnum.AUDIT_UNCOMMITTED.getCode());
            List<AuditDto> auditDtoList = new ArrayList<>();
            auditDtoList.add(auditDto);
            reportAuditDto.setAuditDtoList(auditDtoList);
            iReportRepairRecordServer.report(reportAuditDto);

        }


    }

    private void disposeFile(Map<String, List<MultipartFile>> fileMap, String key, MultipartFile file) {
        List<MultipartFile> multipartFiles;
        if (fileMap.containsKey(key)) {
            multipartFiles = fileMap.get(key);
        } else {
            multipartFiles = new ArrayList<>();
        }
        multipartFiles.add(file);
        fileMap.put(key, multipartFiles);
    }


}
