package com.jeeplus.test.reimbursementAccountant.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.DictUtils;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.reimbursementAccountant.domain.dto.AccountantReimbursementBusinessDTO;
import com.jeeplus.test.reimbursementAccountant.domain.dto.AccountantReimbursementBusinessReturnDTO;
import com.jeeplus.test.reimbursementAccountant.domain.dto.AccountantReimbursementUserDTO;
import com.jeeplus.test.reimbursementAccountant.mapper.AccountantReimbursementBusinessMapper;
import com.jeeplus.test.reimbursementAccountant.mapper.AccountantReimbursementUserMapper;
import com.jeeplus.test.reimbursementAccountant.service.AccountantReimbursementUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author li-peike
 * @version 1.0.0
 * @ClassName ReimbursementSysServiceImpl.java
 * @Description TODO
 * @createTime 2022年05月06日 10:38:00
 */
@Service
@Transactional(readOnly = true)
public class AccountantReimbursementUserServiceImpl implements AccountantReimbursementUserService {

    @Autowired
    private AccountantReimbursementUserMapper mapper;

    @Autowired
    private AccountantReimbursementBusinessMapper businessMapper;


    @Override
    public AccountantReimbursementUserDTO queryById(String id) {
        return mapper.queryById(id);
    }

    @Override
    public AccountantReimbursementUserDTO queryByUserIdAndYear(AccountantReimbursementUserDTO reimbursementUser) {
        return mapper.queryByUserIdAndYear(reimbursementUser);
    }


    @Override
    public IPage<AccountantReimbursementUserDTO> findList(Page<AccountantReimbursementUserDTO> page, AccountantReimbursementUserDTO reimbursementUser) {
        IPage<AccountantReimbursementUserDTO> pageList = mapper.findList(page, reimbursementUser);
        List<AccountantReimbursementUserDTO> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 保存
     * @param reimbursementUser
     */
    @Override
    @Transactional(readOnly = false)
    public Map<String,Object> save(AccountantReimbursementUserDTO reimbursementUser) {
        Map<String,Object> map = new HashMap<>();

        if(StringUtils.isBlank(reimbursementUser.getUserId())){
            map.put("success", false);
            map.put("message", "报销人员为空，无法进行添加报销信息!");
            return map;
        }
        if(StringUtils.isBlank(reimbursementUser.getYear())){
            map.put("success", false);
            map.put("message", "报销年份不正确，请重新填写!");
            return map;
        }

        if(StringUtils.isBlank(reimbursementUser.getReimbursementQuotaDay())){
            map.put("success", false);
            map.put("message", "日报销额度填写不正确!");
            return map;
        }
        if(null == reimbursementUser.getReimbursementAllDay()){
            map.put("success", false);
            map.put("message", "年可报销天数填写不正确!");
            return map;
        }
        //日报销额度
        BigDecimal reimbursementQuotaDay = new BigDecimal(reimbursementUser.getReimbursementQuotaDay());
        //年可报销天数
        BigDecimal reimbursementAllDay = new BigDecimal(reimbursementUser.getReimbursementAllDay());

        //计算并赋值年报销额度
        reimbursementUser.setReimbursementQuota(reimbursementQuotaDay.multiply(reimbursementAllDay).toString());

        UserDTO user = UserUtils.get(reimbursementUser.getUserId());
        if(StringUtils.isNotBlank(reimbursementUser.getId())){
            reimbursementUser.preUpdate();
            //新增
            mapper.update(reimbursementUser);
        }else{
            //查询该用户该年度是否已经添加报销额度
            AccountantReimbursementUserDTO queryByUserIdAndYear = mapper.queryByUserIdAndYear(reimbursementUser);
            if(null != queryByUserIdAndYear){
                map.put("success", false);
                map.put("message", user.getName() + " " + reimbursementUser.getYear() + "年度报销额度已添加，无法重复添加！");
                return map;
            }
            reimbursementUser.preInsert();
            //新增
            mapper.save(reimbursementUser);
        }

        map.put("success", true);
        map.put("message", user.getName() + " " + reimbursementUser.getYear() + "年度报销额度：" + reimbursementUser.getReimbursementQuota() +" 保存成功");
        return map;
    }


    @Override
    @Transactional(readOnly = false)
    public void update(AccountantReimbursementUserDTO reimbursementUser) {
        mapper.update(reimbursementUser);
    }

    @Override
    @Transactional(readOnly = false)
    public Map<String,Object> delete(List<String> idList) {
        Map<String,Object> map = new HashMap<>();
        List<String> userName = Lists.newArrayList();
        //删除发票信息
        //判断该人员该年度是否已经存在报销情况，如存在则不可以删除
        //根据id集合查询人员信息
        for (String id: idList) {
            AccountantReimbursementUserDTO reimbursementUserDTO = mapper.queryById(id);
            AccountantReimbursementBusinessDTO reimbursementBusiness = new AccountantReimbursementBusinessDTO();
            reimbursementBusiness.setUserId(reimbursementUserDTO.getUserId());
            reimbursementBusiness.setYear(reimbursementUserDTO.getYear());
            List<AccountantReimbursementBusinessDTO> list = businessMapper.findListByUserIdAndYear(reimbursementBusiness);
            if(list.size()>0){
                userName.add(reimbursementUserDTO.getUser().getName());
            }
        }
        if(userName.size()>0){
            map.put("success",false);
            String userNames = StringUtils.join(userName, "、");
            map.put("message", "员工 " + userNames + " 存在已报销情况，本次删除失败");
        }else{
            mapper.delete(idList);
            map.put("success",true);
            map.put("message", "删除成功");
        }
        return map;
    }

    @Override
    public AccountantReimbursementBusinessReturnDTO findListByUserId(AccountantReimbursementUserDTO reimbursementUserDTO) {
        AccountantReimbursementBusinessDTO reimbursementBusiness = new AccountantReimbursementBusinessDTO();
        reimbursementBusiness.setUserId(reimbursementUserDTO.getUserId());
        reimbursementBusiness.setYear(reimbursementUserDTO.getYear());
        AccountantReimbursementBusinessReturnDTO reimbursementBusinessReturnDTO = new AccountantReimbursementBusinessReturnDTO();
        List<AccountantReimbursementBusinessDTO> list = businessMapper.findListByUserIdAndYear(reimbursementBusiness);

        //获取人员年度报销详情
        AccountantReimbursementUserDTO reimbursementUserInfo = mapper.queryByUserIdAndYear(reimbursementUserDTO);
        reimbursementBusinessReturnDTO.setList(list);
        reimbursementBusinessReturnDTO.setReimbursementQuota(reimbursementUserInfo.getReimbursementQuota());

        //已报销额度
        BigDecimal alreadyReimbursementAmount = new BigDecimal("0");
        //已报销天数
        BigDecimal alreadyReimbursementDay = new BigDecimal("0");

        for (AccountantReimbursementBusinessDTO info : list) {
            BigDecimal bigDecimal = new BigDecimal(info.getReimbursementAmount());
            alreadyReimbursementAmount = alreadyReimbursementAmount.add(bigDecimal);
            if("1".equals(info.getReimbursementType())){
                alreadyReimbursementDay = alreadyReimbursementDay.add(new BigDecimal(info.getReimbursementDay()));
            }
            info.setReimbursementType(DictUtils.getDictLabel(info.getReimbursementType(), "reimbursement_type", null));
        }
        //剩余报销额度
        reimbursementBusinessReturnDTO.setSurplusReimbursementAmount(new BigDecimal(reimbursementBusinessReturnDTO.getReimbursementQuota()).subtract(alreadyReimbursementAmount).toString());
        //计算出可报销总天数
        BigDecimal reimbursementDay = new BigDecimal("0");
        if(null == reimbursementUserInfo.getReimbursementAllDay()){
            reimbursementDay = new BigDecimal(reimbursementBusinessReturnDTO.getReimbursementQuota()).divide(new BigDecimal(reimbursementUserInfo.getReimbursementQuotaDay()),2, BigDecimal.ROUND_HALF_UP);
        }else{
            reimbursementDay = new BigDecimal(reimbursementUserInfo.getReimbursementAllDay());
        }

        //剩余报销天数
        reimbursementBusinessReturnDTO.setSurplusReimbursementDay(reimbursementDay.subtract(alreadyReimbursementDay).toString());
        //报销天数
        reimbursementBusinessReturnDTO.setReimbursementDay(reimbursementDay.toString());
        //已报销天数
        reimbursementBusinessReturnDTO.setAlreadyReimbursementDay(alreadyReimbursementDay.toString());
        //已报销额度
        reimbursementBusinessReturnDTO.setAlreadyReimbursementAmount(alreadyReimbursementAmount.toString());
        //日报销额度
        reimbursementBusinessReturnDTO.setReimbursementQuotaDay(reimbursementUserInfo.getReimbursementQuotaDay());

        return reimbursementBusinessReturnDTO;
    }

    @Override
    public List<UserDTO> getUserByNameAndOfficeName(AccountantReimbursementUserDTO reimbursementUserDTO) {
        return mapper.getUserByNameAndOfficeName(reimbursementUserDTO);
    }

    @Override
    @Transactional(readOnly = false)
    public Map<String, Object> saveList(List<AccountantReimbursementUserDTO> reimbursementUserList) {

        List<AccountantReimbursementUserDTO> saveList = Lists.newArrayList();
        List<AccountantReimbursementUserDTO> existList = Lists.newArrayList();
        StringBuilder failureMsg = new StringBuilder ( );

        Map<String,Object> map = new HashMap<>();
        Map<String, List<AccountantReimbursementUserDTO>> stringListMap = dataDispose(reimbursementUserList);
        if(reimbursementUserList.size() != stringListMap.size()){
            map.put("success", false);
            map.put("message", "报销人员中存在重复项，无法进行导入!");
            return map;
        }


        for (AccountantReimbursementUserDTO reimbursementUser: reimbursementUserList) {
            if(StringUtils.isBlank(reimbursementUser.getYear())){
                map.put("success", false);
                map.put("message", reimbursementUser.getUserName() + " 的报销年份不正确，请重新填写!");
                return map;
            }
            if(StringUtils.isBlank(reimbursementUser.getReimbursementQuotaDay())){
                map.put("success", false);
                map.put("message", reimbursementUser.getUserName() + " 的日报销额度填写不正确!");
                return map;
            }
            if(null == reimbursementUser.getReimbursementAllDay()){
                map.put("success", false);
                map.put("message", reimbursementUser.getUserName() + " 的年可报销天数填写不正确!");
                return map;
            }
            //日报销额度
            BigDecimal reimbursementQuotaDay = new BigDecimal(reimbursementUser.getReimbursementQuotaDay());
            //年可报销天数
            BigDecimal reimbursementAllDay = new BigDecimal(reimbursementUser.getReimbursementAllDay());

            //计算并赋值年报销额度
            reimbursementUser.setReimbursementQuota(reimbursementQuotaDay.multiply(reimbursementAllDay).toString());

            //根据用户id和年份查询报数员工库表中是否存在数据
            //如果有，则将其从list列表中剔除
            AccountantReimbursementUserDTO reimbursementUserDTOS = mapper.queryByUserIdAndYear(reimbursementUser);
            if(null != reimbursementUserDTOS){
                existList.add(reimbursementUser);
            }else{
                reimbursementUser.preInsert();
                saveList.add(reimbursementUser);
            }

        }


        //新增
        if(saveList.size()>0){
            mapper.saveList(saveList);
        }

        if(existList.size()>0){
            for (AccountantReimbursementUserDTO user : existList) {
                failureMsg.append ( "。 " + user.getOfficeName() + " 部门下的员工 " + user.getUserName() + " 已添加，无法再次添加;" );
            }
        }

        map.put("success", true);
        map.put("saveCount", saveList.size());
        map.put("message", failureMsg);

        return map;
    }


    /**
     * 文件数据分组
     * @param dataList
     * @return
     */
    public Map<String, List<AccountantReimbursementUserDTO>> dataDispose(List<AccountantReimbursementUserDTO> dataList) {
        Map<String, List<AccountantReimbursementUserDTO>> result = listMap(dataList);
        return result;
    }

    private Map<String, List<AccountantReimbursementUserDTO>> listMap(List<AccountantReimbursementUserDTO> list) {
        Map<String, List<AccountantReimbursementUserDTO>> userSignSerialMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            // 分组
            for (AccountantReimbursementUserDTO vo : list) {
                List<AccountantReimbursementUserDTO> tempList = userSignSerialMap.get(vo.getKeyFlag());
                /*如果取不到数据,那么直接new一个空的ArrayList**/
                if (tempList == null) {
                    tempList = new ArrayList<>();
                    tempList.add(vo);
                    userSignSerialMap.put(vo.getKeyFlag(), tempList);
                }
                else {
                    /*某个vo之前已经存放过了,则直接追加数据到原来的List里**/
                    tempList.add(vo);
                }
            }
        }
        return userSignSerialMap;
    }

}
