package com.tykj.dev.rfid.service.impl;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.rfid.entity.domin.LibraryWarningLogDetail;
import com.tykj.dev.rfid.entity.domin.LibraryWarningLog;
import com.tykj.dev.rfid.entity.vo.LibraryWarningLogSelectVo;
import com.tykj.dev.rfid.entity.vo.WarningCountVo;
import com.tykj.dev.rfid.entity.vo.WarningDetailListVo;
import com.tykj.dev.rfid.entity.vo.WarningHandleVo;
import com.tykj.dev.rfid.repository.LibraryWarningLogDao;
import com.tykj.dev.rfid.repository.LibraryWarningLogDetailDao;
import com.tykj.dev.rfid.service.LibraryWarningLogService;
import com.tykj.dev.rfid.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author dengdiyi
 */
@Service
public class LibraryWarningLogServiceImpl implements LibraryWarningLogService {

    @Autowired
    private LibraryWarningLogDao libraryWarningLogDao;

    @Resource
    UserUtils userUtils;

    @Resource
    DeviceLibraryService deviceLibraryService;

    @Autowired
    LibraryWarningLogDetailDao libraryWarningLogDetailDao;


    @Override
    public LibraryWarningLog addEntity(LibraryWarningLog libraryWarningLog) {
        return libraryWarningLogDao.save(libraryWarningLog);
    }

    @Override
    public Page<LibraryWarningLog> getPage(LibraryWarningLogSelectVo libraryWarningLogSelectVo) throws ParseException {
        Specification<LibraryWarningLog> selectSpecification = getSelectSpecification(libraryWarningLogSelectVo);
        return libraryWarningLogDao.findAll(selectSpecification,libraryWarningLogSelectVo.getPageable());
    }


    @Override
    public List<WarningDetailListVo> getWarningDetail(Integer warningId,Boolean isHandle) {
        List<WarningDetailListVo> warningDetailVos = new ArrayList<>();
        PredicateBuilder<LibraryWarningLogDetail> and = Specifications.and();
        and.eq("libraryWarningLogId",warningId);
        if (isHandle!=null&&isHandle){
            and.eq("warningHandle",1);
        }
        List<LibraryWarningLogDetail> all = libraryWarningLogDetailDao.findAll(and.build());
        all.stream().forEach(d->{
            WarningDetailListVo detailVo = new WarningDetailListVo();
            if (d.getDeviceId()!=null){
                DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(d.getDeviceId());
                BeanUtils.copyProperties(d,detailVo);
                detailVo.setDeviceLibraryEntity(deviceLibraryEntity);
            }else {
                DeviceLibrary deviceLibraryEntity = new DeviceLibrary();
                deviceLibraryEntity.setName("未知装备");
                deviceLibraryEntity.setModel("未知型号");
                deviceLibraryEntity.setRfidCardId("");
                deviceLibraryEntity.setRfidSurfaceId("");
                deviceLibraryEntity.setType(0);
                BeanUtils.copyProperties(d,detailVo);
                detailVo.setDeviceLibraryEntity(deviceLibraryEntity);
            }
            warningDetailVos.add(detailVo);
        });
        return warningDetailVos;
    }

    @Override
    public Integer updateDetailHandleResult(WarningHandleVo warningHandleVo) {
        LibraryWarningLogDetail detailEntity = libraryWarningLogDetailDao.getOne(warningHandleVo.getWarningDetailId());
        detailEntity.setHandleResult(warningHandleVo.getHandleResult());
        detailEntity.setWarningHandle(1);
        LibraryWarningLogDetail save = libraryWarningLogDetailDao.save(detailEntity);
        return save.getLibraryWarningLogId();
    }

    @Override
    public LibraryWarningLog getOne(Integer id) {
        return libraryWarningLogDao.getOne(id);
    }

    @Override
    public WarningCountVo getCount(LibraryWarningLogSelectVo libraryWarningLogSelectVo) throws ParseException {

        //获取时间段告警数量
        Long localWarning = libraryWarningLogDao.count(getSelectSpecification(libraryWarningLogSelectVo));
        //获取盘点告警数量
        libraryWarningLogSelectVo.setWarningType(Arrays.asList(2));
        Long inventoryWarning = libraryWarningLogDao.count(getSelectSpecification(libraryWarningLogSelectVo));
        //获取出入库告警数量
        libraryWarningLogSelectVo.setWarningType(Arrays.asList(0,1));
        Long enterOutWarning = libraryWarningLogDao.count(getSelectSpecification(libraryWarningLogSelectVo));
        //获取未处理告警数量
        libraryWarningLogSelectVo.setWarningType(null);
        libraryWarningLogSelectVo.setWarningHandle(0);
        Long handleWaring = libraryWarningLogDao.count(getSelectSpecification(libraryWarningLogSelectVo));
        return new WarningCountVo(localWarning,inventoryWarning,enterOutWarning,handleWaring);
    }

    @Override
    public LibraryWarningLog update(LibraryWarningLog libraryWarningLog) {
        return libraryWarningLogDao.save(libraryWarningLog);
    }

    private Specification<LibraryWarningLog> getSelectSpecification(LibraryWarningLogSelectVo libraryWarningLogSelectVo) throws ParseException {
        PredicateBuilder<LibraryWarningLog> predicateBuilder = Specifications.and();
        if (libraryWarningLogSelectVo.getUnit()!=null){
            predicateBuilder.eq("unit",libraryWarningLogSelectVo.getUnit());
        }else {
            predicateBuilder.eq("unit",userUtils.getCurrentUserUnitName());
        }

        if (libraryWarningLogSelectVo.getInventoryResults()!=null){
            predicateBuilder.like("inventoryResults","%"+libraryWarningLogSelectVo.getInventoryResults()+"%");
        }

        if (libraryWarningLogSelectVo.getStatus()!=null){
            predicateBuilder.eq("status",libraryWarningLogSelectVo.getStatus());
        }

        if (libraryWarningLogSelectVo.getWarningType()!=null){
            predicateBuilder.in("warningType",libraryWarningLogSelectVo.getWarningType().toArray());
        }
        if (libraryWarningLogSelectVo.getContent()!=null){
            Class<LibraryWarningLog> libraryWarningLogEntityClass = LibraryWarningLog.class;
            Field[] declaredFields = libraryWarningLogEntityClass.getDeclaredFields();
            PredicateBuilder<LibraryWarningLog> p = Specifications.or();
            for (Field field : declaredFields) {
                if (field.getType().equals(String.class)&&field.getAnnotation(Transient.class)==null) {
                    p.like(field.getName(), "%" + libraryWarningLogSelectVo.getContent() + "%");
                }
            }
            predicateBuilder.predicate(p.build());
        }

        if (libraryWarningLogSelectVo.getTime()!=null){
            switch (libraryWarningLogSelectVo.getTime()){
                case 0:
                    //设置查询条件为本年
                    predicateBuilder.ge("createTime",DateUtils.getYearStart());
                    predicateBuilder.le("createTime",DateUtils.getYearEnd());
                    break;
                case 1:
                    //设置查询条件为本月
                    predicateBuilder.ge("createTime",DateUtils.getMonthStart());
                    predicateBuilder.le("createTime",DateUtils.getMonthEnd());
                    break;
                case 2:
                    //设置查询条件为本周
                    predicateBuilder.ge("createTime",DateUtils.getWeekStart());
                    predicateBuilder.le("createTime",DateUtils.getWeekEnd());
                    break;
                case 3:
                    //设置查询条件为本日
                    predicateBuilder.like("createTime","%"+DateUtils.getToday()+"%");
                    break;
                default:
                    break;
            };
        }

        if (libraryWarningLogSelectVo.getStartTime()!=null){
            predicateBuilder.ge("createTime",libraryWarningLogSelectVo.getStartTime());
        }
        if (libraryWarningLogSelectVo.getEndTime()!=null){
            predicateBuilder.le("createTime",libraryWarningLogSelectVo.getEndTime());
        }
        return predicateBuilder.build();
    }
}
