/*
 * Copyright (c) 2020 yifu4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yifu.cloud.plus.v1.yifu.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import com.yifu.cloud.plus.v1.yifu.admin.api.dto.UserDTO;
import com.yifu.cloud.plus.v1.yifu.admin.api.dto.UserInfo;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.*;
import com.yifu.cloud.plus.v1.yifu.admin.service.SysUserService;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.MsgUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog;
import com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * @author lengleng
 * @date 2019/2/1
 */
@Tag(name="用户管理模块",description = "用户管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {

	private final SysUserService userService;

	/**
	 * 获取当前用户全部信息
	 * @return 用户信息
	 */
	@Operation(summary = "获取当前用户全部信息", description = "获取当前用户全部信息")
	@GetMapping(value = { "/info" })
	public R<UserInfoVO> info() {
		String username = SecurityUtils.getUser().getUsername();
		SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
		if (user == null) {
			return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));
		}
		UserInfo userInfo = userService.getUserInfo(user);
		UserInfoVO vo = new UserInfoVO();
		vo.setSysUser(userInfo.getSysUser());
		vo.setRoles(userInfo.getRoles());
		vo.setPermissions(userInfo.getPermissions());
		return R.ok(vo);
	}

	/**
	 * 获取指定用户全部信息
	 * @return 用户信息
	 */
	@Inner
	@GetMapping("/info/{username}")
	public R<UserInfo> info(@PathVariable String username) {
		SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
		if (user == null) {
			return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, username));
		}
		return R.ok(userService.getUserInfo(user));
	}

	@GetMapping("/getInfoByUsername")
	public UserInfo infoAPI(@RequestParam(required = true,name = "username") String username) {
		SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
		return userService.getUserInfo(user);
	}

	/**
	 * 根据部门id，查询对应的用户 id 集合
	 * @param deptIds 部门id 集合
	 * @return 用户 id 集合
	 */
	@Inner
	@GetMapping("/ids")
	public R<List<Long>> listUserIdByDeptIds(@RequestParam("deptIds") Set<Long> deptIds) {
		return R.ok(userService.listUserIdByDeptIds(deptIds));
	}

	/**
	 * 通过ID查询用户信息
	 * @param id ID
	 * @return 用户信息
	 */
	@GetMapping("/{id}")
	public R<UserVO> user1(@PathVariable String id) {
		return R.ok(userService.getUserVoById(id));
	}

	/**
	 * 根据用户名查询用户信息
	 * @param username 用户名
	 * @return
	 */
	@GetMapping("/details/{username}")
	public R<SysUser> user(@PathVariable String username) {
		SysUser condition = new SysUser();
		condition.setUsername(username);
		return R.ok(userService.getOne(new QueryWrapper<>(condition)));
	}

	/**
	 * 删除用户信息
	 * @param id ID
	 * @return R
	 */
	@SysLog("删除用户信息")
	@DeleteMapping("/{id:\\d+}")
	@PreAuthorize("@pms.hasPermission('sys_user_del')")
	public R<Boolean> userDel(@PathVariable Long id) {
		SysUser sysUser = userService.getById(id);
		if (null == sysUser){
			return R.failed(Boolean.FALSE);
		}
		return R.ok(userService.removeUserById(sysUser));
	}

	/**
	 * 添加用户
	 * @param userDto 用户信息
	 * @return success/false
	 */
	@SysLog("添加用户")
	@PostMapping
	@PreAuthorize("@pms.hasPermission('sys_user_add')")
	public R<Boolean> user(@RequestBody UserDTO userDto) {
		return R.ok(userService.saveUser(userDto));
	}

	/**
	 * 更新用户信息
	 * @param userDto 用户信息
	 * @return R
	 */
	@SysLog("更新用户信息")
	@PutMapping
	@PreAuthorize("@pms.hasPermission('sys_user_edit')")
	public R<Boolean> updateUser(@Valid @RequestBody UserDTO userDto) {
		return R.ok(userService.updateUser(userDto));
	}

	/**
	 * 分页查询用户
	 * @param page 参数集
	 * @param userDTO 查询参数列表
	 * @return 用户集合
	 */
	@GetMapping("/page")
	public R<IPage<List<UserVO>>> getUserPage(Page page, UserDTO userDTO) {
		return R.ok(userService.getUserWithRolePage(page, userDTO));
	}

	/**
	 * 修改个人信息
	 * @param userDto userDto
	 * @return success/false
	 */
	@SysLog("修改个人信息")
	@PutMapping("/edit")
	public R<Boolean> updateUserInfo(@Valid @RequestBody UserDTO userDto) {
		return R.ok(userService.updateUserInfo(userDto));
	}

	/**
	 * @param username 用户名称
	 * @return 上级部门用户列表
	 */
	@GetMapping("/ancestor/{username}")
	public R<List<SysUser>> listAncestorUsers(@PathVariable String username) {
		return R.ok(userService.listAncestorUsersByUsername(username));
	}

	/**
	 * 导出excel 表格
	 * @param userDTO 查询条件
	 * @return
	 */
	@ResponseExcel
	@GetMapping("/export")
	@PreAuthorize("@pms.hasPermission('sys_user_import_export')")
	public List<UserExcelVO> export(UserDTO userDTO) {
		return userService.listUser(userDTO);
	}

	/**
	 * 导入用户
	 * @param excelVOList 用户列表
	 * @param bindingResult 错误信息列表
	 * @return R
	 */
	@PostMapping("/import")
	@PreAuthorize("@pms.hasPermission('sys_user_import_export')")
	public R importUser(@RequestExcel List<UserExcelVO> excelVOList, BindingResult bindingResult) {
		return userService.importUser(excelVOList, bindingResult);
	}

	/**
	 * 从ldap中获取用户
	 * @return R
	 */
	@SysLog("从ldap中获取用户")
	@PostMapping("/updateUser")
	public R updateByLdap() {
		return R.ok(userService.updateByLdap());
	}

	/**
	 * 从ldap中获取用户
	 * @return R
	 */
	@SysLog("从ldap中获取用户")
	@PostMapping("/inner/updateUser")
	@Inner
	public R innerUpdateByLdap() {
		return R.ok(userService.updateByLdap());
	}

	/**
	 * 从ldap中验证登录用户
	 * @return R
	 */
	@SysLog("登录验证")
	@PostMapping("/ldapLogin")
	public R<Boolean> loginAuthentication(@RequestParam String userName,@RequestParam String password) throws NoSuchAlgorithmException {
		return userService.loginAuthentication(userName,password);
	}

	/**
	 * 获取对象基本信息
	 *
	 * @param id
	 * @Author fxj
	 * @Date 2022-07-11 16:42
	 **/
	@Inner
	@GetMapping("/getSimpleUser/{id}")
	public SysUser getSimpleUser(@PathVariable Integer id) {
		return userService.getById(id);
	}

	/**
	 * @Author fxj
	 * @Description 获取所有用户极
	 * @Date 18:20 2022/8/16
	 * @Param
	 * @return
	**/
	@Inner
	@PostMapping(value = {"/inner/getAllUserName"})
	public AllUserNaVo getAllUserDTO() {
		AllUserNaVo naVo = new AllUserNaVo();
		List<SysUser> sysUsers = userService.list(Wrappers.<SysUser>query().lambda());
		if (Common.isNotEmpty(sysUsers)){
			HashMap<String,String> nameMap = new HashMap<>();
			for (SysUser u:sysUsers){
				nameMap.put(u.getUserId(),u.getNickname());
			}
			naVo.setUserNames(nameMap);
		}
		return naVo;
	}
	/**
	 * @Author fxj
	 * @Description 获取所有用户-- 指定用户名
	 * @Date 18:20 2022/8/16
	 * @Param
	 * @return
	 **/
	@Inner
	@PostMapping(value = {"/inner/getUserIdsByUserNames"})
	public SysUserListVo getUserIdsByUserNames(@RequestBody String  usernames) {
		SysUserListVo naVo = new SysUserListVo();
		if (Common.isEmpty(usernames)){
			return naVo;
		}
		List<SysUser> sysUsers = userService.list(Wrappers.<SysUser>query().lambda()
				.in(SysUser::getUsername,Common.getList(usernames)));
		if (Common.isNotEmpty(sysUsers)){
			List<String> userIds = new ArrayList<>();
			for (SysUser u:sysUsers){
				userIds.add(u.getUserId());
			}
			naVo.setUserIds(userIds);
			naVo.setUserList(sysUsers);
		}
		return naVo;
	}
	/**
	 * @Author hgw
	 * @Description 获取部门下的用户id
	 * @Date 2022-9-14 11:29:59
	**/
	@Inner
	@PostMapping(value = {"/inner/getUserIdByDeptIds"})
	public String getUserIdByDeptIds(@RequestBody String deptIds) {
		StringBuilder userIds = new StringBuilder("'0'");
		if (Common.isNotNull(deptIds)) {
			List<String> list = Common.initStrToList(deptIds, ",");
			List<SysUser> sysUsers = userService.list(Wrappers.<SysUser>query().lambda().in(SysUser::getDeptId, list));
			if (Common.isNotEmpty(sysUsers)){
				for (SysUser u:sysUsers){
					userIds.append(",'").append(u.getUserId()).append("'");
				}
			}
		}
		return userIds.toString();
	}

	/**
	 * @Author hgw
	 * @Description 获取部门下的用户id
	 * @Date 2022-9-14 11:29:59
	 **/
	@Inner
	@PostMapping(value = {"/inner/getUserNamedByDeptIds"})
	public String getUserNameByDeptIds(@RequestBody String deptIds) {
		StringBuilder userIds = new StringBuilder("'0'");
		if (Common.isNotNull(deptIds)) {
			List<String> list = Common.initStrToList(deptIds, ",");
			List<SysUser> sysUsers = userService.list(Wrappers.<SysUser>query().lambda().in(SysUser::getDeptId, list));
			if (Common.isNotEmpty(sysUsers)){
				for (SysUser u:sysUsers){
					userIds.append(",'").append(u.getUsername()).append("'");
				}
			}
		}
		return userIds.toString();
	}

	/**
	 * @param nickName 用户名称
	 * @return 上级部门用户列表
	 */
	@GetMapping("/getSysUserList")
	@Operation(summary = "获取所有系统人员", description = "获取所有系统人员")
	public R<List<SysUser>> getSysUserList(@RequestParam(required = false) String nickName) {
		List<SysUser> sysUserList;
		if (Common.isNotNull(nickName)) {
			sysUserList = userService.list(Wrappers.<SysUser>query().lambda().like(SysUser::getNickname, nickName));
		} else {
			sysUserList = userService.list();
		}
		return R.ok(sysUserList);
	}

}
