package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.RiskRevokeCreditRuleGroupMapper;
import com.crm.manager.dao.repository.RiskRevokeCreditRuleGroupRepository;
import com.crm.manager.service.RiskRevokeCreditRuleExcludeLoginService;
import com.crm.manager.service.RiskRevokeCreditRuleGroupService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.ManagerConstant;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.risk.revoke.credit.rule.exclude.login.RiskRevokeCreditRuleExcludeLoginDto;
import com.crm.rely.backend.core.dto.risk.revoke.credit.rule.group.RiskRevokeCreditRuleGroupDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.risk.revoke.credit.rule.group.RiskRevokeCreditRuleGroupAddEntity;
import com.crm.rely.backend.core.entity.risk.revoke.credit.rule.group.RiskRevokeCreditRuleGroupDeleteEntity;
import com.crm.rely.backend.core.entity.risk.revoke.credit.rule.group.RiskRevokeCreditRuleGroupSearchPageEntity;
import com.crm.rely.backend.core.entity.risk.revoke.credit.rule.group.RiskRevokeCreditRuleGroupUpdateEntity;
import com.crm.rely.backend.core.pojo.table.RiskRevokeCreditRuleGroupTable;
import com.crm.rely.backend.exception.ServiceException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class RiskRevokeCreditRuleGroupServiceImpl implements RiskRevokeCreditRuleGroupService {

    @Autowired
    private RiskRevokeCreditRuleGroupRepository riskRevokeCreditRuleGroupRepository;

    @Autowired
    private RiskRevokeCreditRuleGroupMapper riskRevokeCreditRuleGroupMapper;

    @Autowired
    private RiskRevokeCreditRuleExcludeLoginService riskRevokeCreditRuleExcludeLoginService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(RiskRevokeCreditRuleGroupAddEntity entity) throws ServiceException {
        existsByGroupCode(entity.getGroupCode());

        RiskRevokeCreditRuleGroupTable riskRevokeCreditRuleGroupTable = new RiskRevokeCreditRuleGroupTable();
        BeanUtils.copyProperties(entity, riskRevokeCreditRuleGroupTable);

        riskRevokeCreditRuleGroupRepository.save(riskRevokeCreditRuleGroupTable);

        riskRevokeCreditRuleExcludeLoginService.save(riskRevokeCreditRuleGroupTable.getId(), entity.getExcludeLoginSaveEntities());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(RiskRevokeCreditRuleGroupUpdateEntity entity) throws ServiceException {
        RiskRevokeCreditRuleGroupTable riskRevokeCreditRuleGroupTable = riskRevokeCreditRuleGroupRepository.findFirstById(entity.getId());
        if (riskRevokeCreditRuleGroupTable == null) {
            throw ServiceException.notFoundException();
        }

        if (!entity.getGroupCode().equals(riskRevokeCreditRuleGroupTable.getGroupCode())) {
            existsByGroupCode(entity.getGroupCode());
        }

        BeanUtils.copyProperties(entity, riskRevokeCreditRuleGroupTable);

        riskRevokeCreditRuleGroupRepository.save(riskRevokeCreditRuleGroupTable);

        riskRevokeCreditRuleExcludeLoginService.save(riskRevokeCreditRuleGroupTable.getId(), entity.getExcludeLoginSaveEntities());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(RiskRevokeCreditRuleGroupDeleteEntity entity) throws ServiceException {

        List<RiskRevokeCreditRuleGroupTable> riskRevokeCreditRuleGroupTables = riskRevokeCreditRuleGroupRepository.findAllByIdIn(entity.getIds());
        if (riskRevokeCreditRuleGroupTables == null || riskRevokeCreditRuleGroupTables.size() <= 0) {
            return;
        }
        riskRevokeCreditRuleGroupRepository.delete(riskRevokeCreditRuleGroupTables);

        riskRevokeCreditRuleExcludeLoginService.delete(entity.getIds());
    }

    @Override
    public ResultWithPagerDto<RiskRevokeCreditRuleGroupDto> searchPageList(RiskRevokeCreditRuleGroupSearchPageEntity entity) throws ServiceException {
        Integer count = riskRevokeCreditRuleGroupMapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }

        List<RiskRevokeCreditRuleGroupDto> riskRevokeCreditRuleGroupDto = getRiskRevokeCreditRuleGroupDto(entity);
        if (riskRevokeCreditRuleGroupDto == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        return ResultWithPagerDto.success(pageDto, riskRevokeCreditRuleGroupDto);
    }

    @Override
    public RiskRevokeCreditRuleGroupDto searchSingle(SingleLongEntity entity) throws ServiceException {
        RiskRevokeCreditRuleGroupTable riskRevokeCreditRuleGroupTable = riskRevokeCreditRuleGroupRepository.getFirstById(entity.getId());

        RiskRevokeCreditRuleGroupDto riskRevokeCreditRuleGroupDto = transform(riskRevokeCreditRuleGroupTable);
        List<Long> excludeLogins = riskRevokeCreditRuleExcludeLoginService.getExcludeLoginDto(riskRevokeCreditRuleGroupDto.getId());
        riskRevokeCreditRuleGroupDto.setExcludeLogins(excludeLogins);
        return riskRevokeCreditRuleGroupDto;
    }

    private void existsByGroupCode(String groupCode) throws ServiceException {
        boolean exist = riskRevokeCreditRuleGroupRepository.existsByGroupCode(groupCode);

        if (exist) {
            throw ServiceException.exception(ManagerConstant.CUSTOM_GROUP_CODE_IS_EXIST);
        }
    }

    private List<RiskRevokeCreditRuleGroupDto> getRiskRevokeCreditRuleGroupDto(RiskRevokeCreditRuleGroupSearchPageEntity entity) throws ServiceException {
        List<RiskRevokeCreditRuleGroupTable> riskRevokeCreditRuleGroupTables = riskRevokeCreditRuleGroupMapper.pageList(entity);

        if (riskRevokeCreditRuleGroupTables == null || riskRevokeCreditRuleGroupTables.size() <= 0) {

            return null;
        }
        List<RiskRevokeCreditRuleGroupDto> riskRevokeCreditRuleGroupDtos = new ArrayList<>(riskRevokeCreditRuleGroupTables.size());

        for (RiskRevokeCreditRuleGroupTable riskRevokeCreditRuleGroupTable : riskRevokeCreditRuleGroupTables) {
            RiskRevokeCreditRuleGroupDto riskRevokeCreditRuleGroupDto = transform(riskRevokeCreditRuleGroupTable);
            riskRevokeCreditRuleGroupDtos.add(riskRevokeCreditRuleGroupDto);
        }
        return riskRevokeCreditRuleGroupDtos;
    }

    private RiskRevokeCreditRuleGroupDto transform(RiskRevokeCreditRuleGroupTable riskRevokeCreditRuleGroupTable) {
        RiskRevokeCreditRuleGroupDto riskRevokeCreditRuleGroupDto = new RiskRevokeCreditRuleGroupDto();
        BeanUtils.copyProperties(riskRevokeCreditRuleGroupTable, riskRevokeCreditRuleGroupDto);
        return riskRevokeCreditRuleGroupDto;
    }
}
