package com.crm.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.manager.dao.mapper.SalesCommissionRuleMapper;
import com.crm.manager.service.SalesCommissionRuleService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.BaseResultWithPagerDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.sales.SalesCommissionRuleDropdownDto;
import com.crm.rely.backend.core.dto.sales.SalesCommissionRuleDto;
import com.crm.rely.backend.core.entity.sales.*;
import com.crm.rely.backend.core.enums.SalesKpiStandardType;
import com.crm.rely.backend.core.enums.SalesType;
import com.crm.rely.backend.core.pojo.table.SalesCommissionRuleTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.FormatPage;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class SalesCommissionRuleServiceImpl implements SalesCommissionRuleService {

    @Autowired
    private SalesCommissionRuleMapper salesCommissionRuleMapper;
    @Autowired
    private RedisService redisService;


    @Override
    public Map<Long, SalesCommissionRuleDto> mapAllData() throws ServiceException {

        try {
            List<SalesCommissionRuleDto> dtos = redisService.getList(Constants.SALES_COMMISSION_RULE, SalesCommissionRuleDto.class);
            if (CollectionUtils.isEmpty(dtos)) {
                handleRedis();
                dtos = redisService.getList(Constants.SALES_COMMISSION_RULE, SalesCommissionRuleDto.class);
            }

            Map<Long, SalesCommissionRuleDto> map = new HashMap<>();
            dtos.forEach(a -> map.put(a.getId(), a));
            return map;
        } catch (Exception e) {
            throw ServiceException.exception(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SalesCommissionRuleAddEntity entity) throws ServiceException {
        try {
            if (ruleNameExists(entity.getRuleName())) {
                throw ServiceException.exception("rule_name_exists");
            }

            SalesCommissionRuleTable salesCommissionRuleTable = SalesCommissionRuleTable.getInstance();
            BeanUtils.copyProperties(entity, salesCommissionRuleTable);
            salesCommissionRuleTable.setSalaryRule(JSON.toJSONString(entity.getSalaryRule()));
            salesCommissionRuleTable.setPersonalKpiRule(JSON.toJSONString(entity.getPersonalKpiRule()));
            salesCommissionRuleTable.setTeamKpiRule(JSON.toJSONString(entity.getTeamKpiRule()));
            salesCommissionRuleTable.setPersonalVolumeRule(JSON.toJSONString(entity.getPersonalVolumeRule()));
            salesCommissionRuleTable.setTeamVolumeRule(JSON.toJSONString(entity.getTeamVolumeRule()));
            salesCommissionRuleMapper.save(salesCommissionRuleTable);
            //刷新缓存
            handleRedis();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw ServiceException.exception(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(SalesCommissionRuleUpdateEntity entity) throws ServiceException {
        try {
            SalesCommissionRuleTable table = salesCommissionRuleMapper.findOne(entity.getId());
            if (table == null) {
                throw ServiceException.exception(Constants.INFO_NOT_FOUND);
            }

            //名称是否重复
            if (!table.getRuleName().equals(entity.getRuleName())) {
                if (ruleNameExists(entity.getRuleName())) {
                    throw ServiceException.exception("rule_name_exists");
                }
            }

            BeanUtils.copyProperties(entity, table);
            table.setSalaryRule(JSON.toJSONString(entity.getSalaryRule()));
            table.setPersonalKpiRule(JSON.toJSONString(entity.getPersonalKpiRule()));
            table.setTeamKpiRule(JSON.toJSONString(entity.getTeamKpiRule()));
            table.setPersonalVolumeRule(JSON.toJSONString(entity.getPersonalVolumeRule()));
            table.setTeamVolumeRule(JSON.toJSONString(entity.getTeamlVolumeRule()));
            salesCommissionRuleMapper.update(table);
            //刷新缓存
            handleRedis();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw ServiceException.exception(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) throws ServiceException {
        try {
            SalesCommissionRuleTable table = salesCommissionRuleMapper.findOne(id);
            if (table == null) {
                throw ServiceException.exception(Constants.INFO_NOT_FOUND);
            }

            //TODO 查询是否占用

            //删除
            salesCommissionRuleMapper.deleteById(id);
            //刷新缓存
            handleRedis();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw ServiceException.exception(e.getMessage());
        }
    }

    @Override
    public SalesCommissionRuleDto getById(Long id) throws ServiceException {
        SalesCommissionRuleTable table = salesCommissionRuleMapper.findOne(id);
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return convertTableToDto(table);
    }

    @Override
    public BaseResultWithPagerDto<List<SalesCommissionRuleDto>> searchList(SalesCommissionRuleSearchEntity searchEntity) throws ServiceException {

        Integer count = salesCommissionRuleMapper.countSearch(searchEntity);
        PageDto pageDto = FormatPage.format(searchEntity.getPage(), count);
        if (count == null || count == 0) {
            return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto);
        }

        List<SalesCommissionRuleTable> tables = salesCommissionRuleMapper.listSearch(searchEntity);
        List<SalesCommissionRuleDto> dtos = Lists.newArrayList();
        for (SalesCommissionRuleTable table : tables) {
            dtos.add(convertTableToDto(table));
        }

        return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto, dtos);
    }

    @Override
    public List<SalesCommissionRuleDropdownDto> searchDropdownList() throws ServiceException {
        List<SalesCommissionRuleTable> tables = salesCommissionRuleMapper.findAllDropdownInfo();
        List<SalesCommissionRuleDropdownDto> dtos = Lists.newArrayList();
        for (SalesCommissionRuleTable table : tables) {
            SalesCommissionRuleDropdownDto dto = new SalesCommissionRuleDropdownDto();
            BeanUtils.copyProperties(table, dto);
            dto.setSaleTypeName(SalesType.matchCode(dto.getSalesType()).getDesc());
            dto.setKpiStandardName(SalesKpiStandardType.matchCode(dto.getKpiStandard()).getDesc());
            dtos.add(dto);
        }
        return dtos;
    }

    private SalesCommissionRuleDto convertTableToDto(SalesCommissionRuleTable table) {
        SalesCommissionRuleDto dto = new SalesCommissionRuleDto();
        BeanUtils.copyProperties(table, dto);
        dto.setSalaryRule(JSON.parseArray(table.getSalaryRule(), SalesCommissionSalaryRuleEntity.class));
        dto.setPersonalKpiRule(JSON.parseArray(table.getPersonalKpiRule(), SalesCommissionSalaryRuleEntity.class));
        dto.setTeamKpiRule(JSON.parseArray(table.getTeamKpiRule(), SalesCommissionSalaryRuleEntity.class));
        dto.setPersonalVolumeRule(JSON.parseArray(table.getPersonalVolumeRule(), SalesCommissionVolumeRuleEntity.class));
        dto.setTeamVolumeRule(JSON.parseArray(table.getTeamVolumeRule(), SalesCommissionVolumeRuleEntity.class));
        return dto;
    }



    private synchronized void handleRedis() throws Exception {
//        List<SalesCommissionRuleTable> tables = salesCommissionRuleMapper.findAll();
//        List<SalesCommissionRuleDto> dtos = Lists.newArrayList();
//        for (SalesCommissionRuleTable table : tables) {
//            dtos.add(convertTableToDto(table));
//        }
//
//        redisService.saveList(Constants.SALES_COMMISSION_RULE, dtos);

    }

    private boolean ruleNameExists(String ruleName) {
        int count = salesCommissionRuleMapper.countByRuleName(ruleName);
        return count > 0 ? true : false;
    }
}
