package com.tykj.dev.device.destroy.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.subject.service.UserPublicService;
import com.tykj.dev.misc.utils.StringSplitUtil;
import com.tykj.dev.misc.utils.TimestampUtil;
import com.tykj.dev.device.destroy.entity.domain.DeviceDestroyBill;
import com.tykj.dev.device.destroy.entity.vo.DeviceDestroyBillSelectVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.tykj.dev.device.destroy.repository.DeviceDestroyBillDao;
import com.tykj.dev.device.destroy.service.DeviceDestroyBillService;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.*;

/**
 * @author dengdiyi
 */
@Service
public class DeviceDestroyBillServiceImpl implements DeviceDestroyBillService {

    @Autowired
    private DeviceDestroyBillDao deviceDestroyBillDao;

    @Autowired
    private UserPublicService userService;

    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Override
    public DeviceDestroyBill addEntity(DeviceDestroyBill deviceDestroyBillEntity) {
        return deviceDestroyBillDao.save(deviceDestroyBillEntity);
    }

    @Override
    public Page<DeviceDestroyBill> getPage(DeviceDestroyBillSelectVo deviceDestoryBillSelectVo, Pageable pageable) {
        Page<DeviceDestroyBill> page = deviceDestroyBillDao.findAll(getSelectSpecification(deviceDestoryBillSelectVo),deviceDestoryBillSelectVo.getPageable());
        for (DeviceDestroyBill d:page.getContent()) {
            d.setUserA(userService.getOne(d.getStartUserAId()).getName());
            List<Integer> list = StringSplitUtil.split(d.getDestroyDeviceDetail());
            Set<String> nameSet = new HashSet<>();
            Set<String> modelSet = new HashSet<>();
            for (Integer id:list) {
                if (id>0){
                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                    if (deviceLibraryEntity!=null){
                        nameSet.add(deviceLibraryEntity.getName());
                        modelSet.add(deviceLibraryEntity.getModel());
                    }
                }
            }
            d.setName(StringUtils.join(nameSet,","));
            d.setModel(StringUtils.join(modelSet,","));
        }
        return page;
    }

    @Override
    public DeviceDestroyBill getOne(Integer id) {
        Optional<DeviceDestroyBill> resultEntity = deviceDestroyBillDao.findById(id);
        return resultEntity.orElse(null);
    }

    @Override
    public DeviceDestroyBill updateEntity(DeviceDestroyBill deviceDestoryBillEntity) {
        return deviceDestroyBillDao.save(deviceDestoryBillEntity);
    }

    @Override
    public void delete(Integer id) {
        deviceDestroyBillDao.deleteById(id);
    }

    @Override
    public Integer getNewDocNumber() throws ParseException {
        PredicateBuilder<DeviceDestroyBill> predicateBuilder = Specifications.and();
        predicateBuilder.ne("docNumber",null);
        predicateBuilder.ge("createTime", TimestampUtil.getYearStart());
        predicateBuilder.le("createTime",TimestampUtil.getYearEnd());
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC,"createTime"));
        Sort by = Sort.by(orders);
        List<DeviceDestroyBill> all = deviceDestroyBillDao.findAll(predicateBuilder.build(), by);
//      如果有数据则取第一个
        if (all.size()!=0){
            DeviceDestroyBill deviceDestoryBillEntity = all.get(0);
            return  deviceDestoryBillEntity.getDocNumber();
        }else {
//      如果没有则取1
            return 1;
        }
    }

    private Specification<DeviceDestroyBill> getSelectSpecification(DeviceDestroyBillSelectVo deviceDestoryBillSelectVo){
        PredicateBuilder<DeviceDestroyBill> predicateBuilder = Specifications.and();
        if (deviceDestoryBillSelectVo!=null) {
            if (deviceDestoryBillSelectVo.getUndertaker()!=null){
                predicateBuilder.eq("supervisor",deviceDestoryBillSelectVo.getSupervisor());
            }
            if (deviceDestoryBillSelectVo.getSupervisor()!=null){
                predicateBuilder.eq("supervisor",deviceDestoryBillSelectVo.getSupervisor());
            }
            if (deviceDestoryBillSelectVo.getLeader()!=null){
                predicateBuilder.eq("leader",deviceDestoryBillSelectVo.getLeader());
            }

            if (deviceDestoryBillSelectVo.getContent() != null) {
                Class<DeviceDestroyBill> deviceDestoryBillEntityClass = DeviceDestroyBill.class;
                Field[] declaredFields = deviceDestoryBillEntityClass.getDeclaredFields();
                PredicateBuilder<DeviceDestroyBill> p = Specifications.or();
                for (Field field : declaredFields) {
                    if (field.getType().equals(String.class)&&field.getAnnotation(Transient.class)==null) {
                        p.like(field.getName(), "%" + deviceDestoryBillSelectVo.getContent() + "%");
                    }
                }
                predicateBuilder.predicate(p.build());
            }
            if (deviceDestoryBillSelectVo.getStartTime() != null) {
                predicateBuilder.gt("destroyTime", deviceDestoryBillSelectVo.getStartTime());
            }
            if (deviceDestoryBillSelectVo.getEndTime() != null) {
                predicateBuilder.lt("destroyTime", deviceDestoryBillSelectVo.getEndTime());
            }
        }
        predicateBuilder.in("destroyStatus",2);
        return predicateBuilder.build();
    }
}
