package vn.azteam.tpf.service;

import io.github.jhipster.service.QueryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 org.springframework.transaction.annotation.Transactional;
import vn.azteam.tpf.domain.*;
import vn.azteam.tpf.repository.TBCodeDetailsRepository;
import vn.azteam.tpf.service.dto.TBCodeDetailsCriteria;
import vn.azteam.tpf.service.dto.TBCodeDetailsDTO;
import vn.azteam.tpf.service.mapper.TBCodeDetailsMapper;

import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import java.util.Optional;

@Service
@Transactional(readOnly = true)
public class TBCodeDetailsQueryService extends QueryService<TBCodeDetails> {

    private final Logger log = LoggerFactory.getLogger(TBCodeDetailsQueryService.class);

    private final TBCodeDetailsRepository tBCodeDetailsRepository;

    private final TBCodeDetailsMapper tBCodeDetailsMapper;

    public TBCodeDetailsQueryService(TBCodeDetailsRepository tBCodeDetailsRepository,
                                     TBCodeDetailsMapper tBCodeDetailsMapper) {
        this.tBCodeDetailsRepository = tBCodeDetailsRepository;
        this.tBCodeDetailsMapper = tBCodeDetailsMapper;
    }

    @Transactional(readOnly = true)
    public Page<TBCodeDetailsDTO> findByCriteria(TBCodeDetailsCriteria criteria, Pageable page) {
        log.debug("find by criteria : {}, page: {}", criteria, page);
        final Specification<TBCodeDetails> specification = createSpecification(criteria);
        return tBCodeDetailsRepository.findAll(specification, page)
            .map(tBCodeDetailsMapper::toDto);
    }

    @Transactional(readOnly = true)
    public Optional<TBCodeDetailsDTO> findByCode(String code) {
        log.debug("find by criteria code : {}", code);
        return tBCodeDetailsRepository.findByCode(code)
            .map(tBCodeDetailsMapper::toDto);
    }

    private Specification<TBCodeDetails> initializeCropSpecification() {
        return (Specification<TBCodeDetails>) (root, query, cb) -> {
            final Join<TBCodeDetails, TBDetailUser> detailUserJoin = root.join(TBCodeDetails_.deletedBy, JoinType.LEFT);
            return cb.isNull(detailUserJoin.get(TBDetailUser_.id));
        };
    }

    /**
     * Function to convert TBCodeDetailCriteria to a {@link Specification}
     */
    private Specification<TBCodeDetails> createSpecification(TBCodeDetailsCriteria criteria) {
        Specification<TBCodeDetails> specification = initializeCropSpecification();
        if (criteria != null) {
            if (criteria.getId() != null) {
                specification = specification.and(buildSpecification(criteria.getId(), TBCodeDetails_.id));
            }
//            if (criteria.getQrCode() != null) {
//                specification = specification.and(buildStringSpecification(criteria.getQrCode(), TBCrop_.qrCode));
//            }
            if (criteria.getCode() != null) {
                specification = specification.and(buildStringSpecification(criteria.getCode(), TBCodeDetails_.code));
            }
//            if (criteria.getAreaM2() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getAreaM2(), TBCrop_.areaM2));
//            }
//            if (criteria.getTbCropType() != null) {
//                specification = specification.and(buildSpecification(criteria.getTbCropType(),
//                    root -> root.join(TBCrop_.tbCropType, JoinType.LEFT).get(TBCropType_.id)));
//            }
//            if (criteria.getStartDate() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getStartDate(), TBCrop_.startDate));
//            }
//            if (criteria.getEndDate() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getEndDate(), TBCrop_.endDate));
//            }
//            if (criteria.getStatus() != null) {
//                specification = specification.and(buildStringSpecification(criteria.getStatus(), TBCrop_.status));
//            }
//            if (criteria.getDescription() != null) {
//                specification = specification.and(buildStringSpecification(criteria.getDescription(), TBCrop_.description));
//            }
//            if (criteria.getAgeDayStartAt() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getAgeDayStartAt(), TBCrop_.ageDayStartAt));
//            }
//            if (criteria.getCreatedDate() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getCreatedDate(), TBCrop_.createdDate));
//            }
//            if (criteria.getModifiedDate() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getModifiedDate(), TBCrop_.modifiedDate));
//            }
//            if (criteria.getDeletedDate() != null) {
//                specification = specification.and(buildRangeSpecification(criteria.getDeletedDate(), TBCrop_.deletedDate));
//            }
//            if (criteria.getTbSuppliesId() != null) {
//                specification = specification.and(buildSpecification(criteria.getTbSuppliesId(),
//                    root -> root.join(TBCrop_.tbSupplies, JoinType.LEFT).get(TBSupplies_.id)));
//            }
//            if (criteria.getTbGuidelineId() != null) {
//                specification = specification.and(buildSpecification(criteria.getTbGuidelineId(),
//                    root -> root.join(TBCrop_.tbGuideline, JoinType.LEFT).get(TBGuideline_.id)));
//            }
//            if (criteria.getNetHouseId() != null) {
//                specification = specification.and(buildSpecification(criteria.getNetHouseId(),
//                    root -> root.join(TBCrop_.tbEntity, JoinType.LEFT).get(TBEntity_.id)));
//            }
//            if (criteria.getCreatedById() != null) {
//                specification = specification.and(buildSpecification(criteria.getCreatedById(),
//                    root -> root.join(TBCrop_.createdBy, JoinType.LEFT).get(TBDetailUser_.id)));
//            }
//            if (criteria.getModifiedById() != null) {
//                specification = specification.and(buildSpecification(criteria.getModifiedById(),
//                    root -> root.join(TBCrop_.modifiedBy, JoinType.LEFT).get(TBDetailUser_.id)));
//            }
//            if (criteria.getDeletedById() != null) {
//                specification = specification.and(buildSpecification(criteria.getDeletedById(),
//                    root -> root.join(TBCrop_.deletedBy, JoinType.LEFT).get(TBDetailUser_.id)));
//            }
//            if (criteria.getTbDetailUserId() != null) {
//                specification = specification.and(buildSpecification(criteria.getTbDetailUserId(),
//                    root -> root.join(TBCrop_.tbDetailUsers, JoinType.LEFT).get(TBDetailUser_.id)));
//            }
        }
        return specification;
    }
}
