package com.mortals.xhx.module.site.service.impl;

import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.SatusEnum;
import com.mortals.xhx.module.site.dao.ISiteCustomDao;
import com.mortals.xhx.module.site.dao.SiteDao;
import com.mortals.xhx.module.site.model.SiteEntity;
import com.mortals.xhx.module.site.model.SiteQuery;
import com.mortals.xhx.module.site.model.TreeSelect;
import com.mortals.xhx.module.site.service.SiteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * <p>Title: 站点信息表</p>
 * <p>Description: SiteService service接口 </p>
 * <p>Copyright: Copyright &reg;  </p>
 *
 * @version 1.0.0
 */
@Service("siteService")
public class SiteServiceImpl extends AbstractCRUDServiceImpl<SiteDao, SiteEntity, Long> implements SiteService {

    @Autowired
    private ISiteCustomDao siteCustomDao;

    @Autowired
    private UserService userService;


    @Override
    protected void validData(SiteEntity entity, Context context) throws AppException {

        //校验站点名称是否存在 todo
        super.validData(entity, context);
    }

    @Override
    protected void saveBefore(SiteEntity entity, Context context) throws AppException {

        SiteEntity parentSiteEntity = this.get(entity.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!ObjectUtils.isEmpty(parentSiteEntity) && SatusEnum.DISENABLE.getValue() == parentSiteEntity.getStatus()) {
            throw new AppException("站点停用，不允许新增");
        }

        if (!ObjectUtils.isEmpty(parentSiteEntity)) {
            entity.setAncestors(parentSiteEntity.getAncestors() + "," + entity.getParentId());
        }

        super.saveBefore(entity, context);
    }


    @Override
    protected void updateBefore(SiteEntity entity, Context context) throws AppException {
        super.updateBefore(entity, context);

        SiteEntity newParentDept = this.get(entity.getParentId());
        SiteEntity oldDept = this.get(entity.getId());

        if (!ObjectUtils.isEmpty(newParentDept) && !ObjectUtils.isEmpty(oldDept)) {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getId();
            String oldAncestors = oldDept.getAncestors();
            entity.setAncestors(newAncestors);
            updateDeptChildren(entity.getId(), newAncestors, oldAncestors, context);
        }


    }

    @Override
    protected void updateAfter(SiteEntity entity, Context context) throws AppException {
        super.updateAfter(entity, context);

        if (SatusEnum.ENABLE.getValue() == entity.getStatus()) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatus(entity, context);
        }
    }

    /**
     * 修改该部门的父级部门状态
     *
     * @param dept 当前部门
     */
    private void updateParentDeptStatus(SiteEntity dept, Context context) {
        SiteEntity siteEntity = this.get(dept.getParentId());

        siteEntity.setStatus(SatusEnum.ENABLE.getValue());
        siteEntity.setUpdateTime(new Date());
        siteEntity.setUpdateUser(context.getUser().getLoginName());
        SiteEntity condition = new SiteEntity();
        condition.setId(siteEntity.getId());
        this.updateBatch(siteEntity, condition, context);
    }

    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors, Context context) {

        HashMap<String, String> map = new HashMap<>();
        map.put("siteId", deptId.toString());

        List<SiteEntity> children = siteCustomDao.selectChildrenSiteById(map);

        for (SiteEntity child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            this.updateAfter(children, context);
            //  deptMapper.updateDeptChildren(children);
        }


    }


    @Override
    protected void removeBefore(Long[] ids, Context context) throws AppException {
        //有子节点 禁止删除
        if (hasChildBySiteId(ids[0])) {
            throw new AppException("存在下级站点,不允许删除");
        }
        if (checkSiteExistUser(ids[0])) {

            throw new AppException("站点存在用户,不允许删除");
        }
        super.removeBefore(ids, context);
    }

    @Override
    public boolean hasChildBySiteId(Long siteId) {
        List<SiteEntity> siteEntities = this.find(new SiteQuery().parentId(siteId));
        return siteEntities.size() > 0 ? true : false;
    }

    @Override
    public boolean checkSiteExistUser(Long siteId) {
        List<UserEntity> userEntities = userService.find(new UserQuery().siteId(siteId));
        return userEntities.size() > 0 ? true : false;
    }

    @Override
    public List<SiteEntity> selectSiteList(SiteEntity site) {
        return this.find(new SiteQuery());
    }

    @Override
    public List<TreeSelect> buildSiteTreeSelect(List<SiteEntity> sites) {
        List<SiteEntity> returnList = new ArrayList<>();
        List<Long> tempList = sites.stream().map(SiteEntity::getId).collect(Collectors.toList());

        for (Iterator<SiteEntity> iterator = sites.iterator(); iterator.hasNext(); ) {
            SiteEntity siteEntity = iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(siteEntity.getParentId())) {
                recursionFn(sites, siteEntity);
                returnList.add(siteEntity);
            }
        }
        if (returnList.isEmpty()) {
            returnList = sites;
        }

        return returnList.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

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

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

    /**
     * 得到子节点列表
     */
    private List<SiteEntity> getChildList(List<SiteEntity> list, SiteEntity t) {
        return list.stream().map(item->{
            if (!ObjectUtils.isEmpty(item.getParentId()) && item.getParentId() == t.getId()) {
                return item;
            }
            return null;
        }).filter(f->f!=null).collect(Collectors.toList());
    }

}