package me.zhengjie.modules.company.service.impl;

import java.util.List;
import java.util.Set;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;
import me.zhengjie.exception.EntityExistException;
import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.modules.company.domain.Company;
import me.zhengjie.modules.company.repository.CompanyRepository;
import me.zhengjie.modules.company.service.CompanyService;
import me.zhengjie.modules.company.service.criteria.CompanyQueryCriteria;
import me.zhengjie.modules.company.service.dto.CompanyDto;
import me.zhengjie.modules.company.service.mapstruct.CompanyMapper;
import me.zhengjie.utils.PageResult;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.ValidationUtil;

@Service
@RequiredArgsConstructor
public class CompanyServiceImpl implements CompanyService {

    private final CompanyRepository companyRepository;
    private final CompanyMapper companyMapper;

    @Override
    public PageResult<CompanyDto> queryAll(CompanyQueryCriteria criteria, Pageable pageable) {
        Page<Company> page = companyRepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,
                        criteria, criteriaBuilder),
                pageable);
        return PageUtil.toPage(page.map(companyMapper::toDto));
    }

    @Override
    public List<CompanyDto> queryAll(CompanyQueryCriteria criteria) {
        List<Company> companies = companyRepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
        return companyMapper.toDto(companies);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Company resources) {
        if (companyRepository.findByName(resources.getName()) != null) {
            throw new EntityExistException(Company.class, "name", resources.getName());
        }
        companyRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Company resources) throws Exception {
        Company company = companyRepository.findById(resources.getId()).orElseGet(Company::new);
        ValidationUtil.isNull(company.getId(), "Company", "id", resources.getId());
        Company company1 = companyRepository.findByName(resources.getName());
        if (company1 != null && !company.getId().equals(company1.getId())) {
            throw new EntityExistException(Company.class, "name", resources.getName());
        }
        company.setName(resources.getName());
        companyRepository.save(company);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        companyRepository.deleteAllByIdIn(ids);
    }

    @Override
    public CompanyDto findByName(String companyName) {
        Company company = companyRepository.findByName(companyName);
        if (company == null) {
            throw new EntityNotFoundException(Company.class, "name", companyName);
        } else {
            return companyMapper.toDto(company);
        }
    }

}
