package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.CustomGroupDemoMapper;
import com.crm.manager.dao.repository.AccountTypeCurrencyRepository;
import com.crm.manager.dao.repository.AccountTypeLeverageRepository;
import com.crm.manager.dao.repository.AccountTypeRepository;
import com.crm.manager.dao.repository.CustomGroupDemoRepository;
import com.crm.manager.service.CustomGroupDemoLeverageService;
import com.crm.manager.service.CustomGroupDemoService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.ManagerConstant;
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.demo.CustomGroupDemoDto;
import com.crm.rely.backend.core.dto.custom.group.demo.CustomGroupDemoStaticDto;
import com.crm.rely.backend.core.dto.custom.group.leverage.CustomGroupLeverageDto;
import com.crm.rely.backend.core.dto.custom.type.CustomDemoTypeSelectDto;
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.demo.CustomGroupDemoAddEntity;
import com.crm.rely.backend.core.entity.custom.group.demo.CustomGroupDemoListEntity;
import com.crm.rely.backend.core.entity.custom.group.demo.CustomGroupDemoUpdateEntity;
import com.crm.rely.backend.core.entity.custom.group.leverage.CustomGroupLeverageSaveEntity;
import com.crm.rely.backend.core.pojo.table.*;
import com.crm.rely.backend.core.pojo.view.CustomGroupDemoView;
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.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;
import java.util.concurrent.atomic.AtomicBoolean;

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

    @Autowired
    private CustomGroupDemoRepository customGroupDemoRepository;
    @Autowired
    private CustomGroupDemoMapper customGroupDemoMapper;

    @Autowired
    private CustomGroupDemoLeverageService customGroupDemoLeverageService;
    @Autowired
    private AccountTypeRepository accountTypeRepository;

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

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

        CustomGroupDemoTable table = new CustomGroupDemoTable();
        BeanUtils.copyProperties(entity, table);
        customGroupDemoRepository.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());
        customGroupDemoLeverageService.save(customGroupLeverageSaveEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(CustomGroupDemoUpdateEntity entity) throws Exception {
        /*
            获取原信息
         */
        CustomGroupDemoTable table = customGroupDemoRepository.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);
        customGroupDemoRepository.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());
        customGroupDemoLeverageService.save(customGroupLeverageSaveEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) throws Exception {
        /*
            获取原信息
         */
        CustomGroupDemoTable table = customGroupDemoRepository.findFirstById(id);
        if (table == null) {
            throw new ServiceException(Constants.INFO_NOT_FOUND);
        }

        customGroupDemoRepository.delete(id);
        customGroupDemoLeverageService.delete(id);
    }

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

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

        CustomGroupLeverageDto customGroupLeverageDto = customGroupDemoLeverageService.getByGroupId(id);

        return transfer(view, customGroupLeverageDto);
    }

    @Override
    public BaseResultWithPagerDto<List<CustomGroupDemoDto>> getList(CustomGroupDemoListEntity entity) throws Exception {

        /*
            获取总数
         */
        Integer count = customGroupDemoMapper.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<CustomGroupDemoView> views = customGroupDemoMapper.getList(entity);
        List<Long> groupIds = new ArrayList<>(views.size());
        for (CustomGroupDemoView customGroupDemoView : views) {
            groupIds.add(customGroupDemoView.getId());
        }
        List<CustomGroupLeverageDto> customGroupLeverageDtos = customGroupDemoLeverageService.getByGroupIdIn(groupIds);
        List<CustomGroupDemoDto> dtos = transfers(views, customGroupLeverageDtos);


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

    @Override
    public CustomGroupDemoStaticDto getStaticData() throws Exception {

        CustomGroupDemoStaticDto dto = new CustomGroupDemoStaticDto();
        /*
            账户类型
         */
        List<AccountTypeTable> typeTables = accountTypeRepository.findAll();
        List<CustomDemoTypeSelectDto> typeSelectDtos = Lists.newArrayList();
        typeTables.forEach((typeTable) -> {
            CustomDemoTypeSelectDto selectDto = new CustomDemoTypeSelectDto();
            selectDto.setId(typeTable.getId());
            selectDto.setName(typeTable.getName());
            typeSelectDtos.add(selectDto);
        });
        dto.setTypes(typeSelectDtos);

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

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

        typeSelectDtos.forEach((type) -> {

            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);
                }
            }

        });

        return dto;
    }

    private CustomGroupDemoDto transfer(CustomGroupDemoView customGroupDemoView, CustomGroupLeverageDto customGroupLeverageDto) {
        CustomGroupDemoDto dto = new CustomGroupDemoDto();
        BeanUtils.copyProperties(customGroupDemoView, dto);

        if (customGroupLeverageDto != null) {
            dto.setLeverages(customGroupLeverageDto.getLeverages());
        }
        return dto;
    }

    private List<CustomGroupDemoDto> transfers(List<CustomGroupDemoView> views, List<CustomGroupLeverageDto> customGroupLeverageDtos) {
        List<CustomGroupDemoDto> customGroupDemoDtos = new ArrayList<>(views.size());
        views.forEach(view -> {
            AtomicBoolean isAdd = new AtomicBoolean(false);
            customGroupLeverageDtos.forEach(dto -> {
                if (view.getId().equals(dto.getGroupId())) {
                    CustomGroupDemoDto customGroupDto = transfer(view, dto);
                    customGroupDemoDtos.add(customGroupDto);
                    isAdd.set(true);
                }
            });
            if (!isAdd.get()) {
                CustomGroupDemoDto customGroupDemoDto = transfer(view, null);
                customGroupDemoDtos.add(customGroupDemoDto);
            }
        });

        return customGroupDemoDtos;
    }

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