/*
 *
 *      Copyright (c) 2018-2025, avenue All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the pig4cloud.com developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: avenue
 *
 */

package com.emergency.avenue.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emergency.avenue.admin.api.entity.SysDept;
import com.emergency.avenue.admin.api.entity.SysDeptRelation;
import com.emergency.avenue.admin.api.entity.SysTreeDict;
import com.emergency.avenue.admin.mapper.SysDeptMapper;
import com.emergency.avenue.admin.service.SysDeptRelationService;
import com.emergency.avenue.admin.service.SysDeptService;
import com.emergency.avenue.common.data.datascope.DataScope;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门管理 服务实现类
 * </p>
 *
 * @author avenue
 * @since 2018-01-20
 */
@Service
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

	private final SysDeptRelationService sysDeptRelationService;

	private final SysDeptMapper deptMapper;

	/**
	 * 添加信息部门
	 *
	 * @param dept 部门
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveDept(SysDept dept) {
		SysDept sysDept = new SysDept();
		BeanUtils.copyProperties(dept, sysDept);
		this.save(sysDept);
		sysDeptRelationService.insertDeptRelation(sysDept);
		return Boolean.TRUE;
	}

	/**
	 * 删除部门
	 *
	 * @param id 部门 ID
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeDeptById(String id) {
		// 级联删除部门
		List<String> idList = sysDeptRelationService
				.list(Wrappers.<SysDeptRelation>query().lambda().eq(SysDeptRelation::getAncestor, id)).stream()
				.map(SysDeptRelation::getDescendant).collect(Collectors.toList());

		if (CollUtil.isNotEmpty(idList)) {
			this.removeByIds(idList);
		}

		// 删除部门级联关系
		sysDeptRelationService.deleteAllDeptRealtion(id);
		return Boolean.TRUE;
	}

	/**
	 * 更新部门
	 *
	 * @param sysDept 部门信息
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateDeptById(SysDept sysDept) {
		// 更新部门状态
		this.updateById(sysDept);
		// 更新部门关系
		SysDeptRelation relation = new SysDeptRelation();
		relation.setAncestor(sysDept.getParentId());
		relation.setDescendant(sysDept.getDeptId());
		sysDeptRelationService.updateDeptRealtion(relation);
		return Boolean.TRUE;
	}

	/**
	 * 查询全部部门树
	 *
	 * @param deptName
	 * @return 树 部门名称
	 */
	@Override
	public List<Tree<String>> selectTree(String deptName) {
		// 查询全部部门
		List<SysDept> deptAllList = deptMapper.selectList(
				Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
		// 查询数据权限内部门
		Map<String, SysDept> deptOwnIdList = deptMapper.selectListByScope(
				Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
				DataScope.of()).stream().collect(Collectors.toMap(SysDept::getDeptId, d -> d, (p1, p2) -> p2));

		// 权限内部门
		List<TreeNode<String>> collect = deptAllList.stream()
				.filter(dept -> !dept.getDeptId().equals(dept.getParentId()))
				.sorted(Comparator.comparingInt(SysDept::getSortOrder)).map(dept -> {
					TreeNode<String> treeNode = new TreeNode();
					treeNode.setId(dept.getDeptId());
					treeNode.setParentId(dept.getParentId());
					treeNode.setName(dept.getName());
					treeNode.setWeight(dept.getSortOrder());
					// 有权限不返回标识
					Map<String, Object> extra = new HashMap<>(8);
					extra.put("isLock", deptOwnIdList.get(dept.getDeptId()) != null);
					extra.put("createTime", dept.getCreateTime());
					extra.put("deptType", dept.getDeptType());
					extra.put("delFlag", dept.getDelFlag());
					extra.put("longitude", dept.getLongitude());
					extra.put("dimension", dept.getDimension());
					extra.put("abbreviationName", dept.getAbbreviationName());
					extra.put("warehouseType", dept.getWarehouseType());
					treeNode.setExtra(extra);
					return treeNode;
				}).collect(Collectors.toList());

		// 模糊查询 不组装树结构 直接返回 表格方便编辑
		if (StrUtil.isNotBlank(deptName)) {
			return collect.stream().map(node -> {
				Tree<String> tree = new Tree<>();
				tree.putAll(node.getExtra());
				BeanUtils.copyProperties(node, tree);
				return tree;
			}).collect(Collectors.toList());
		}

		List<TreeNode<String>> treeList = collect.stream().filter(treeNode -> treeNode.getExtra().get("isLock").toString().equals("true")).collect(Collectors.toList());;

		BigDecimal minValue = treeList.stream()
				.map(entity -> new BigDecimal(entity.getParentId())) // 根据实际情况调整字段名称
				.min(Comparator.naturalOrder())
				.orElseThrow(() -> new IllegalStateException("No elements found in the list"));
		return TreeUtil.build(treeList, minValue.toString());
	}

}
