package com.hotent.uc.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.hotent.base.datasource.DatabaseContext;
import com.hotent.base.enums.ResponseErrorEnums;
import com.hotent.base.exception.BaseException;
import com.hotent.base.query.*;
import com.hotent.base.util.FieldConvertUtil;
import com.hotent.orgext.controller.OrgAuthExtController;
import com.hotent.orgext.manager.OrgAuthExtManager;
import com.hotent.uc.manager.OrgManager;
import com.hotent.uc.model.Org;
import com.hotent.uc.model.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotent.base.annotation.ApiGroup;
import com.hotent.base.annotation.DataPermission;
import com.hotent.base.constants.ApiGroupConsts;
import com.hotent.base.controller.BaseController;
import com.hotent.base.model.CommonResult;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.StringUtil;
import com.hotent.uc.manager.RoleManager;
import com.hotent.uc.manager.UserManager;
import com.hotent.uc.manager.UserRoleManager;
import com.hotent.uc.model.Role;
import com.hotent.uc.model.User;
import com.hotent.uc.params.role.RoleVo;
import com.hotent.uc.params.user.UserVo;
import com.hotent.uc.util.OrgUtil;
import com.hotent.uc.util.UpdateMethod;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 角色组织模块接口
 * @author zhangxw
 *
 */
@RestController
@RequestMapping("/api/role/v1/")
@Api(tags="角色管理")
@ApiGroup(group= {ApiGroupConsts.GROUP_UC})
public class RoleController extends BaseController<RoleManager, Role> {
	
	@Resource
	RoleManager roleService;
	@Autowired
	UserManager userService;
	@Autowired
	UserRoleManager userRoleService;
	@Autowired
	DatabaseContext databaseContext;
	@Autowired
	OrgAuthExtController orgAuthExtController;
	@Resource
	OrgManager orgManager;
	@Resource
	OrgAuthExtManager orgAuthExtManager;
	
	/**
	 * 查询角色
	 * @param filter
	 * @param orgId 扩展角色和组织挂关系 获取当前组织及以下的角色
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="roles/getRolePage",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色列表（带分页信息）", httpMethod = "POST", notes = "获取角色列表")
	@DataPermission
	public PageList<Role> getRolePage(@ApiParam(name = "filter", value = "查询参数", required = true) @RequestBody QueryFilter filter,
									  @ApiParam(name="orgId",value="组织id", required = false)@RequestParam(required=false) String orgId) throws Exception{
		if(StringUtil.isNotEmpty(orgId)) {
			Org org = orgManager.get(orgId);
			//TODO 跟原角色组件 共用接口 给查询条件增加前缀
			List<QueryField> queryFields = filter.getQuerys();
			for (int i = 0; i < queryFields.size(); i++) {
				QueryField queryField = queryFields.get(i);
				String field = queryField.getProperty();
				field = FieldConvertUtil.property2Field(field, Role.class);
				queryField.setProperty("t." + field);
			}
			return roleService.queryRoleByExtOrgPath(filter, org.getPath());
		}
    	PageList<Role> list = roleService.query(filter);
    	return list;
	}

	public Class currentModelClass(Class<?> cls) {
		return ReflectionKit.getSuperClassGenericType(cls, 1);
	}

	/**
	 * 查询所有可用的角色
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="roles/getEnableRolePage",method=RequestMethod.POST, produces = {
			"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色列表（带分页信息）", httpMethod = "POST", notes = "获取角色列表")
	@DataPermission
	public PageList<Role> getEnableRolePage(@ApiParam(name = "filter", value = "查询参数", required = true) @RequestBody QueryFilter filter) throws Exception{
		filter.addFilter("ENABLED_",0,QueryOP.NOT_EQUAL);
		PageList<Role> list = roleService.query(filter);
		return list;
	}
	
	/**
	 * 获取所有角色
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="roles/getAll",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "获取所有角色", httpMethod = "POST", notes = "获取所有角色")
	public List<Role> getAll() throws Exception{
		return roleService.getAll();
	}
	
	/**
	 * 添加角色
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value="role/addRole",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "添加角色", httpMethod = "POST", notes = "添加角色")
	public CommonResult<String> addRole(@ApiParam(name="role",value="角色参数对象", required = true) @RequestBody RoleVo role) throws Exception{
		CommonResult<String> rtn = roleService.addRole(role);
		if(rtn.getState() && StringUtil.isNotEmpty(role.getExtOrgId())) {
			Role r = roleService.getByAlias(role.getCode());
			orgAuthExtController.saveRole(role.getExtOrgId(), r.getId());
		}
		return rtn;
	}
	
	/**
	 * 根据角色帐号删除角色
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/deleteRole",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "根据角色编码删除角色", httpMethod = "POST", notes = "根据角编码识删除角色")
	@DataPermission
	public CommonResult<String> deleteRole(@ApiParam(name="codes",value="角色编码（多个用,号隔开）", required = true) @RequestBody String codes) throws Exception{
		return roleService.deleteRole(codes);
	}
	
	/**
	 * 根据角色id删除角色
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/deleteRoleByIds",method=RequestMethod.DELETE, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "根据角色id删除角色", httpMethod = "DELETE", notes = "根据角色id删除角色")
    @DataPermission
	public CommonResult<String> deleteRoleByIds(
			@ApiParam(name="ids",value="角色id（多个用,号隔开）", required = true) @RequestParam String ids,
			@ApiParam(name="extOrgId",value="扩展组织id", required = true)@RequestParam(required=false) String extOrgId) throws Exception{
		CommonResult<String> rtn = roleService.deleteRoleByIds(ids);
		if(rtn.getState() && StringUtil.isNotEmpty(extOrgId)) {
			orgAuthExtController.deleteRoleByIds(extOrgId, ids);
		}
		return rtn;
	}
	
	
	/**
	 * 更新角色
	 * @param Role
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/updateRole",method=RequestMethod.PUT, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "更新角色", httpMethod = "PUT", notes = "更新角色")
	@UpdateMethod(type=RoleVo.class)
	@DataPermission
	public CommonResult<String> updateRole(@ApiParam(name="role",value="角色参数对象", required = true) @RequestBody  RoleVo role) throws Exception{
		CommonResult<String> rtn = roleService.updateRole(role);
		if(rtn.getState() && StringUtil.isNotEmpty(role.getExtOrgId())) {
			Role r = roleService.getByAlias(role.getCode());
			orgAuthExtController.saveRole(role.getExtOrgId(), r.getId());
		}
		return rtn;
	}
	
	
	/**
	 * 获取角色信息
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/getRole",method=RequestMethod.GET, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "根据角色编码获取角色信息", httpMethod = "GET", notes = "获取角色信息")
	public CommonResult<Role> getRole(@ApiParam(name="code",value="角色编码", required = true) @RequestParam String code) throws Exception{
		if(StringUtil.isEmpty(code)){
			return new CommonResult<Role>(false, "角色编码必填！", null);
		}
		Role r = roleService.getByAlias(code);
		if(BeanUtils.isEmpty(r)){
			r = roleService.get(code);
		}
		if(BeanUtils.isEmpty(r)){
			return new CommonResult<Role>(false, "根据输入的编码没有找到对应的角色", null);
		}
		return new CommonResult<Role>(true, "", r);
	}
	
	/**
	 * 分配用户（按用户）
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value="roleUser/saveUserRole",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "分配用户（按用户）", httpMethod = "POST", notes = "分配用户（按用户）")
	public CommonResult<String> saveUserRole(@ApiParam(name="code",value="角色编码", required = true) @RequestParam String code,
			@ApiParam(name="accounts",value="用户帐号，多个用“,”号隔开", required = true) @RequestParam String accounts) throws Exception{
		return roleService.saveUserRole(code,accounts);
	}
	
	/**
	 * 分配用户（按用户）
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value="roleUser/saveUserRoles",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "分配用户（按用户）", httpMethod = "POST", notes = "分配用户（按用户）")
	public CommonResult<String> saveUserRoles(@ApiParam(name="codes",value="角色编码，多个用“,”号隔开", required = true) @RequestParam String codes,
			@ApiParam(name="account",value="用户帐号", required = true) @RequestParam String account) throws Exception{
		return roleService.saveUserRoles(codes,account);
	}
	
	/**
	 * 分配用户（按组织）
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value="roleUser/addUserRoleByOrg",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "分配用户（按组织）", httpMethod = "POST", notes = "分配用户（按组织）")
	public CommonResult<String> addUserRoleByOrg(@ApiParam(name="code",value="角色编码", required = true) @RequestParam String code,
			@ApiParam(name="orgCodes",value="组织编码，多个用“,”号隔开", required = true) @RequestParam String orgCodes) throws Exception{
		return roleService.addUserRoleByOrg(code,orgCodes);
	}
	
	/**
	 * 角色移除用户
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value="roleUser/deleteUserRole",method=RequestMethod.DELETE, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "角色移除用户", httpMethod = "DELETE", notes = "角色移除用户")
	public CommonResult<String> deleteUserRole(@ApiParam(name="code",value="角色编码", required = true) @RequestParam String code,
			@ApiParam(name="accounts",value="用户帐号，多个用“,”号隔开", required = true) @RequestParam String accounts) throws Exception{
		return roleService.removeUserRole(code,accounts);
	}
	
	/**
	 * 获取用户所属角色列表
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/getRolesByUser",method=RequestMethod.GET, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "获取用户所属角色列表", httpMethod = "GET", notes = "获取用户所属角色列表")
	public List<Role> getRolesByUser(@ApiParam(name="account",value="用户帐号", required = true) @RequestParam String account) throws Exception{
		return roleService.getListByAccount(account);
	}
	
	/**
	 * 获取角色（多个）中的用户
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/getUsersByRoleCode",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色（多个）中的用户", httpMethod = "POST", notes = "获取角色（多个）中的用户")
	public List<UserVo> getUsersByRoleCode(@ApiParam(name="codes",value="角色编码，多个用“,”号隔开", required = true) @RequestBody String codes) throws Exception{
		return roleService.getUsersByRoleCode(codes);
	}

	/**
	 * 获取角色ids（多个）中的角色
	 * @param ids
	 */
	@RequestMapping(value="role/getRoleByIds",method=RequestMethod.GET, produces = {"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色ids（多个）中的角色", httpMethod = "GET", notes = "获取角色ids（多个）中的角色")
	public List<Role> getRoleByIds(@ApiParam(name="ids",value="角色ids(逗号分隔)", required = true) @RequestParam String ids) throws Exception {
		List<String> roleIds = new ArrayList<>(Arrays.asList(ids.split(",")));
		List<Role> roleList = roleService.getRoleByIds(roleIds);
		return roleList;
	}

	/**
	 * 获取角色ids（多个）中的角色
	 * @param ids
	 * @param orgId
	 */
	@RequestMapping(value="role/getRoleByIdsAndExtOrgId",method=RequestMethod.GET, produces = {"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色ids（多个）中的角色", httpMethod = "GET", notes = "获取角色ids（多个）中的角色")
	public List<Map<String, Object>> getRoleByIdsAndExtOrgId(@ApiParam(name="ids",value="角色ids(逗号分隔)", required = true) @RequestParam String ids,
											  @ApiParam(name="orgId",value="组织id", required = true) @RequestParam String orgId) throws Exception {
		Org org = orgManager.get(orgId);
		String orgPath = org.getPath();
		List<String> roleIds = new ArrayList<>(Arrays.asList(ids.split(",")));
		List<Map<String, Object>> roleList = roleService.getRoleByIdsAndExtOrgId(roleIds, orgPath);
		return roleList;
	}
	
	/**
	 * 物理删除所有逻辑删除了的角色数据
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/deleteRolePhysical",method=RequestMethod.DELETE, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "物理删除所有逻辑删除了的角色数据", httpMethod = "DELETE", notes = "物理删除所有逻辑删除了的角色数据")
	public com.hotent.base.model.CommonResult<Integer> deleteRolePhysical() throws Exception{
		Integer num = roleService.removePhysical();
		return OrgUtil.getRemovePhysiMsg(num);
	}
	
	/**
	 * 物理删除所有逻辑删除了的用户角色关系数据
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/deleteUserRolePhysical",method=RequestMethod.DELETE, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "物理删除所有逻辑删除了的用户角色关系数据", httpMethod = "DELETE", notes = "物理删除所有逻辑删除了的用户角色关系数据")
	public com.hotent.base.model.CommonResult<Integer> deleteUserRolePhysical() throws Exception{
		Integer num = userRoleService.removePhysical();
		return OrgUtil.getRemovePhysiMsg(num);
	}
	
	/**
	 * 禁用角色（多个用,号隔开）
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/forbiddenRoles",method=RequestMethod.PUT, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "禁用角色（多个用,号隔开）", httpMethod = "PUT", notes = "禁用角色（多个用,号隔开）")
	public CommonResult<String> forbiddenRoles(@ApiParam(name="codes",value="角色编码，多个用“,”号隔开", required = true) @RequestBody String codes) throws Exception{
		return roleService.forbiddenRoles(codes);
	}
	
	/**
	 * 激活角色（多个用,号隔开）
	 * @param json
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/activateRoles",method=RequestMethod.PUT, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "激活角色（多个用,号隔开）", httpMethod = "PUT", notes = "激活角色（多个用,号隔开）")
	public CommonResult<String> activateRoles(@ApiParam(name="codes",value="角色编码，多个用“,”号隔开", required = true) @RequestBody String codes) throws Exception{
		return roleService.activateRoles(codes);
	}
	
	/**
	 * 根据时间获取角色数据（数据同步）
	 * @param btime
	 * @param etime
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="roles/getRoleByTime",method=RequestMethod.GET, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "根据时间获取角色数据（数据同步）", httpMethod = "GET", notes = "根据时间获取角色数据（数据同步）")
	public List<Role> getRoleByTime(@ApiParam(name="btime",value="开始时间（格式：2018-01-01 12:00:00或2018-01-01）") @RequestParam(required=false) String btime,@ApiParam(name="etime",value="结束时间（格式：2018-02-01 12:00:00或2018-02-01）") @RequestParam(required=false) String etime) throws Exception{
		return roleService.getRoleByTime(btime,etime);
	}
	
	/**
	 * 获取角色用户（分页）
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="role/getRoleUsers",method=RequestMethod.POST, produces = {
	"application/json; charset=utf-8" })
	@ApiOperation(value = "获取角色用户（分页）", httpMethod = "POST", notes = "获取角色用户（分页）",hidden=false)
	public PageList<User> getRoleUsers(@ApiParam(name="filter",value="查询参数", required = true) @RequestBody QueryFilter filter,@ApiParam(name="code",value="角色编码", required = true) @RequestParam String code) throws Exception{
		filter.addFilter("r.CODE_",code, QueryOP.EQUAL, FieldRelation.AND, "group_code");
		Page<User> list = (Page<User>)userService.getRoleUserQuery(filter);
		return new PageList<User>(list);
	}
	
	@RequestMapping(value="role/isCodeExist",method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "查询角色编码是否已存在", httpMethod = "GET", notes = "查询角色编码是否已存在")
	public CommonResult<Boolean> isCodeExist(@ApiParam(name="code",value="角色编码")
												@RequestParam(required=true) String code) throws Exception{
		return roleService.isCodeExist(code);
	}

	/**
	 *  根据角色别名获取除这个角色之外的所有角色
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="roles/getNotCodeAll",method=RequestMethod.GET, produces = {
			"application/json; charset=utf-8" })
	@ApiOperation(value = "根据角色别名获取除这个角色之外的所有角色", httpMethod = "GET", notes = "获取所有角色")
	public List<Role> getNotCodeAll(@ApiParam(name="code",value="角色编码") @RequestParam(required=true) String code) throws Exception{
		return roleService.getOrgRoleListNotCode(code);
	}
	
	@RequestMapping(value="roles/importRole", method=RequestMethod.POST, produces={"application/json; charset=utf-8" })
	@ApiOperation(value = "角色导入", httpMethod = "POST", notes = "角色导入")
	public CommonResult<String> importRole(@ApiParam(name = "request", value = "上传的文件流") MultipartHttpServletRequest request) throws Exception{
		CommonResult res = roleService.importRole(request);
		return res;
	}

	@RequestMapping(value="roles/importRoleData", method=RequestMethod.POST, produces={"application/json; charset=utf-8" })
	@ApiOperation(value = "角色导入", httpMethod = "POST", notes = "角色导入")
	public CommonResult<String> importRoleData(@ApiParam(name = "request", value = "上传的文件流") MultipartHttpServletRequest request,@ApiParam(name="status",value="status", required = true)@RequestParam String status) throws Exception{
		CommonResult res = roleService.importRoleData(request,status);
		return res;
	}

	@RequestMapping(value="roles/export" ,method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "角色导出", httpMethod = "GET", notes = "角色导出")
	public void export(HttpServletResponse response,@ApiParam(name="ids",value="ids", required = true)@RequestParam String ids) throws 	Exception{
		roleService.export(response,ids);
	}

	@RequestMapping(value="roleUser/operatingUserRoles",method=RequestMethod.POST, produces = {
			"application/json; charset=utf-8" })
	@ApiOperation(value = "转移、复制角色给用户（多个角色，多个用户）", httpMethod = "POST", notes = "转移、复制角色给用户（多个角色，多个用户）")
	public CommonResult<String> operatingUserRoles(@ApiParam(name="map",value="参数", required = true) @RequestBody Map<String,Object> map) throws Exception{
		return roleService.operatingUserRoles(map);
	}

	/**
	 * 移除用户所属的指定角色
	 * 
	 * @param Role
	 * @return
	 * @throws Exception
	 * 
	 */
	@RequestMapping(value = "roleUser/delUserRoles", method = RequestMethod.DELETE, produces = {
			"application/json; charset=utf-8" })
	@ApiOperation(value = "移除用户所属的指定角色", httpMethod = "DELETE", notes = "移除用户所属的指定角色")
	public CommonResult<String> delUserRoles(
			@ApiParam(name = "account", value = "用户账号", required = true) @RequestParam String account,
			@ApiParam(name = "codes", value = "角色编码，多个用“,”号隔开", required = true) @RequestParam String codes)
			throws Exception {
		userRoleService.removeUserRole(account, codes.split(","));
		return CommonResult.ok();
	}

	/**
	 * 根据用户账号和手机号 查询对应的角色
	 *
	 * @param account: 用户账号
	 * @param mobile: 手机号
	 * @author: 梁宏锦
	 * @date: 2024/04/08
	 * @return: java.util.List<com.hotent.uc.model.UserRole>
	 **/
	@RequestMapping(value = "roleUser/getListByAccountOrMobile", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "根据用户账号和手机号 查询对应的角色", httpMethod = "GET", notes = "根据用户账号和手机号 查询对应的角色")
	public CommonResult<List<UserRole>> getListByAccountOrMobile(
			@ApiParam(name = "account", value = "用户账号", required = true) @RequestParam(required=false) String account,
			@ApiParam(name = "mobile", value = "手机号", required = true) @RequestParam(required=false) String mobile)
			throws Exception {
		if(StringUtil.isEmpty(account) && StringUtil.isEmpty(mobile)) {
			throw new BaseException("用户账号 和 手机号 不能同时为空！");
		}
		List<UserRole> list = userRoleService.getListByAccountOrMobile(account, mobile);

		CommonResult<List<UserRole>> result = new CommonResult(ResponseErrorEnums.SUCCESS_OPTION);
		result.setValue(list);
		return result;
	}
}
