package com.tykj.dev.device.allot.service.impl;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.device.allot.repository.AllotBillDao;
import com.tykj.dev.device.allot.service.AllotBillService;
import com.tykj.dev.device.allot.subject.domin.AllotBill;
import com.tykj.dev.device.allot.subject.vo.AllotBillSelectVo;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;

/**
 * @author dengdiyi
 */
@Service
public class AllotBillServiceImpl implements AllotBillService {

    @Autowired
    private AllotBillDao allotBillDao;

    @Autowired
    private UserPublicService userPublicService;

    @Override
    public AllotBill addEntity(AllotBill allotBillEntity) {
        return allotBillDao.save(allotBillEntity);
    }

    @Override
    public AllotBill update(AllotBill allotBillEntity) {
        return allotBillDao.save(allotBillEntity);
    }

    @Override
    public Page<AllotBill> getPage(AllotBillSelectVo allotBillSelectVo, Pageable pageable) {
        Page<AllotBill> page = allotBillDao.findAll(getSelectSpecification(allotBillSelectVo),pageable);
        for (AllotBill a:page.getContent()) {
            a.setSenderUserA(userPublicService.getOne(a.getSendUseraId()).getName());
            a.setSenderUserB(userPublicService.getOne(a.getSendUserbId()).getName());
            a.setReceiveUserA(userPublicService.getOne(a.getReceiveUseraId()).getName());
            a.setReceiveUserB(userPublicService.getOne(a.getReceiveUserbId()).getName());
        }
        return page;
    }

    @Override
    public List<AllotBill> getList(AllotBillSelectVo allotBillSelectVo) {
        return allotBillDao.findAll(getSelectSpecification(allotBillSelectVo));
    }

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

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

    private Specification<AllotBill> getSelectSpecification(AllotBillSelectVo allotBillSelectVo){
        PredicateBuilder<AllotBill> predicateBuilder = Specifications.and();
        if (allotBillSelectVo!=null) {
            if (allotBillSelectVo.getReplayNumber()!=null){
                predicateBuilder.eq("replayNumber",allotBillSelectVo.getReplayNumber());
            }
            if (allotBillSelectVo.getReceiveUnit()!=null){
                predicateBuilder.eq("receiveUnit",allotBillSelectVo.getReceiveUnit());
            }
            if (allotBillSelectVo.getReceiveUseraId()!=null){
                predicateBuilder.eq("receiveUseraId",allotBillSelectVo.getReceiveUseraId());
            }
            if (allotBillSelectVo.getSendUnit()!=null){
                predicateBuilder.eq("sendUnit",allotBillSelectVo.getSendUnit());
            }
            if (allotBillSelectVo.getSendUseraId()!=null){
                predicateBuilder.eq("sendUseraId",allotBillSelectVo.getSendUseraId());
            }
            if (allotBillSelectVo.getContent() != null) {
                Class<AllotBill> allotBillEntityClass = AllotBill.class;
                Field[] declaredFields = allotBillEntityClass.getDeclaredFields();
                PredicateBuilder<AllotBill> p = Specifications.or();
                for (Field field : declaredFields) {
                    if (field.getType().equals(String.class)&&field.getAnnotation(Transient.class)==null) {
                        p.like(field.getName(), "%" + allotBillSelectVo.getContent() + "%");
                    }
                }
                predicateBuilder.predicate(p.build());
            }
            if (allotBillSelectVo.getStartTime() != null) {
                predicateBuilder.gt("sendTime", allotBillSelectVo.getStartTime());
            }
            if (allotBillSelectVo.getEndTime() != null) {
                predicateBuilder.lt("receiveTime", allotBillSelectVo.getEndTime());
            }
            predicateBuilder.eq("allotStatus",5);
        }
        return predicateBuilder.build();
    }
}
