package com.tykj.dev.device.confirmcheck.utils;


import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckBillEntity;
import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckDetailEntity;
import com.tykj.dev.device.confirmcheck.entity.vo.CheckBillVo;
import com.tykj.dev.device.confirmcheck.entity.vo.CheckDetailVo;
import com.tykj.dev.device.confirmcheck.entity.vo.DeviceInLibVo;
import com.tykj.dev.device.confirmcheck.entity.vo.DeviceNotInLibVo;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.user.subject.dao.AreaDao;
import com.tykj.dev.device.user.subject.dao.UnitsDao;
import com.tykj.dev.device.user.subject.dao.UserDao;
import com.tykj.dev.misc.base.BeanHelper;
import com.tykj.dev.misc.exception.ApiException;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ObjTransUtil.
 *
 * @author Matrix <xhyrzldf@gmail.com>
 * @since 2020/8/17 at 8:45 下午
 */
@Component
public class ObjTransUtil {

    @Autowired
    private UserDao userRepo;

    @Autowired
    private DeviceLibraryDao deviceRepo;

    @Autowired
    private AreaDao areaRepo;

    @Autowired
    private UnitsDao unitRepo;

    public DeviceCheckBillEntity checkBillVo2Do(CheckBillVo vo) {
        ModelMapper modelMapper = BeanHelper.getUserMapper();
        DeviceCheckBillEntity billDo = modelMapper.map(vo, DeviceCheckBillEntity.class);
        billDo.setCheckStatus(0);
        //areas -> unitIds -> unitStrings
        String unitString = vo.getAreaRange().stream()
                .flatMap(id -> unitRepo.findAllByAreaId(id).stream())
                .map(units -> units.getUnitId().toString())
                .collect(Collectors.joining("x"));
        billDo.setCheckDetail(unitString);

        return billDo;
    }

    public DeviceCheckDetailEntity checkDetailVo2Do(CheckDetailVo detailVo) {
        ModelMapper modelMapper = BeanHelper.getUserMapper();
        DeviceCheckDetailEntity detailDo = modelMapper.map(detailVo, DeviceCheckDetailEntity.class);
        //将inLib与notInLib 的集合 转化为压缩字符串
        String checkDetailString = devLib2String(detailVo.getDevInLibrary(), detailVo.getDevNotInLibrary());
        detailDo.setCheckDetail(checkDetailString);

        return detailDo;
    }

    public String devLib2String(List<DeviceInLibVo> inLibrary, List<DeviceNotInLibVo> notInLibrary) {

        String inLibString = inLibrary.stream()
                .map(lib -> String.format("%d-%d", lib.getId(), lib.getProofResult()))
                .collect(Collectors.joining(","));

        String notInLibString = notInLibrary.stream()
                .map(lib -> String.format("%d-%d", lib.getId(), 3))
                .collect(Collectors.joining(","));

        //不为空则拼接
        String checkDetailString = inLibString;
        if (!CollectionUtils.isEmpty(notInLibrary)) {
            checkDetailString = checkDetailString + "," + notInLibString;
        }
        return checkDetailString;
    }


    public CheckDetailVo CheckDetailDo2Vo(DeviceCheckDetailEntity detailDo) {
        //查询人物id
        Integer checkUserAId = detailDo.getCheckUserAId();
        Integer checkUserBId = detailDo.getCheckUserBId();
        Integer userAId = detailDo.getUserAId();
        Integer userBId = detailDo.getUserBId();

        String checkUserAName = userRepo.findById(checkUserAId).orElse(null).getName();
        String checkUserBName = userRepo.findById(checkUserBId).orElse(null).getName();
        String userAName = "";
        String userBName = "";
        if (userAId != null && userAId != 0) {
            userAName = userRepo.findById(userAId).orElse(null).getName();
        }

        if (userBId != null && userBId != 0) {
            userBName = userRepo.findById(userBId).orElse(null).getName();
        }

        //解析核查详情 -> 获取id与核查结果
        List<DeviceInLibVo> inLibVoList = new ArrayList<>();
        List<DeviceNotInLibVo> notInLibVoList = new ArrayList<>();
        String checkDetail = detailDo.getCheckDetail();
        String[] detailArray = checkDetail.split(",");
        for (String detail : detailArray) {
            String[] array = detail.split("-");
            Integer deviceId = Integer.valueOf(array[0]);
            int proofResult = Integer.parseInt(array[1]);
            DeviceLibrary device = deviceRepo.findById(deviceId).orElseThrow(
                    () -> new ApiException(ResponseEntity.badRequest().body(String.format("检查到装备序号为%d的装备不在库资料中，请先执行入库操作!", deviceId))));
            //依据proofResult 判断是否是在库装备
            if (proofResult == 3) {
                // 非在库装备
                notInLibVoList.add(toCheckNotInLibVo(device));
            } else {
                // 在库装备
                inLibVoList.add(toCheckInLibVo(device, proofResult));
            }
        }
        // detailDo -> detailVo
        ModelMapper modelMapper = BeanHelper.getUserMapper();
        CheckDetailVo detailVo = modelMapper.map(detailDo, CheckDetailVo.class);
        detailVo.setCheckUserAName(checkUserAName);
        detailVo.setCheckUserBName(checkUserBName);
        detailVo.setUserAName(userAName);
        detailVo.setUserBName(userBName);
        detailVo.setDevInLibrary(inLibVoList);
        detailVo.setDevNotInLibrary(notInLibVoList);

        return detailVo;

    }

    public DeviceInLibVo toCheckInLibVo(DeviceLibrary device, int proofResult) {
        return new DeviceInLibVo(
                device.getId(),
                device.getModel(),
                device.getName(),
                device.getSeqNumber(),
                device.getProdNumber(),
                device.getRfidSurfaceId(),
                device.getRfidCardId(),
                proofResult
        );
    }

    public DeviceNotInLibVo toCheckNotInLibVo(DeviceLibrary device) {
        return new DeviceNotInLibVo(
                device.getId(),
                device.getModel(),
                device.getName(),
                device.getSeqNumber(),
                device.getProdNumber(),
                device.getRfidSurfaceId(),
                device.getRfidCardId(),
                device.getLocationUnit(),
                device.getOwnUnit(),
                device.getLifeStatus()
        );
    }
}

