package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.CreditUser;
import com.ruoyi.system.domain.InterestsNumberTable;
import com.ruoyi.system.mapper.CreditUserMapper;
import com.ruoyi.system.mapper.InterestsNumberTableMapper;
import com.ruoyi.system.mapper.UsageRecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.PolicyMenuMapper;
import com.ruoyi.common.core.domain.entity.PolicyMenu;
import com.ruoyi.system.service.IPolicyMenuService;

/**
 * 政策类别Service业务层处理
 *
 * @author boman
 * @date 2022-06-10
 */
@Service
public class PolicyMenuServiceImpl implements IPolicyMenuService {
    @Autowired
    private PolicyMenuMapper policyMenuMapper;
    @Autowired
    private CreditUserMapper creditUserMapper;
    @Autowired
    private InterestsNumberTableMapper interestsNumberTableMapper;
    @Autowired
    private UsageRecordMapper usageRecordMapper;

    /**
     * 查询政策类别
     *
     * @param menuId 政策类别主键
     * @return 政策类别
     */
    @Override
    public PolicyMenu selectPolicyMenuByMenuId(Long menuId) {
        return policyMenuMapper.selectPolicyMenuByMenuId(menuId);
    }

    /**
     * 查询政策类别列表
     *
     * @param policyMenu 政策类别
     * @return 政策类别
     */
    @Override
    public List<PolicyMenu> selectPolicyMenuList(PolicyMenu policyMenu) {
        return policyMenuMapper.selectPolicyMenuList(policyMenu);
    }

    /**
     * 新增政策类别
     *
     * @param policyMenu 政策类别
     * @return 结果
     */
    @Override
    public int insertPolicyMenu(PolicyMenu policyMenu) {

        //判断是否有上级类别
        Long parentId = policyMenu.getParentId();
        if (parentId != null && parentId > 0) {
            PolicyMenu menu = policyMenuMapper.selectPolicyMenuByMenuId(policyMenu.getParentId());
            // 如果父节点不为正常状态,则不允许新增子节点
            if (!UserConstants.DEPT_NORMAL.equals(menu.getStatus())) {
                throw new ServiceException("部门停用，不允许新增");
            }
            policyMenu.setAncestors(menu.getAncestors() + "," + menu.getParentId());
        }else {
            policyMenu.setAncestors("0");
            policyMenu.setParentId(0L);
        }
        policyMenu.setCreateTime(DateUtils.getNowDate());
        return policyMenuMapper.insertPolicyMenu(policyMenu);
    }

    /**
     * 修改政策类别
     *
     * @param policyMenu 政策类别
     * @return 结果
     */
    @Override
    public int updatePolicyMenu(PolicyMenu policyMenu) {

        PolicyMenu newPolicyMenu = policyMenuMapper.selectPolicyMenuByMenuId(policyMenu.getParentId());
        PolicyMenu oldPolicyMenu = policyMenuMapper.selectPolicyMenuByMenuId(policyMenu.getMenuId());
        if (StringUtils.isNotNull(newPolicyMenu) && StringUtils.isNotNull(oldPolicyMenu))
        {
            String newAncestors = newPolicyMenu.getAncestors() + "," + newPolicyMenu.getMenuId();
            String oldAncestors = oldPolicyMenu.getAncestors();
            policyMenu.setAncestors(newAncestors);
            updateMenuChildren(policyMenu.getMenuId(), newAncestors, oldAncestors);
        }
        int result = policyMenuMapper.updatePolicyMenu(policyMenu);
        if (UserConstants.DEPT_NORMAL.equals(policyMenu.getStatus()) && StringUtils.isNotEmpty(policyMenu.getAncestors())
                && !StringUtils.equals("0", policyMenu.getAncestors()))
        {
            // 如果该类别是启用状态，则启用该类别的所有上级类别
            updateParentMenuStatusNormal(policyMenu);
        }
        policyMenu.setUpdateTime(DateUtils.getNowDate());
        return policyMenuMapper.updatePolicyMenu(policyMenu);
    }

    /**
     * 修改该类别的父级部门状态
     *
     * @param policyMenu 当前类别
     */
    private void updateParentMenuStatusNormal(PolicyMenu policyMenu)
    {
        String ancestors = policyMenu.getAncestors();
        Long[] deptIds = Convert.toLongArray(ancestors);
        policyMenuMapper.updateMenuStatusNormal(deptIds);
    }

    /**
     * 修改子元素关系
     *
     * @param menuId 被修改的类别ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateMenuChildren(Long menuId, String newAncestors, String oldAncestors)
    {
        List<PolicyMenu> children = policyMenuMapper.selectChildrenMenuById(menuId);
        for (PolicyMenu child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            policyMenuMapper.updateMenuChildren(children);
        }
    }

    /**
     * 批量删除政策类别
     *
     * @param menuIds 需要删除的政策类别主键
     * @return 结果
     */
    @Override
    public int deletePolicyMenuByMenuIds(Long[] menuIds) {
        return policyMenuMapper.deletePolicyMenuByMenuIds(menuIds);
    }

    /**
     * 删除政策类别信息
     *
     * @param menuId 政策类别主键
     * @return 结果
     */
    @Override
    public int deletePolicyMenuByMenuId(Long menuId) {
        return policyMenuMapper.deletePolicyMenuByMenuId(menuId);
    }

    /**
     * 查询政策类别管理数据
     *
     * @param policyMenu
     * @return
     */
    @Override
    public List<PolicyMenu> selectMenusList(PolicyMenu policyMenu) {
        return policyMenuMapper.selectPolicyMenuList(policyMenu);
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param policyMenu 政策类别列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildMenuTreeSelect(List<PolicyMenu> policyMenu) {
        List<PolicyMenu> menuTrees = buildDeptTree(policyMenu);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 校验政策类别名称
     *
     * @param policyMenu
     * @return
     */
    @Override
    public String checkMenuNameUnique(PolicyMenu policyMenu) {
        Long menuId = StringUtils.isNull(policyMenu.getMenuId()) ? -1L : policyMenu.getMenuId();
        PolicyMenu info = policyMenuMapper.checkMenuNameUnique(policyMenu.getMenuName(), policyMenu.getParentId());
        if (StringUtils.isNotNull(info) && info.getMenuId() != null && info.getMenuId().longValue() != menuId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 根据ID查询所有子部门（正常状态）
     *
     * @param menuId 部门ID
     * @return 子部门数
     */
    @Override
    public int selectNormalChildrenMenuById(Long menuId) {
        return policyMenuMapper.selectNormalChildrenMenuById(menuId);
    }

    @Override
    public AjaxResult listApp(String idCard) {
        //查询信用人员
        CreditUser creditUser = new CreditUser();
        creditUser.setIdCard(idCard);
        creditUser = creditUserMapper.selectCreditUser(creditUser);

        //获取政策列表
        List<PolicyMenu> policyMenus =  policyMenuMapper.selectPolicyMenuList(new PolicyMenu());
        //获取所有子集
        List<PolicyMenu> policyMenuZs = new ArrayList<>();
        for (PolicyMenu policyMenu : policyMenus) {
            if(policyMenu.getParentId() != 0){
                policyMenuZs.add(policyMenu);
            }
        }
        List<Map<String,Object>> maps = new ArrayList<>();

        for (PolicyMenu policyMenuZ : policyMenuZs) {
            Map<String,Object> map = new HashMap<>();
            //二级标题类别id
            map.put("menuId",policyMenuZ.getMenuId());
            //人员信用等级
            map.put("creditLevel",creditUser.getCreditLevel());

            //二级标题
            map.put("twoTitle",policyMenuZ.getMenuName());
            //有效期限
            map.put("validTerm",DateUtils.getCurrentYear()+"-12-31");

            for (PolicyMenu policyMenu : policyMenus) {
                //一及列表
                if(policyMenuZ.getParentId().equals(policyMenu.getMenuId())){
                    map.put("oneTitle",policyMenu.getMenuName());
                    break;
                }
            }
            //查询次数
            InterestsNumberTable interestsNumberTable = interestsNumberTableMapper.selectInterestsNumberTableByPolicyId(policyMenuZ.getMenuId(),creditUser.getCreditLevel());
            if(interestsNumberTable!=null){
                if(interestsNumberTable.getNumber()!=null && interestsNumberTable.getNumber()!=0){
                    map.put("total",interestsNumberTable.getNumber());
                    //查询该用户已在该商家使用次数（按年来查询）
                    String year =DateUtils.getCurrentYear();
                    int count = usageRecordMapper.selectUsageRecordByRecordNum(creditUser.getPhoneNum(),interestsNumberTable.getInterestsId(),year);
                    map.put("remaining",interestsNumberTable.getNumber()-count);
                }else{
                    map.put("total","无限次");
                    map.put("remaining","无限次");
                }
            }else{
                map.put("total","无限次");
                map.put("remaining","无限次");
            }
            maps.add(map);
        }

        return AjaxResult.success("操作成功 ",maps);
    }


    /**
     * 构建前端所需要树结构
     *
     * @param policyMenus 政策类别列表
     * @return 树结构列表
     */
    public List<PolicyMenu> buildDeptTree(List<PolicyMenu> policyMenus) {
        List<PolicyMenu> returnList = new ArrayList<PolicyMenu>();
        List<Long> tempList = new ArrayList<Long>();
        for (PolicyMenu menu : policyMenus) {
            tempList.add(menu.getMenuId());
        }
        for (PolicyMenu menu : policyMenus) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(policyMenus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty()) {
            returnList = policyMenus;
        }
        return returnList;
    }


    /**
     * 递归列表
     */
    private void recursionFn(List<PolicyMenu> list, PolicyMenu t) {
        // 得到子节点列表
        List<PolicyMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (PolicyMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<PolicyMenu> getChildList(List<PolicyMenu> list, PolicyMenu t) {
        List<PolicyMenu> tlist = new ArrayList<PolicyMenu>();
        Iterator<PolicyMenu> it = list.iterator();
        while (it.hasNext()) {
            PolicyMenu n = (PolicyMenu) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<PolicyMenu> list, PolicyMenu t) {
        return getChildList(list, t).size() > 0;
    }
}
