package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.CustomGroupDao;
import com.crm.manager.dao.repository.*;
import com.crm.manager.service.CustomGroupHideService;
import com.crm.manager.service.CustomGroupLeverageService;
import com.crm.manager.service.CustomGroupPointService;
import com.crm.manager.service.CustomGroupService;
import com.crm.rely.backend.configuration.LocaleMessage;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.ManagerConstant;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
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.custom.group.*;
import com.crm.rely.backend.core.dto.custom.group.hide.CustomGroupHideDto;
import com.crm.rely.backend.core.dto.custom.group.leverage.CustomGroupLeverageDto;
import com.crm.rely.backend.core.dto.custom.group.print.CustomGroupPointDto;
import com.crm.rely.backend.core.dto.custom.type.CustomTypeSelectDto;
import com.crm.rely.backend.core.dto.system.pos.SysPosSelectDto;
import com.crm.rely.backend.core.entity.custom.group.CustomGroupAddEntity;
import com.crm.rely.backend.core.entity.custom.group.CustomGroupListEntity;
import com.crm.rely.backend.core.entity.custom.group.CustomGroupPlatformListEntity;
import com.crm.rely.backend.core.entity.custom.group.CustomGroupUpdateEntity;
import com.crm.rely.backend.core.entity.custom.group.hide.CustomGroupHideSaveEntity;
import com.crm.rely.backend.core.entity.custom.group.leverage.CustomGroupLeverageSaveEntity;
import com.crm.rely.backend.core.entity.custom.group.point.CustomGroupPointSaveEntity;
import com.crm.rely.backend.core.pojo.table.*;
import com.crm.rely.backend.core.pojo.view.CustomGroupView;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.util.FormatPage;
import com.crm.rely.backend.util.TranslateUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
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;

/**
 * Created by max on 2020/7/8.
 */
@SuppressWarnings("SpringJavaAutowiringInspection")
@Service
public class CustomGroupServiceImpl implements CustomGroupService {

    @Autowired
    private CustomGroupRepository customGroupRepository;
    @Autowired
    private CustomGroupDao customGroupDao;
    @Autowired
    private AccountTypeRepository accountTypeRepository;
    @Autowired
    private AccountTypePointRepository accountTypePointRepository;

    @Autowired
    private AccountTypeLeverageRepository accountTypeLeverageRepository;
    @Autowired
    private AccountTypeCurrencyRepository accountTypeCurrencyRepository;

    @Autowired
    private AccountHideRepository accountHideRepository;

    @Autowired
    private CustomGroupLeverageService customGroupLeverageService;
    @Autowired
    private CustomGroupHideService customGroupHideService;
    @Autowired
    private CustomGroupPointService customGroupPointService;
    @Autowired
    private LocaleMessage localeMessage;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(CustomGroupAddEntity entity) throws Exception {
        /*
            验证组别标识是否唯一
         */
        existByCode(entity.getCode());

        CustomGroupTable table = new CustomGroupTable();
        BeanUtils.copyProperties(entity, table);
        if (table.getRebateValid() == null) {
            table.setRebateValid(0);
        }

        if (table.getCommissionValid() == null) {
            table.setCommissionValid(0);
        }

        if (entity.getIntegralValid() == null) {
            entity.setIntegralValid(0);
        }

        if (entity.getSalesCommissionValid() == null) {
            entity.setSalesCommissionValid(0);
        }

        if (entity.getStorageValid() == null) {
            entity.setStorageValid(0);
        }

        if (entity.getPointValid() == null) {
            entity.setPointValid(0);
        }

        if (entity.getHideValid() == null) {
            entity.setHideValid(0);
        }

        customGroupRepository.save(table);

        //更新杠杆
        CustomGroupLeverageSaveEntity customGroupLeverageSaveEntity = new CustomGroupLeverageSaveEntity();
        customGroupLeverageSaveEntity.setGroupId(table.getId());
        customGroupLeverageSaveEntity.setLeverages(entity.getLeverages());
        customGroupLeverageSaveEntity.setIp(entity.getAddIp());
        customGroupLeverageSaveEntity.setTime(entity.getAddTime());
        customGroupLeverageSaveEntity.setUserId(entity.getAddUser());
        customGroupLeverageService.save(customGroupLeverageSaveEntity);

        //更新暗点
        CustomGroupHideSaveEntity customGroupHideSaveEntity = new CustomGroupHideSaveEntity();
        customGroupHideSaveEntity.setGroupId(table.getId());
        customGroupHideSaveEntity.setHides(entity.getHides());
        customGroupHideSaveEntity.setIp(entity.getAddIp());
        customGroupHideSaveEntity.setTime(entity.getAddTime());
        customGroupHideSaveEntity.setUserId(entity.getAddUser());
        customGroupHideService.save(customGroupHideSaveEntity);

        //更新外佣
        CustomGroupPointSaveEntity customGroupPointSaveEntity = new CustomGroupPointSaveEntity();
        customGroupPointSaveEntity.setGroupId(table.getId());
        customGroupPointSaveEntity.setPoints(entity.getComPoints());
        customGroupPointSaveEntity.setIp(entity.getAddIp());
        customGroupPointSaveEntity.setTime(entity.getAddTime());
        customGroupPointSaveEntity.setUserId(entity.getAddUser());
        customGroupPointService.save(customGroupPointSaveEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(CustomGroupUpdateEntity entity) throws Exception {
        /*
            获取原信息
         */
        CustomGroupTable table = customGroupRepository.findFirstById(entity.getId());
        if (table == null) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }
        /*
            验证组别标识是否唯一
         */
        if (!table.getCode().equals(entity.getCode())) {
            existByCode(entity.getCode());
        }
        /*
            修改信息
         */
        BeanUtils.copyProperties(entity, table);

        if (table.getRebateValid() == null) {
            table.setRebateValid(0);
        }

        if (table.getCommissionValid() == null) {
            table.setCommissionValid(0);
        }

        if (entity.getIntegralValid() == null) {
            entity.setIntegralValid(0);
        }

        if (entity.getSalesCommissionValid() == null) {
            entity.setSalesCommissionValid(0);
        }

        if (entity.getStorageValid() == null) {
            entity.setStorageValid(0);
        }

        if (entity.getPointValid() == null) {
            entity.setPointValid(0);
        }

        if (entity.getHideValid() == null) {
            entity.setHideValid(0);
        }

        customGroupRepository.save(table);
        //更新杠杆
        CustomGroupLeverageSaveEntity customGroupLeverageSaveEntity = new CustomGroupLeverageSaveEntity();
        customGroupLeverageSaveEntity.setGroupId(table.getId());
        customGroupLeverageSaveEntity.setLeverages(entity.getLeverages());
        customGroupLeverageSaveEntity.setIp(entity.getModifyIp());
        customGroupLeverageSaveEntity.setTime(entity.getModifyTime());
        customGroupLeverageSaveEntity.setUserId(entity.getModifyUser());
        customGroupLeverageService.save(customGroupLeverageSaveEntity);

        //更新暗点
        CustomGroupHideSaveEntity customGroupHideSaveEntity = new CustomGroupHideSaveEntity();
        customGroupHideSaveEntity.setGroupId(table.getId());
        customGroupHideSaveEntity.setHides(entity.getHides());
        customGroupHideSaveEntity.setIp(entity.getModifyIp());
        customGroupHideSaveEntity.setTime(entity.getModifyTime());
        customGroupHideSaveEntity.setUserId(entity.getModifyUser());
        customGroupHideService.save(customGroupHideSaveEntity);


        //更新外佣
        CustomGroupPointSaveEntity customGroupPointSaveEntity = new CustomGroupPointSaveEntity();
        customGroupPointSaveEntity.setGroupId(table.getId());
        customGroupPointSaveEntity.setPoints(entity.getComPoints());
        customGroupPointSaveEntity.setIp(entity.getModifyIp());
        customGroupPointSaveEntity.setTime(entity.getModifyTime());
        customGroupPointSaveEntity.setUserId(entity.getModifyUser());
        customGroupPointService.save(customGroupPointSaveEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) throws Exception {

        /*
            获取原信息
         */
        CustomGroupTable table = customGroupRepository.findFirstById(id);
        if (table == null) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }

        customGroupRepository.delete(table);
        customGroupLeverageService.delete(id);
        customGroupHideService.delete(id);
        customGroupPointService.delete(id);
    }

    @Override
    public CustomGroupDto getById(Long id) throws Exception {

        CustomGroupView view = customGroupDao.getOne(id);
        if (view == null) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }

        CustomGroupLeverageDto customGroupLeverageDto = customGroupLeverageService.getByGroupId(id);

        CustomGroupHideDto customGroupHideDto = customGroupHideService.getByGroupId(id);

        CustomGroupPointDto customGroupPointDto = customGroupPointService.getByGroupId(id);

        return copyFromView(view, customGroupLeverageDto, customGroupHideDto, customGroupPointDto);
    }

    @Override
    public BaseResultWithPagerDto<List<CustomGroupDto>> getList(CustomGroupListEntity entity) throws Exception {

        /*
            获取总数
         */
        Integer count = customGroupDao.countList(entity);
        PageDto pageDto = FormatPage.format(entity.getPage(), count);
        if (count <= 0) {
            if (count == null || count == 0) {
                return new BaseResultWithPagerDto(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto);
            }
        }
        /*
            获取列表
         */
        List<CustomGroupView> views = customGroupDao.getList(entity);
        List<Long> groupIds = new ArrayList<>(views.size());
        for (CustomGroupView customGroupView : views) {
            groupIds.add(customGroupView.getId());
        }
        List<CustomGroupLeverageDto> customGroupLeverageDtos = customGroupLeverageService.getByGroupIdIn(groupIds);
        List<CustomGroupHideDto> customGroupHideDtos = customGroupHideService.getByGroupIdIn(groupIds);
        List<CustomGroupPointDto> customGroupPointDtos = customGroupPointService.getByGroupIdIn(groupIds);
        List<CustomGroupDto> dtos = copyFromViews(views, customGroupLeverageDtos, customGroupHideDtos, customGroupPointDtos);

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

    @Override
    public BaseResultDto<List<String>> getList(CustomGroupPlatformListEntity customGroupPlatformListEntity) throws Exception {

        List<CustomGroupTable> tables;
        if (customGroupPlatformListEntity == null || Strings.isNullOrEmpty(customGroupPlatformListEntity.getPlatform())) {
            tables = customGroupRepository.findAll();
        } else {
            tables = customGroupRepository.getAllByPlatform(customGroupPlatformListEntity.getPlatform());
        }
        if (tables == null) {
            return BaseResultDto.success(null);
        }
        List<String> dtos = new ArrayList<>();
        tables.forEach((view) -> {
            dtos.add(view.getCode());
        });

        return BaseResultDto.success(dtos);
    }

    @Override
    public CustomGroupStaticDto getStaticData() throws Exception {

        CustomGroupStaticDto dto = new CustomGroupStaticDto();
        /*
            账户类型
         */
        List<AccountTypeTable> typeTables = accountTypeRepository.findAll();
        List<CustomTypeSelectDto> typeSelectDtos = Lists.newArrayList();
        typeTables.forEach((typeTable) -> {
            CustomTypeSelectDto selectDto = new CustomTypeSelectDto();
            selectDto.setId(typeTable.getId());
            selectDto.setName(typeTable.getName());
            typeSelectDtos.add(selectDto);
        });
        dto.setTypes(typeSelectDtos);
        /*
            仓位
         */
        List<SysPosSelectDto> posSelectDtos = Lists.newArrayList(new SysPosSelectDto(1, "A"), new SysPosSelectDto(2, "B"));
        dto.setPositions(posSelectDtos);
        /*
            外佣
         */
        List<AccountTypePointTable> pointTables = accountTypePointRepository.findAll();

        List<AccountTypeLeverageTable> accountTypeLeverageTables = accountTypeLeverageRepository.findAll();

        List<AccountTypeCurrencyTable> accountTypeCurrencyTables = accountTypeCurrencyRepository.findAll();

        List<AccountHideTable> accountHideTables = accountHideRepository.findAll();

        typeSelectDtos.forEach((type) -> {
            for (AccountTypePointTable pointTable : pointTables) {
                if (type.getId().equals(pointTable.getType())) {
                    List<CustomGroupCommissionSelectDto> selectDtos = null;
                    if ((selectDtos = type.getCommissions()) == null) {
                        selectDtos = Lists.newArrayList();
                        type.setCommissions(selectDtos);
                    }
                    CustomGroupCommissionSelectDto selectDto = new CustomGroupCommissionSelectDto();
                    selectDto.setId(pointTable.getPoint());
                    selectDto.setName(pointTable.getPoint());
                    selectDtos.add(selectDto);
                }
            }
            for (AccountTypeLeverageTable accountTypeLeverageTable : accountTypeLeverageTables) {
                if (type.getId().equals(accountTypeLeverageTable.getType())) {
                    List<CustomGroupLeverageSelectDto> selectDtos = null;
                    if ((selectDtos = type.getLeverages()) == null) {
                        selectDtos = Lists.newArrayList();
                        type.setLeverages(selectDtos);
                    }
                    CustomGroupLeverageSelectDto selectDto = new CustomGroupLeverageSelectDto();

                    selectDto.setLeverage(accountTypeLeverageTable.getLeverage());
                    selectDtos.add(selectDto);
                }
            }
            for (AccountTypeCurrencyTable accountTypeCurrencyTable : accountTypeCurrencyTables) {
                if (type.getId().equals(accountTypeCurrencyTable.getType())) {
                    List<CustomGroupCurrencySelectDto> selectDtos = null;
                    if ((selectDtos = type.getCurrents()) == null) {
                        selectDtos = Lists.newArrayList();
                        type.setCurrents(selectDtos);
                    }
                    CustomGroupCurrencySelectDto selectDto = new CustomGroupCurrencySelectDto();
                    selectDto.setCurrency(accountTypeCurrencyTable.getCurrency());
                    selectDtos.add(selectDto);
                }
            }

        });
        List<CustomGroupHideSelectDto> selectDtos = new ArrayList<>();
        for (AccountHideTable accountHideTable : accountHideTables) {
            CustomGroupHideSelectDto selectDto = new CustomGroupHideSelectDto();
            selectDto.setHide(accountHideTable.getHide());
            selectDtos.add(selectDto);
        }
        dto.setHides(selectDtos);

        return dto;
    }

    @Override
    public List<String> searchGroupList(String platform) throws Exception {

        return searchGroupList(platform,null);
    }

    @Override
    public List<String> searchGroupList(String platform, List<Long> types) throws Exception {
        List<CustomGroupTable> groupTables ;
        if (types == null) {
            groupTables=customGroupRepository.getAllByPlatform(platform);
        }else {
            groupTables=customGroupRepository.getAllByPlatformAndTypeIn(platform,types);
        }
        if (groupTables == null || groupTables.size() <= 0) {
            return null;
        }
        List<String> groups = new ArrayList<>(groupTables.size());
        for (CustomGroupTable groupTable : groupTables) {
            groups.add(groupTable.getCode());
        }
        return groups;
    }

    private CustomGroupDto copyFromView(CustomGroupView view, CustomGroupLeverageDto customGroupLeverageDto, CustomGroupHideDto customGroupHideDto, CustomGroupPointDto customGroupPointDto) {
        CustomGroupDto dto = new CustomGroupDto();
        BeanUtils.copyProperties(view, dto);
        dto.setPosName(TranslateUtil.posToName(dto.getPos()));
        if (customGroupLeverageDto != null) {
            dto.setLeverages(customGroupLeverageDto.getLeverages());
        }
        if (customGroupHideDto != null) {
            dto.setHides(customGroupHideDto.getHides());
        }
        if (customGroupPointDto != null) {
            dto.setComPoints(customGroupPointDto.getPoints());
        }
        dto.setRebateValidName(localeMessage.getMessage(TranslateUtil.rebateValidToName(dto.getRebateValid() == null ? 0 : dto.getRebateValid())));
        dto.setCommissionValidName(localeMessage.getMessage(TranslateUtil.commissionValidToName(dto.getCommissionValid() == null ? 0 : dto.getCommissionValid())));
        dto.setIntegralValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getIntegralValid() == null ? 0 : dto.getIntegralValid())));
        dto.setSalesCommissionValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getSalesCommissionValid() == null ? 0 : dto.getSalesCommissionValid())));
        dto.setStorageValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getStorageValid() == null ? 0 : dto.getStorageValid())));
        dto.setPointValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getPointValid() == null ? 0 : dto.getPointValid())));
        dto.setHideValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getHideValid() == null ? 0 : dto.getHideValid())));
        return dto;
    }

    private CustomGroupDto copyFromView(CustomGroupView view) {
        CustomGroupDto dto = new CustomGroupDto();
        BeanUtils.copyProperties(view, dto);
        dto.setPosName(TranslateUtil.posToName(dto.getPos()));
        dto.setRebateValidName(localeMessage.getMessage(TranslateUtil.rebateValidToName(dto.getRebateValid() == null ? 0 : dto.getRebateValid())));
        dto.setCommissionValidName(localeMessage.getMessage(TranslateUtil.commissionValidToName(dto.getCommissionValid() == null ? 0 : dto.getCommissionValid())));
        dto.setIntegralValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getIntegralValid() == null ? 0 : dto.getIntegralValid())));
        dto.setSalesCommissionValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getSalesCommissionValid() == null ? 0 : dto.getSalesCommissionValid())));
        dto.setStorageValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getStorageValid() == null ? 0 : dto.getStorageValid())));
        dto.setPointValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getPointValid() == null ? 0 : dto.getPointValid())));
        dto.setHideValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getHideValid() == null ? 0 : dto.getHideValid())));
        return dto;
    }

    private CustomGroupDto copyFromView(CustomGroupDto dto, CustomGroupLeverageDto customGroupLeverageDto) {
        if (customGroupLeverageDto != null) {
            dto.setLeverages(customGroupLeverageDto.getLeverages());
        }
        dto.setRebateValidName(localeMessage.getMessage(TranslateUtil.rebateValidToName(dto.getRebateValid() == null ? 0 : dto.getRebateValid())));
        dto.setCommissionValidName(localeMessage.getMessage(TranslateUtil.commissionValidToName(dto.getCommissionValid() == null ? 0 : dto.getCommissionValid())));
        dto.setIntegralValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getIntegralValid() == null ? 0 : dto.getIntegralValid())));
        dto.setStorageValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getStorageValid() == null ? 0 : dto.getStorageValid())));
        dto.setPointValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getPointValid() == null ? 0 : dto.getPointValid())));
        dto.setHideValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getHideValid() == null ? 0 : dto.getHideValid())));
        return dto;
    }

    private CustomGroupDto copyFromView(CustomGroupDto dto, CustomGroupHideDto customGroupHideDto) {
        if (customGroupHideDto != null) {
            dto.setHides(customGroupHideDto.getHides());
        }
        dto.setRebateValidName(localeMessage.getMessage(TranslateUtil.rebateValidToName(dto.getRebateValid() == null ? 0 : dto.getRebateValid())));
        dto.setCommissionValidName(localeMessage.getMessage(TranslateUtil.commissionValidToName(dto.getCommissionValid() == null ? 0 : dto.getCommissionValid())));
        dto.setIntegralValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getIntegralValid() == null ? 0 : dto.getIntegralValid())));
        dto.setStorageValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getStorageValid() == null ? 0 : dto.getStorageValid())));
        dto.setPointValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getPointValid() == null ? 0 : dto.getPointValid())));
        dto.setHideValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getHideValid() == null ? 0 : dto.getHideValid())));
        return dto;
    }

    private CustomGroupDto copyFromView(CustomGroupDto dto, CustomGroupPointDto customGroupHideDto) {
        if (customGroupHideDto != null) {
            dto.setComPoints(customGroupHideDto.getPoints());
        }
        dto.setRebateValidName(localeMessage.getMessage(TranslateUtil.rebateValidToName(dto.getRebateValid() == null ? 0 : dto.getRebateValid())));
        dto.setCommissionValidName(localeMessage.getMessage(TranslateUtil.commissionValidToName(dto.getCommissionValid() == null ? 0 : dto.getCommissionValid())));
        dto.setIntegralValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getIntegralValid() == null ? 0 : dto.getIntegralValid())));
        dto.setStorageValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getStorageValid() == null ? 0 : dto.getStorageValid())));
        dto.setPointValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getPointValid() == null ? 0 : dto.getPointValid())));
        dto.setHideValidName(localeMessage.getMessage(TranslateUtil.integralValidToName(dto.getHideValid() == null ? 0 : dto.getHideValid())));
        return dto;
    }

    private List<CustomGroupDto> copyFromViews(List<CustomGroupView> views, List<CustomGroupLeverageDto> customGroupLeverageDtos, List<CustomGroupHideDto> customGroupHideDtos, List<CustomGroupPointDto> customGroupPointDtos) {
        List<CustomGroupDto> customGroupDtos = new ArrayList<>(views.size());
        views.forEach(view -> {
            CustomGroupDto customGroupDto = copyFromView(view);

            customGroupLeverageDtos.forEach(dto -> {
                if (view.getId().equals(dto.getGroupId())) {
                    copyFromView(customGroupDto, dto);
                }
            });
            customGroupHideDtos.forEach(dto -> {
                if (view.getId().equals(dto.getGroupId())) {
                    copyFromView(customGroupDto, dto);
                }
            });
            customGroupPointDtos.forEach(dto -> {
                if (view.getId().equals(dto.getGroupId())) {
                    copyFromView(customGroupDto, dto);
                }
            });
            customGroupDtos.add(customGroupDto);
        });

        return customGroupDtos;
    }

    private void existByCode(String code) throws ServiceException {
        boolean bl = customGroupRepository.existsByCode(code);
        if (bl) {
            throw ServiceException.exception(ManagerConstant.CUSTOM_GROUP_CODE_IS_EXIST);
        }
    }
}
