
package com.xunhong.erp.turbo.admin.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckSafe;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.monitor4all.logRecord.annotation.OperationLog;
import cn.monitor4all.logRecord.context.LogRecordContext;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.xunhong.erp.turbo.api.rbac.api.UserRoleServiceI;
import com.xunhong.erp.turbo.api.rbac.dto.cmd.UserRoleCreateCmd;
import com.xunhong.erp.turbo.api.rbac.dto.cmd.UserRoleUpdateCmd;
import com.xunhong.erp.turbo.api.rbac.dto.qry.UserRoleListQry;
import com.xunhong.erp.turbo.api.rbac.dto.vo.UserRoleVO;
import com.xunhong.erp.turbo.api.user.api.EmployeeServiceI;
import com.xunhong.erp.turbo.api.user.dto.cmd.*;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeeListQry;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeePageQry;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeeShowQry;
import com.xunhong.erp.turbo.api.user.dto.vo.EmployeeVO;
import com.xunhong.erp.turbo.base.dto.PageDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * @author shenyifei
 */
@Tag(name = "Employee", description = "员工信息管理")
@RestController("operationEmployeeController")
@RequestMapping(value = "/operation")
@RequiredArgsConstructor
public class EmployeeController {

	@DubboReference(version = "1.0.0")
	private final EmployeeServiceI employeeService;

	@DubboReference(version = "1.0.0")
	private final UserRoleServiceI userRoleService;

	@SaCheckLogin
	@SaCheckSafe
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_REST_PASSWORD})
	@PostMapping("restEmployeePassword")
	@Operation(summary = "重置员工密码", method = "POST")
	public Response restEmployeePassword(@RequestBody @Validated EmployeeRestPasswordCmd employeeRestPasswordCmd) {
		employeeService.restPassword(employeeRestPasswordCmd);

		// 强制注销
		StpUtil.logout(employeeRestPasswordCmd.getUserId());
		return Response.buildSuccess();
	}

	@SaCheckLogin
	@SaCheckSafe
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_DISABLE})
	@PostMapping("disableEmployee")
	@Operation(summary = "封禁员工", method = "POST")
	@OperationLog(bizId = "#employeeVO.employeeId", bizType = "'disableEmployee'", msg = "'封禁员工：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public Response disableEmployee(@RequestBody @Validated EmployeeDisableCmd employeeDisableCmd) {
		EmployeeVO employeeVO = employeeService.disable(employeeDisableCmd);

		// 踢他下线
		StpUtil.kickout(employeeVO.getUserId());
		// 永久封禁
		StpUtil.disable(employeeVO.getUserId(), -1);
		return Response.buildSuccess();
	}

	@SaCheckLogin
	@SaCheckSafe
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_ROLE_UPDATE})
	@PostMapping("updateEmployeeRole")
	@Operation(summary = "修改员工角色", method = "POST")
	@OperationLog(bizId = "#employeeVO.employeeId", bizType = "'updateEmployeeRole'", msg = "'修改员工角色：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", extra = "#_DIFF(#oldEmployeeVO, #employeeVO)", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public Response updateEmployeeRole(@RequestBody @Validated UserRoleUpdateCmd userRoleUpdateCmd) {
		userRoleService.update(userRoleUpdateCmd);

		// 强制注销
		StpUtil.logout(userRoleUpdateCmd.getUserId());
		return Response.buildSuccess();
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_VIEW})
	@GetMapping("listEmployee")
	@Operation(summary = "员工信息列表", method = "GET")
	public MultiResponse<EmployeeVO> listEmployee(@ModelAttribute @Validated EmployeeListQry employeeListQry) {
		return MultiResponse.of(employeeService.list(employeeListQry));
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_CREATE})
	@PostMapping("createEmployee")
	@Operation(summary = "创建员工信息", method = "POST")
	@OperationLog(bizId = "#employeeVO.employeeId", bizType = "'createEmployee'", msg = "'创建员工：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public SingleResponse<EmployeeVO> createEmployee(@RequestBody @Validated EmployeeCreateCmd employeeCreateCmd) {
		// 创建员工，注册用户，注册管理员
		EmployeeVO employeeVO = employeeService.create(employeeCreateCmd);

		// 赋予用户权限
		UserRoleCreateCmd userRoleCreateCmd = new UserRoleCreateCmd();
		userRoleCreateCmd.setRoleId(employeeCreateCmd.getRoleId());
		userRoleCreateCmd.setUserId(employeeVO.getUserId());
		List<UserRoleVO> userRoleVOList = userRoleService.create(userRoleCreateCmd);

		employeeVO.setRoleIdList(userRoleVOList.stream().map(UserRoleVO::getRoleId).toList());
		LogRecordContext.putVariable("employeeVO", employeeVO);

		return SingleResponse.of(employeeVO);
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_VIEW})
	@GetMapping("showEmployee")
	@Operation(summary = "员工信息详情", method = "GET")
	@OperationLog(bizId = "#employeeShowQry.employeeId", bizType = "'showEmployee'", msg = "'查看员工：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public SingleResponse<EmployeeVO> showEmployee(@ModelAttribute @Validated EmployeeShowQry employeeShowQry) {
		EmployeeVO employeeVO = employeeService.show(employeeShowQry);

		// 获取角色
		UserRoleListQry userRoleListQry = new UserRoleListQry();
		userRoleListQry.setUserId(employeeVO.getUserId());
		List<UserRoleVO> userRoleVOList = userRoleService.list(userRoleListQry);

		employeeVO.setRoleIdList(userRoleVOList.stream().map(UserRoleVO::getRoleId).toList());
		LogRecordContext.putVariable("employeeVO", employeeVO);

		return SingleResponse.of(employeeVO);
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_VIEW})
	@GetMapping("pageEmployee")
	@Operation(summary = "员工信息列表", method = "GET")
	public PageResponse<EmployeeVO> pageEmployee(@ModelAttribute @Validated EmployeePageQry employeePageQry) {
		PageDTO<EmployeeVO> page = employeeService.page(employeePageQry);
		List<Long> userIdList = page.getRecords().stream().map(EmployeeVO::getUserId).toList();
		if (CollUtil.isNotEmpty(userIdList)) {
			UserRoleListQry userRoleListQry = new UserRoleListQry();
			userRoleListQry.setUserIdList(userIdList);
			List<UserRoleVO> userRoleVOList = userRoleService.list(userRoleListQry);
			page.getRecords().forEach(employeeVO -> employeeVO.setRoleIdList(userRoleVOList.stream().filter(userRoleVO -> userRoleVO.getUserId().equals(employeeVO.getUserId())).map(UserRoleVO::getRoleId).toList()));

		}
		return PageResponse.of(page.getRecords(), (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_UPDATE})
	@RequestMapping(value = "updateEmployee", method = {RequestMethod.PATCH, RequestMethod.PUT})
	@Operation(summary = "员工信息更新", method = "PATCH")
	@OperationLog(bizId = "#employeeVO.employeeId", bizType = "'updateEmployee'", msg = "'更新员工：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", extra = "#_DIFF(#oldEmployeeVO, #employeeVO)", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public SingleResponse<EmployeeVO> updateEmployee(@RequestBody @Validated EmployeeUpdateCmd employeeUpdateCmd) {
		EmployeeShowQry employeeShowQry = new EmployeeShowQry();
		employeeShowQry.setEmployeeId(employeeUpdateCmd.getEmployeeId());
		LogRecordContext.putVariable("oldEmployeeVO", employeeService.show(employeeShowQry));

		EmployeeVO employeeVO = employeeService.update(employeeUpdateCmd);
		LogRecordContext.putVariable("employeeVO", employeeVO);

		return SingleResponse.of(employeeVO);
	}

	@SaCheckLogin
//	@SaCheckPermission(value = {PermissionConstant.MDB_BUSINESS_EMPLOYEE_DELETE})
	@DeleteMapping("destroyEmployee")
	@Operation(summary = "员工信息删除", method = "DELETE")
	@OperationLog(bizId = "#employeeVO.employeeId", bizType = "'destroyEmployee'", msg = "'删除员工：' + #employeeVO.name + '(工号：' + #employeeVO.number + ')'", operatorId = "T(cn.dev33.satoken.stp.StpUtil).getLoginIdAsLong()")
	public Response destroyEmployee(@RequestBody @Validated EmployeeDestroyCmd employeeDestroyCmd) {
		EmployeeShowQry employeeShowQry = new EmployeeShowQry();
		employeeShowQry.setEmployeeId(employeeDestroyCmd.getEmployeeId());

		EmployeeVO employeeVO = employeeService.show(employeeShowQry);
		if (Objects.isNull(employeeVO)) {
			return Response.buildFailure("400", "员工不存在");
		}

		LogRecordContext.putVariable("employeeVO", employeeVO);

		employeeService.destroy(employeeDestroyCmd);
		return Response.buildSuccess();
	}
}
