package com.crm.custom.service.impl;

import com.crm.custom.dao.mapper.CustomLoginAssetManagementMapper;
import com.crm.custom.dao.repository.CustomLoginAssetManagementRepository;
import com.crm.custom.dao.repository.CustomLoginDemoRepository;
import com.crm.custom.dao.repository.CustomLoginFirmOfferRepository;
import com.crm.custom.service.*;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.StatusConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.CustomConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.dto.custom.login.CustomLoginAssetManagementDto;
import com.crm.rely.backend.model.dto.custom.login.CustomLoginConditionDto;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoUpdateAgentEntity;
import com.crm.rely.backend.model.entity.custom.login.CustomLoginCheckByLoginEntity;
import com.crm.rely.backend.model.entity.custom.login.asset.management.CustomLoginAssetManagementAddEntity;
import com.crm.rely.backend.model.entity.custom.login.asset.management.CustomLoginAssetManagementApproveEntity;
import com.crm.rely.backend.model.entity.custom.login.asset.management.CustomLoginAssetManagementSearchListEntity;
import com.crm.rely.backend.model.entity.custom.login.asset.management.CustomLoginAssetManagementUpdateCheckByLoginEntity;
import com.crm.rely.backend.model.pojo.table.CustomLoginAssetManagementTable;
import com.crm.rely.backend.model.pojo.table.CustomLoginDemoTable;
import com.crm.rely.backend.model.pojo.table.CustomLoginFirmOfferTable;
import com.crm.rely.backend.model.pojo.view.CustomLoginAssetManagementView;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.util.DateUtil;
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.math.BigDecimal;
import java.util.*;

@Service
public class CustomLoginAssetManagementServiceImpl implements CustomLoginAssetManagementService {

    @Autowired
    private CustomLoginAssetManagementRepository repository;

    @Autowired
    private CustomLoginAssetManagementMapper mapper;

    @Autowired
    private CustomInfoService customInfoService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private FinanceTrainFeignService financeTrainFeignService;

    @Autowired
    private WebVideoFeignService webVideoFeignService;

    @Autowired
    private CustomLoginService customLoginService;

    @Autowired
    private CustomLoginDemoRepository customLoginDemoRepository;

    @Autowired
    private CustomLoginFirmOfferRepository customLoginFirmOfferRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(CustomLoginAssetManagementAddEntity entity) throws ServiceException {
        existLogin(entity);
        CustomLoginAssetManagementTable customLoginAssetManagementTable = new CustomLoginAssetManagementTable();
        BeanUtils.copyProperties(entity, customLoginAssetManagementTable);
        customLoginAssetManagementTable.setStatus(StatusConstants.APPLY_PENDING_STATUS);
        repository.save(customLoginAssetManagementTable);
    }

    /**
     * 是否有在的账号或者成功的账号
     *
     * @param customId
     * @return
     * @throws ServiceException
     */
    @Override
    public boolean existAssetManagementStatus(Long customId) throws ServiceException {
        List<Integer> sts = new ArrayList<>(3);
        sts.add(StatusConstants.APPLY_PENDING_STATUS);
        sts.add(StatusConstants.APPLY_STATUS);
        sts.add(StatusConstants.PASSED_STATUS);
        return repository.existsByCustomIdAndStatusInAndSourceLoginIsNull(customId, sts);
    }

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

        CustomLoginAssetManagementTable table = repository.findFirstByLoginAndCustomId(entity.getLogin(), entity.getCustomId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        //如果不是放弃考核 则判断是否只读
        if (!StatusConstants.APPLY_ABANDON_STATUS.equals(entity.getStatus())) {
            CustomLoginAssetManagementView customLoginAssetManagementView = mapper.getOne(table.getId());

            if (customLoginAssetManagementView == null) {
                throw ServiceException.exception(Constants.INFO_NOT_FOUND);
            }

            if (!customLoginAssetManagementView.getEnableReadonly().equals(0)) {
                //如果是只读 则无权限
                throw ServiceException.exception(Constants.NOT_PERMIT);
            }
            table.setStatus(entity.getStatus());
        } else {
            table.setStatus(StatusConstants.APPLY_PENDING_STATUS);
        }


        repository.save(table);
        sendManager(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomLoginAssetManagementTable approve(CustomLoginAssetManagementApproveEntity entity) throws ServiceException {
        CustomLoginAssetManagementTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (!StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }

        BeanUtils.copyProperties(entity, table);

        //如果不是拒绝 则判断是否只读
        //不管同意拒绝 则判断是否只读
//        if (StatusConstants.REJECTED_STATUS.equals(entity.getStatus())) {
        CustomLoginAssetManagementView customLoginAssetManagementView = mapper.getOne(table.getId());

        if (customLoginAssetManagementView == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        if (customLoginAssetManagementView.getEnableReadonly().equals(0)) {
            //如果是非只读 状态重置为初始状态
            table.setStatus(StatusConstants.APPLY_PENDING_STATUS);
        }
//        }

        repository.save(table);

        //核验通过
        /*if (StatusConstants.PASSED_STATUS.equals(entity.getStatus())) {
            customInfoService.updateCnyAmountByCId(table.getCId(), entity.getAmount(),
                    "资管" + String.valueOf(table.getLogin()) + "核验通过发放");
        }*/
        return table;
    }


    @Override
    public CustomLoginConditionDto conditionAssetManagement(CustomLoginCheckByLoginEntity entity) throws Exception {

        BaseResultDto<Boolean> resultDto = financeTrainFeignService.validateLogin(entity);
        CustomLoginConditionDto dto = new CustomLoginConditionDto();
        dto.setTrainCondition((resultDto != null && resultDto.getData()) ? 1 : 0);

        boolean exist = customLoginService.existByCustomIdAndEquity(entity.getCustomId(), CustomConstants.CUSTOM_LOGIN_CONDITION);
        dto.setCustomLoginCondition(exist ? 1 : 0);
        dto.setLogin(entity.getLogin());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void studyAssetManagement(CustomLoginCheckByLoginEntity entity) throws Exception {
        CustomLoginAssetManagementTable table = repository.getFirstByLogin(entity.getLogin());
        if (table == null) {
            throw ServiceException.exception(Constants.FAIL);
        }
        //账号只有是拒绝的账号才能进行重新学习
        if (table.getSourceLogin() == null &&
                !StatusConstants.NOT_OPERATION_STATUS.equals(table.getStatus())) {
            CustomLoginConditionDto customLoginDemoConditionDto = conditionAssetManagement(entity);
            //这个账号条件都满足 则吧账号关闭 设置为不可操作状态
            if (customLoginDemoConditionDto != null && customLoginDemoConditionDto.getCustomLoginCondition() == 1 && customLoginDemoConditionDto.getTrainCondition() == 1) {
                table.setStatus(StatusConstants.NOT_OPERATION_STATUS);
                repository.save(table);

                List<CustomLoginDemoTable> tables =
                        customLoginDemoRepository.findAllByCustomIdAndStatus(table.getCustomId(),
                                StatusConstants.PASSED_STATUS);
                if (tables != null && tables.size() > 0) {
                    for (CustomLoginDemoTable customLoginDemoTable : tables) {
                        customLoginDemoTable.setStatus(StatusConstants.NOT_OPERATION_STATUS);
                    }
                    customLoginDemoRepository.save(tables);
                }

                List<CustomLoginFirmOfferTable> customLoginFirmOfferTables =
                        customLoginFirmOfferRepository.findAllByCustomIdAndStatus(table.getCustomId(),
                                StatusConstants.PASSED_STATUS);
                if (customLoginFirmOfferTables != null && customLoginFirmOfferTables.size() > 0) {
                    for (CustomLoginFirmOfferTable customLoginFirmOfferTable : customLoginFirmOfferTables) {
                        customLoginFirmOfferTable.setStatus(StatusConstants.NOT_OPERATION_STATUS);
                    }
                    customLoginFirmOfferRepository.save(customLoginFirmOfferTables);
                }

                customInfoService.updatePosition(table.getCustomId(), CustomConstants.POSITION1);
                BaseResultDto baseResultDto = webVideoFeignService.delete();
                if (baseResultDto == null) {
                    throw ServiceException.exception(Constants.SYSTEM_ERROR);
                }
                if (baseResultDto.getCode() != 200) {
                    throw ServiceException.exception(baseResultDto.getMsg());
                }
            } else {
                throw ServiceException.exception(Constants.NOT_PERMIT);
            }
        } else {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }
    }

    @Override
    public ResultWithPagerDto<CustomLoginAssetManagementDto> searchPageList(CustomLoginAssetManagementSearchListEntity entity) throws ServiceException {
        Integer count = mapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<CustomLoginAssetManagementDto> dtos = getDtos(entity);
        if (dtos == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }

        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    public CustomLoginAssetManagementTable getByLogin(Long login) throws ServiceException {
        CustomLoginAssetManagementTable table = repository.getFirstByLogin(login);
        if (table == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        return table;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAgentId(CustomInfoUpdateAgentEntity entity) throws ServiceException {
        List<CustomLoginAssetManagementTable> tables = repository.findAllByCustomId(entity.getId());
        if (tables != null && tables.size() > 0) {
            for (CustomLoginAssetManagementTable table : tables) {
                table.setAgentId(entity.getAgentId());
                table.setModifyIp(entity.getModifyIp());
                table.setModifyTime(entity.getModifyTime());
                table.setModifyUser(entity.getModifyUser());
            }
            repository.save(tables);
        }
    }

    private void sendManager(CustomLoginAssetManagementTable table) throws ServiceException {
        if (!StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
            return;
        }
        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.ASSET_MANAGEMENT_COMPLETE_MANAGER_EMAIL);
        if (sysConfigTable == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        String users = sysConfigTable.getValue();

        if (users == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(10);

        map.put(MapConstants.LOGIN, table.getLogin() + "");
        map.put(MapConstants.APPLY_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.LOGIN_TYPE, "资管");

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG DEPOSIT");
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.CHECK_COMPLETE_EMAIL);
        sysEmailSendEntity.setUsers(users);
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<CustomLoginAssetManagementDto> getDtos(CustomLoginAssetManagementSearchListEntity entity) throws ServiceException {
        List<CustomLoginAssetManagementView> views = mapper.pageList(entity);

        if (views == null || views.size() <= 0) {
            return null;
        }
        List<CustomLoginAssetManagementDto> dtos = new ArrayList<>(views.size());
        for (CustomLoginAssetManagementView view : views) {
            CustomLoginAssetManagementDto dto = transform(view);

            if (dto.getEquity() != null) {
                dto.setEquity(dto.getEquity().setScale(2,BigDecimal.ROUND_HALF_UP));
            }
            if (dto.getBalance() != null) {
                dto.setBalance(dto.getBalance().setScale(2,BigDecimal.ROUND_HALF_UP));
            }
            if (dto.getCredit() != null) {
                dto.setCredit(dto.getCredit().setScale(2,BigDecimal.ROUND_HALF_UP));
            }
            if (dto.getFloating() != null) {
                dto.setFloating(dto.getFloating().setScale(2,BigDecimal.ROUND_HALF_UP));
            }
            dtos.add(dto);
        }

        return dtos;
    }

    private CustomLoginAssetManagementDto transform(CustomLoginAssetManagementView table) {
        CustomLoginAssetManagementDto dto = new CustomLoginAssetManagementDto();
        BeanUtils.copyProperties(table, dto);

        return dto;
    }

    private void existLogin(CustomLoginAssetManagementAddEntity entity) throws ServiceException {
        boolean bl = repository.existsByLogin(entity.getLogin());
        if (bl) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
    }
}
