/*
 *      Copyright (c) 2018-2028, Chill Zhuang 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 dreamlu.net 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: Chill 庄骞 (smallchill@163.com)
 */
package org.security.trans.basic.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.security.system.cache.SysCache;
import org.security.system.entity.Dept;
import org.security.trans.basic.dto.DepartmentDTO;
import org.security.ht.entity.basic.Department;
import org.security.trans.basic.mapper.DepartmentMapper;
import org.security.trans.basic.service.IDepartmentService;
import org.security.ht.vo.basic.DepartmentVO;
import org.security.ht.vo.basic.DeptDataVO;
import org.security.ht.vo.basic.MapDeptDataVO;
import org.security.ht.vo.basic.RoleDataVO;
import org.security.trans.common.service.IFileService;
import org.security.ht.vo.common.UploadVO;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.node.ForestNodeMerger;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 基础信息-组织机构 服务实现类
 *
 * @author BladeX
 * @since 2022-03-07
 */
@Service
@AllArgsConstructor
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {

	private final IFileService fileService;

	@Override
	public IPage<DepartmentVO> selectDepartmentPage(IPage<DepartmentVO> page, DepartmentVO department) {
		return page.setRecords(baseMapper.selectDepartmentPage(page, department));
	}

	@Override
	public List<DepartmentVO> lazyList(Map<String, Object> param, String parentId) {
		String PARENT_ID = "parentId";
		// 判断点击搜索但是没有查询条件的情况
		if (Func.isEmpty(param.get(PARENT_ID)) && param.size() == 1) {
			parentId = "0";
		}
		// 判断数据权限控制,非超管角色只可看到本级及以下数据
		if (Func.toLong(parentId) == 0L && !AuthUtil.isAdministrator()) {
			Long deptId = Func.firstLong(AuthUtil.getDeptId());
			Dept dept = SysCache.getDept(deptId);
			if (dept.getParentId() != 0) {
				parentId = String.valueOf(dept.getParentId());
			}
		}
		// 判断点击搜索带有查询条件的情况
		if (Func.isEmpty(param.get(PARENT_ID)) && param.size() > 1 && Func.toLong(parentId) == 0L) {
			parentId = null;
		}
		List<DepartmentVO> list = baseMapper.lazyList(parentId, param);
		List<DepartmentVO> collect = list.stream().peek(dept -> {
		}).collect(Collectors.toList());
		return ForestNodeMerger.merge(collect);
	}

	@Override
	public List<DepartmentVO> lazyListForTask(Map<String, Object> param, String parentId) {
		List<DepartmentVO> list = baseMapper.lazyListForTask(parentId, param);
		List<DepartmentVO> collect = list.stream().peek(dept -> {
		}).collect(Collectors.toList());
		return ForestNodeMerger.merge(collect);
	}

	@Override
	public DeptDataVO getDepartmentById(Long id) {
		Department department = this.getById(id);
		DeptDataVO deptDataVO = Func.copy(department, DeptDataVO.class);
//		查询上级机构名称
		Long rootParentId = new Long(0);
		deptDataVO.setParentName(Func.isNotEmpty(department.getParentId()) && !rootParentId.equals(department.getParentId())?this.getById(department.getParentId()).getDeptName():"");
		//获取相关附件
		List<UploadVO> attachments = fileService.getAttachments(String.valueOf(id), department.getGroupName());
		assert deptDataVO != null;
		deptDataVO.setDeptDisList(attachments);
		return deptDataVO;
	}

	@Override
	public List<DepartmentVO> cascadeSelection() {
		String deptId = AuthUtil.getDeptId();
		List<DepartmentVO> departmentVOList = this.baseMapper.cascade(deptId);
		return ForestNodeMerger.merge(departmentVOList);
	}

	@Override
	public List<DepartmentVO> tree(DepartmentDTO departmentDTO) {
		//地图页面跳转到机构列表获取相关数据
		if (Func.isNotEmpty(departmentDTO.getId())) {
			ArrayList<DepartmentVO> list = new ArrayList<>();
			Department department = this.getById(departmentDTO.getId());
			DepartmentVO departmentVO = Func.copy(department, DepartmentVO.class);
			list.add(departmentVO);
			return list;
		}
		String deptId = AuthUtil.getDeptId();
		String id;
		if (StringUtils.isNotBlank(departmentDTO.getDeptLevel()) || StringUtils.isNotBlank(departmentDTO.getDeptName())) {
			id = null;
		} else {
			id = deptId;
		}
		QueryWrapper<Department> beforeQueryWrapper = new QueryWrapper<>();
		beforeQueryWrapper.lambda().like(Department::getAncestors, deptId);
		List<Department> childrenList = this.list(beforeQueryWrapper);
		QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
		if ((StringUtils.isNotBlank(departmentDTO.getDeptLevel()) || StringUtils.isNotBlank(departmentDTO.getDeptName())) && childrenList.isEmpty()) {
			queryWrapper.lambda()
				.eq(Department::getId, deptId);
		} else {
			queryWrapper.lambda()
				.eq(StringUtils.isNotBlank(id), Department::getId, id)
				.or()
				.like(Department::getAncestors, deptId);
		}
		queryWrapper.lambda()
			.eq(StringUtils.isNotBlank(departmentDTO.getDeptLevel()), Department::getDeptLevel, departmentDTO.getDeptLevel())
			.like(StringUtils.isNotBlank(departmentDTO.getDeptName()), Department::getDeptName, departmentDTO.getDeptName());
		List<Department> departmentList = this.list(queryWrapper);
		List<DepartmentVO> voList = Func.copy(departmentList, DepartmentVO.class);
		return ForestNodeMerger.merge(voList);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateDeptData(DepartmentDTO departmentDTO) {
		Department department = Func.copy(departmentDTO, Department.class);
		//保存机构信息
		boolean b1 = this.updateById(department);
		//将机构相关照片保存到附件表
		fileService.saveAttachments(departmentDTO.getDeptDisList(), String.valueOf(department.getId()));
		return b1;
	}

	@Override
	public List<RoleDataVO> getData(String deptId) {
		return baseMapper.getData(deptId);
	}

	@Override
	public List<DepartmentVO> getChildDeptTree(String topDeptId) {
		List<DepartmentVO> departmentVOList = this.baseMapper.cascade(topDeptId);
		return ForestNodeMerger.merge(departmentVOList);
	}

	@Override
	public List<MapDeptDataVO> getDeptMapDetail() {
		ArrayList<MapDeptDataVO> vos = new ArrayList<>();
		List<Department> list = this.list();
		//筛选出经纬度都不为空的相关机构信息
		List<Department> collect = list.stream().filter(item -> Func.isNotEmpty(item.getLongitude()) && Func.isNotEmpty(item.getLatitude())).collect(Collectors.toList());
		if (Func.isNotEmpty(collect)) {
			collect.forEach(item -> {
				MapDeptDataVO dataVO = new MapDeptDataVO();
				dataVO.setId(String.valueOf(item.getId()));
				dataVO.setDeptName(item.getDeptName());
				dataVO.setCoordinate(item.getLongitude().concat(",").concat(item.getLatitude()));
				dataVO.setLongitude(item.getLongitude());
				dataVO.setLatitude(item.getLatitude());
				dataVO.setCategory(item.getDeptCategory());
				vos.add(dataVO);
			});
		}
		return vos;
	}

	@Override
	public boolean saveDepartmentData(List<Department> departmentList) {
		return this.saveOrUpdateBatch(departmentList);
	}

	@Override
	public List<DepartmentVO> getSelfBankData() {
		return baseMapper.getSelfBankData(AuthUtil.getDeptId());
	}

	@Override
	public List<Department> getBudgetDept() {
		return this.list(new QueryWrapper<Department>().lambda().eq(Department::getDeptCategory,"6"));
	}

	@Override
	public R addSelfBank(DepartmentDTO departmentDTO) {
		if (Func.isEmpty(departmentDTO.getParentId())) {
			return R.fail("请务必选择所属网点");
		}
		if (Func.isEmpty(departmentDTO.getDeptCategory())) {
			departmentDTO.setDeptCategory("4");
		}
		//赋值祖级id
		List<String> list = setAncestors(departmentDTO);
		departmentDTO.setAncestors(org.apache.commons.lang.StringUtils.join(list, ","));
		Department department = Func.copy(departmentDTO, Department.class);
		super.save(department);
		//将机构相关照片保存到附件表
		fileService.saveAttachments(departmentDTO.getDeptDisList(), String.valueOf(department.getId()));
		return R.success("操作成功");
	}

	/**
	 *赋值祖级id
	 */
	private List<String> setAncestors(DepartmentDTO departmentDTO) {
		List<String> list = new ArrayList<>();
		String aimDeptId = String.valueOf(departmentDTO.getParentId());
		while (true) {
			if (Func.isNotEmpty(aimDeptId) && !("0".equals(aimDeptId))) {
				Department department = this.getById(aimDeptId);
				list.add(String.valueOf(department.getParentId()));
				aimDeptId = String.valueOf(department.getParentId());
			} else {
				break;
			}
		}
		list.add(0, "0");
		list.add(1, String.valueOf(departmentDTO.getParentId()));
		return list;
	}
}
