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

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.xunhong.erp.turbo.api.facade.api.WxMaServiceI;
import com.xunhong.erp.turbo.api.facade.dto.cmd.WxMaPhoneBindCmd;
import com.xunhong.erp.turbo.api.facade.dto.qry.WxMaPhoneQry;
import com.xunhong.erp.turbo.api.rbac.api.UserMenuServiceI;
import com.xunhong.erp.turbo.api.rbac.api.UserRoleServiceI;
import com.xunhong.erp.turbo.api.rbac.dto.qry.RoleMenuTreeQry;
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.AdminServiceI;
import com.xunhong.erp.turbo.api.user.api.EmployeeServiceI;
import com.xunhong.erp.turbo.api.user.api.UserAuthServiceI;
import com.xunhong.erp.turbo.api.user.api.UserServiceI;
import com.xunhong.erp.turbo.api.user.dto.cmd.EmployeeUpdateAvatarCmd;
import com.xunhong.erp.turbo.api.user.dto.cmd.UserUpdateCmd;
import com.xunhong.erp.turbo.api.user.dto.qry.AdminShowQry;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeeShowQry;
import com.xunhong.erp.turbo.api.user.dto.qry.UserAuthShowQry;
import com.xunhong.erp.turbo.api.user.dto.qry.UserShowQry;
import com.xunhong.erp.turbo.api.user.dto.vo.AdminVO;
import com.xunhong.erp.turbo.api.user.dto.vo.EmployeeVO;
import com.xunhong.erp.turbo.api.user.dto.vo.UserAuthVO;
import com.xunhong.erp.turbo.api.user.dto.vo.UserVO;
import com.xunhong.erp.turbo.base.dto.UserSession;
import com.xunhong.erp.turbo.base.utils.FileUploadUtil;
import com.xunhong.erp.turbo.file.FileService;
import com.xunhong.erp.turbo.file.config.OssProperties;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
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 org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * @author shenyifei
 */
@Tag(name = "User", description = "用户管理")
@RestController("authUserController")
@RequestMapping(value = "/auth")
@RequiredArgsConstructor
public class UserController {
	private final OssProperties properties;

	@DubboReference(version = "1.0.0")
	private final AdminServiceI adminService;

	@DubboReference(version = "1.0.0")
	private final UserServiceI userService;

	@DubboReference(version = "1.0.0")
	private final UserMenuServiceI userMenuService;

	@DubboReference(version = "1.0.0")
	private final WxMaServiceI wxMaService;

	private final FileService fileService;

	@DubboReference(version = "1.0.0")
	private final UserAuthServiceI userAuthService;

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

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

	@SaCheckLogin
	@GetMapping(value = "/userAdmin")
	@Operation(summary = "管理员详情", method = "GET")
	public SingleResponse<AdminVO> userAdmin(@ModelAttribute @Validated AdminShowQry adminShowQry) {
		Long userId = UserSession.USER_THREAD_LOCAL.get().getUserId();
		adminShowQry.setUserId(userId);

		return SingleResponse.of(adminService.show(adminShowQry));
	}

	@SaCheckLogin
	@GetMapping(value = "/userEmployee")
	@Operation(summary = "员工详情", method = "GET")
	public SingleResponse<EmployeeVO> userEmployee(@ModelAttribute @Validated EmployeeShowQry employeeShowQry) {

		Long userId = UserSession.USER_THREAD_LOCAL.get().getUserId();
		employeeShowQry.setUserId(userId);

		EmployeeVO employeeVO = employeeService.show(employeeShowQry);

		if (Objects.isNull(employeeVO)) {
			return SingleResponse.of(null);
		}

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

		employeeVO.setUserRoleList(userRoleVOList);
		employeeVO.setRoleIdList(userRoleVOList.stream().map(UserRoleVO::getRoleId).toList());

		return SingleResponse.of(employeeVO);
	}

	// 更新员工头像
	@SaCheckLogin
	@PostMapping("/userEmployeeUpdateAvatar")
	@Operation(summary = "更新员工头像", method = "POST")
	public Response userEmployeeUpdateAvatar(@RequestBody @Validated EmployeeUpdateAvatarCmd employeeUpdateAvatarCmd) {
		employeeService.updateAvatar(employeeUpdateAvatarCmd);
		return Response.buildSuccess();
	}


	@SaCheckLogin
	@GetMapping("/userInfo")
	@Operation(summary = "用户信息", method = "GET")
	public SingleResponse<UserAuthVO> userInfo() {
		UserAuthShowQry userAuthShowQry = new UserAuthShowQry();
		userAuthShowQry.setUserId(UserSession.USER_THREAD_LOCAL.get().getUserId());
		UserAuthVO userAuthVO = userAuthService.show(userAuthShowQry);

		return SingleResponse.of(userAuthVO);
	}

	@SaCheckLogin
	@PostMapping("/userUpdate")
	@Operation(summary = "修改用户信息", method = "POST")
	public Response userUpdate(@RequestBody @Validated UserUpdateCmd userUpdateCmd) {
		userUpdateCmd.setUserId(UserSession.USER_THREAD_LOCAL.get().getUserId());
		userService.update(userUpdateCmd);

		return Response.buildSuccess();
	}

	@SaCheckLogin
	@GetMapping("/userMenu")
	@Operation(summary = "菜单列表", method = "GET")
	public MultiResponse<Tree<Long>> userMenu(
		@ModelAttribute @Validated RoleMenuTreeQry roleMenuTreeQry
	) {
		return MultiResponse.of(userMenuService.list(roleMenuTreeQry));
	}

	/**
	 * 获取手机号码
	 */
	@SaCheckLogin
	@PostMapping("/wxMaPhone")
	@Operation(summary = "绑定微信手机号码", method = "GET")
	public SingleResponse<String> wxMaPhone(@ModelAttribute @Validated WxMaPhoneQry wxMaPhoneQry) {
		String phone = wxMaService.getPhone(wxMaPhoneQry);

		return SingleResponse.of(phone);
	}

	/**
	 * 绑定微信手机号码
	 */
	@SaCheckLogin
	@PostMapping("/wxMaPhoneBind")
	@Operation(summary = "绑定微信手机号码", method = "POST")
	public Response wxMaPhoneBind(@RequestBody @Validated WxMaPhoneBindCmd wxMaPhoneBindCmd) {
		String phone = wxMaService.getPhone(wxMaPhoneBindCmd);

		UserAuthVO userAuthVO = (UserAuthVO) StpUtil.getSession().get("userAuth");
		UserUpdateCmd userUpdateCmd = new UserUpdateCmd();
		userUpdateCmd.setUserId(userAuthVO.getUserId());
		userUpdateCmd.setPhone(phone);

		UserVO userVO = userAuthVO.getUserVO();
		userVO.setPhone(phone);
		userAuthVO.setUserVO(userVO);
		StpUtil.getSession().set("userAuth", userAuthVO);

		userService.update(userUpdateCmd);

		return Response.buildSuccess();
	}

	@SaCheckLogin
	@PostMapping(value = "upload", consumes = "multipart/form-data")
	@Operation(summary = "上传图片", method = "POST", hidden = true)
	public SingleResponse<String> upload(@RequestParam @Schema(title = "图片文件", requiredMode = Schema.RequiredMode.REQUIRED, type = "file") MultipartFile file) throws IOException {
		// 使用FileUploadUtil安全处理文件名
		String objectName = FileUploadUtil.generateObjectName(file);

		// 记录上传信息
		System.out.println("上传文件: " + file.getOriginalFilename() +
			", Content-Type: " + file.getContentType() +
			", 生成对象名: " + objectName);

		fileService.upload(objectName, file.getInputStream());
		return SingleResponse.of(properties.getDomain() + objectName);
	}

	/**
	 * 判断是否关注公众号
	 */
	@SaCheckLogin
	@PostMapping("/isSubscribe")
	@Operation(summary = "判断是否关注公众号", method = "POST")
	public SingleResponse<Boolean> isSubscribe() {
		UserShowQry userShowQry = new UserShowQry();
		userShowQry.setUserId(UserSession.USER_THREAD_LOCAL.get().getUserId());
		UserVO userVO = userService.show(userShowQry);

		return SingleResponse.of(Objects.nonNull(userVO.getMpOpenid()));
	}
}
