package com.crm.custom.service.impl;

import com.crm.custom.dao.mapper.CustomLoginMapper;
import com.crm.custom.dao.repository.CustomLoginRepository;
import com.crm.custom.service.AccountApplyAssetManagementService;
import com.crm.custom.service.CustomInfoService;
import com.crm.custom.service.CustomLoginService;
import com.crm.custom.service.SysConfigService;
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.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.exception.ServiceException;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.dto.custom.login.CustomLoginDto;
import com.crm.rely.backend.model.entity.account.apply.asset.management.AccountApplyAssetManagementAddEntity;
import com.crm.rely.backend.model.entity.custom.CustomLoginUpdateAssessmentByLoginEntity;
import com.crm.rely.backend.model.entity.custom.CustomLoginUpdateCheckByLoginEntity;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoUpdateAgentEntity;
import com.crm.rely.backend.model.entity.custom.login.CustomLoginApproveEntity;
import com.crm.rely.backend.model.entity.custom.login.CustomLoginSearchListEntity;
import com.crm.rely.backend.model.pojo.table.CustomLoginTable;
import com.crm.rely.backend.model.pojo.view.CustomLoginView;
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 CustomLoginServiceImpl implements CustomLoginService {

    @Autowired
    private CustomLoginRepository repository;

    @Autowired
    private CustomLoginMapper mapper;

    @Autowired
    private CustomInfoService customInfoService;

    @Autowired
    private AccountApplyAssetManagementService accountApplyAssetManagementService;


    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private EmailService emailService;

    @Override
    public boolean existByCustomIdAndEquity(Long customId, BigDecimal equity) throws ServiceException {
        int count = mapper.existByCustomIdAndEquity(customId, equity);
        return count > 0 ? true : false;
    }

    @Override
    public CustomLoginView getByLogin(Long login) throws ServiceException {
        return mapper.getByLogin(login);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Long login, Integer valid) throws ServiceException {
        CustomLoginTable table = repository.findFirstByLogin(login);
        if (table != null) {
            table.setValid(valid);
            table.setLoginStatus(StatusConstants.MANAGER_PENDING_STATUS);
        }
    }

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

        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void abandonAssessment(CustomLoginUpdateAssessmentByLoginEntity entity) throws ServiceException {
        CustomLoginTable table = repository.findFirstByLoginAndCustomId(entity.getLogin(), entity.getCustomId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        if (StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception("核验评定中,无权限");
        }
        //放弃考核
        table.setStartTime(null);
        table.setEndTime(null);
        table.setStatus(StatusConstants.APPLY_PENDING_STATUS);
        repository.save(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assessment(CustomLoginUpdateAssessmentByLoginEntity entity) throws ServiceException {
        CustomLoginTable table = repository.findFirstByLoginAndCustomId(entity.getLogin(), entity.getCustomId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        CustomLoginView customLoginView = mapper.getByLogin(entity.getLogin());
        if (customLoginView.getEquity() == null || customLoginView.getEquity().compareTo(new BigDecimal(2000)) < 0) {
            throw ServiceException.exception("净值不足2000,无权限申请考核");
        }
        if (table.getStartTime() == null && table.getEndTime() == null) {
            table.setStartTime(new Date());
            //加一个月
            table.setEndTime(DateUtil.operationMoth(table.getStartTime(), 1));
            table.setStatus(StatusConstants.APPLY_PENDING_STATUS);
        } else {

            throw ServiceException.exception("考核期内,无权限");
        }
        repository.save(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyCheck(CustomLoginUpdateCheckByLoginEntity entity) throws ServiceException {
        CustomLoginTable table = repository.findFirstByLoginAndCustomId(entity.getLogin(), entity.getCustomId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        //如果是申请考核
        if (StatusConstants.APPLY_STATUS.equals(entity.getStatus())) {
//            //判断状态是否为初始状态
//            if (!StatusConstants.APPLY_PENDING_STATUS.equals(table.getStatus())) {
//                throw ServiceException.exception(Constants.NOT_PERMIT);
//            }
            if (table.getStartTime() == null || table.getEndTime() == null) {
                throw ServiceException.exception("未开始考核,无权限申请核验");
            }
            if (table.getEndTime().getTime() > System.currentTimeMillis()) {
                throw ServiceException.exception("考核期内,无权限申请核验");
            }

        }
        //如果放弃考核
        else if (StatusConstants.APPLY_ABANDON_STATUS.equals(entity.getStatus())) {
            //判断状态是否为申请中
            if (StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
                throw ServiceException.exception(Constants.NOT_PERMIT);
            }
            //放弃核验
            table.setStartTime(null);
            table.setEndTime(null);
        }
        table.setStatus(entity.getStatus());
        repository.save(table);
        if (StatusConstants.APPLY_STATUS.equals(entity.getStatus())) {
            sendManager(table);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomLoginTable approve(CustomLoginApproveEntity entity) throws ServiceException {
        CustomLoginTable 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);
        //不管通过拒绝 考核结束 时间置空
        table.setStartTime(null);
        table.setEndTime(null);
        repository.save(table);


        //如果审核通过 注册资管账户
        if (StatusConstants.PASSED_STATUS.equals(table.getStatus())) {

            AccountApplyAssetManagementAddEntity accountApplyAssetManagementAddEntity =
                    new AccountApplyAssetManagementAddEntity();
            accountApplyAssetManagementAddEntity.setCustomId(table.getCustomId());
            accountApplyAssetManagementAddEntity.setAgentId(table.getAgentId());
            accountApplyAssetManagementAddEntity.setCId(table.getCId());
            accountApplyAssetManagementAddEntity.setBalance(entity.getBalance());
            accountApplyAssetManagementAddEntity.setSourceLogin(table.getLogin());

            accountApplyAssetManagementService.addAccountApply(accountApplyAssetManagementAddEntity);

        }
        return table;
    }

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

    @Override
    public Integer countByCustomId(Long customId) throws ServiceException {

        return repository.countByCustomId(customId);
    }

    private List<CustomLoginDto> getDtos(CustomLoginSearchListEntity entity) throws ServiceException {
        List<CustomLoginView> views = mapper.pageList(entity);

        if (views == null || views.size() <= 0) {
            return null;
        }
        List<CustomLoginDto> dtos = new ArrayList<>(views.size());
        for (CustomLoginView view : views) {
            CustomLoginDto dto = transform(view);
            if (view.getEndTime() == null) {
                dto.setAssessmentStatus(0);
            }
            if (view.getEndTime() != null) {
                if (view.getEndTime().getTime() < System.currentTimeMillis()) {
                    dto.setAssessmentStatus(2);
                } else {
                    dto.setAssessmentStatus(1);
                }
            }

            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 CustomLoginDto transform(CustomLoginView table) {
        CustomLoginDto dto = new CustomLoginDto();
        BeanUtils.copyProperties(table, dto);

        return dto;
    }

    private void sendManager(CustomLoginTable table) throws ServiceException {
        if (!StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
            return;
        }
        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.REAL_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();
        }
    }
}
