
package com.crm.web.service.impl;

import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.GlobalConfigConstants;
import com.crm.rely.backend.core.dto.system.config.SysConfigSearchDto;
import com.crm.rely.backend.core.entity.system.config.SysConfigSingleEntity;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.service.RedisService;
import com.crm.web.dao.repository.SysConfigRepository;
import com.crm.web.service.SysConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class SysConfigServiceImpl implements SysConfigService {

    @Autowired
    private SysConfigRepository sysConfigRepository;

    @Autowired
    private RedisService redisService;

    @Override
    public SysConfigSearchDto searchSingle(SysConfigSingleEntity entity) throws ServiceException {
        SysConfigTable sysConfigTable = sysConfigRepository.getByIdAndCode(entity.getId(), entity.getCode());

        if (sysConfigTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return transform(sysConfigTable);

    }

    private SysConfigSearchDto transform(SysConfigTable sysConfigTable) {
        SysConfigSearchDto sysConfigSearchDto = new SysConfigSearchDto();
        BeanUtils.copyProperties(sysConfigTable, sysConfigSearchDto);
        return sysConfigSearchDto;
    }

    @Override
    public SysConfigTable getByCode(String code) throws ServiceException {
        SysConfigTable sysConfigTable = redisService.getEntity(code, SysConfigTable.class);
        if (sysConfigTable != null) {
            return sysConfigTable;
        }
        SysConfigTable supplementTable = sysConfigRepository.getByCode(code);
        if (supplementTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        saveCache(supplementTable);

        return supplementTable;
    }

    @Override
    public List<SysConfigTable> getByCodes(List<String> codes) throws ServiceException {
        List<SysConfigTable> sysConfigTables = new ArrayList<>(codes.size());
        for (int i = 0; i < codes.size(); ) {
            SysConfigTable sysConfigTable = redisService.getEntity(codes.get(i), SysConfigTable.class);
            if (sysConfigTable != null) {
                sysConfigTables.add(sysConfigTable);
                codes.remove(i);
            } else {
                i++;
            }
        }
        if (codes != null && codes.size() > 0) {
            List<SysConfigTable> supplementTables = sysConfigRepository.getByCodeIn(codes);
            if (sysConfigTables == null || supplementTables.size() <= 0) {
                throw ServiceException.exception(Constants.INFO_NOT_FOUND);
            }

            saveCache(supplementTables);

            sysConfigTables.addAll(supplementTables);
        }
        return sysConfigTables;
    }

    private void saveCache(List<SysConfigTable> sysConfigTables) throws ServiceException {
        List<String> configListKey = redisService.getList(GlobalConfigConstants.CONFIG_LIST, String.class);
        sysConfigTables.forEach(v -> {
            try {
                saveCache(v, configListKey);
            } catch (ServiceException e) {
                e.printStackTrace();
            }
        });
    }

    private void saveCache(SysConfigTable sysConfigTable) throws ServiceException {
        saveCache(sysConfigTable, null);
    }

    private void saveCache(SysConfigTable sysConfigTable, List<String> configListKey) throws ServiceException {
        if (configListKey == null) {
            configListKey = redisService.getList(GlobalConfigConstants.CONFIG_LIST, String.class);
        }
        if (configListKey == null) {
            configListKey = new ArrayList<>(10);
        }
        if (!configListKey.contains(sysConfigTable.getCode())) {
            configListKey.add(sysConfigTable.getCode());
        }
        redisService.save(sysConfigTable.getCode(), sysConfigTable);
        redisService.save(GlobalConfigConstants.CONFIG_LIST, configListKey);
    }
}
