package org.springblade.business.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springblade.business.entity.UserOpinionFile;
import org.springblade.business.entity.UserOpinionFlow;
import org.springblade.business.service.IUserOpinionFileService;
import org.springblade.business.service.IUserOpinionFlowService;
import org.springblade.common.utils.SnowFlakeUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
import org.springblade.manager.feign.ProjectAssignmentUserClient;
import org.springblade.system.entity.DictBiz;
import org.springblade.system.feign.IDictBizClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.feign.IUserClient;
import org.springblade.system.vo.DictBizVO;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.business.entity.UserOpinion;
import org.springblade.business.vo.UserOpinionVO;
import org.springblade.business.service.IUserOpinionService;
import org.springblade.core.boot.ctrl.BladeController;

import java.util.*;

/**
 * 用户意见表 控制器
 *
 * @author BladeX
 * @since 2022-05-25
 */
@RestController
@AllArgsConstructor
@RequestMapping("/userOpinion")
@Api(value = "用户意见表", tags = "用户意见表接口")
public class UserOpinionController extends BladeController {

	private final IUserOpinionService userOpinionService;

	private final IUserOpinionFileService userOpinionFileService;

	private final IUserOpinionFlowService userOpinionFlowService;

	private final IDictBizClient dictBizClient;

	private final ProjectAssignmentUserClient projectAssignmentUserClient;

	private final IUserClient userClient;

	/**
	 * 取消点赞
	 * @param userOpinionId 工单ID
	 * @return 结果
	 */
	@PostMapping("/cancelGood")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "取消点赞")
	@ApiImplicitParam(name = "userOpinionId", value = "工单ID")
	public R<Boolean> cancelGood(@RequestParam String userOpinionId){
		if(StringUtils.isNotEmpty(userOpinionId)){
			UserOpinion opinion = this.userOpinionService.getById(userOpinionId);
			//获取原本的点赞数
			Integer oldGood = opinion.getGoodNumber();
			return R.data(this.userOpinionService.update(Wrappers.<UserOpinion>lambdaUpdate().set(UserOpinion::getGoodNumber, (oldGood - 1)).eq(UserOpinion::getId, userOpinionId)));
		}
		return R.data(-1, false, "数据操作失败");
	}

	/**
	 * 获取工单服务相关数据字典
	 * @return 结果
	 */
	@GetMapping("/queryDictBizList")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "获取字典信息")
	public R<List<DictBizVO>> queryDictBizList(){
		//获取字典
		List<DictBiz> dictList = this.dictBizClient.getList("opinion_type", "").getData();
		//找到根节点
		DictBiz root = null;
		Iterator<DictBiz> iterator = dictList.iterator();
		while (iterator.hasNext()){
			DictBiz biz = iterator.next();
			if(new Long("0").equals(biz.getParentId())){
				root = biz;
				iterator.remove();
				break;
			}
		}

		//首先找到父节点为0的
		List<DictBizVO> result = new ArrayList<>();
		Iterator<DictBiz> iterator1 = dictList.iterator();
		while (iterator1.hasNext()){
			DictBiz biz = iterator1.next();
			if(root != null && root.getId().equals(biz.getParentId())){
				DictBizVO vo = new DictBizVO();
				BeanUtils.copyProperties(biz, vo);
				result.add(vo);
				iterator1.remove();
			} else if(new Long("0").equals(biz.getParentId())){
				DictBizVO vo = new DictBizVO();
				BeanUtils.copyProperties(biz, vo);
				result.add(vo);
				iterator1.remove();
			}
		}
		//组成相关结构树
		result.forEach(vo -> {
			List<DictBizVO> clientList = new ArrayList<>();
			Iterator<DictBiz> iterator2 = dictList.iterator();
			while (iterator2.hasNext()){
				DictBiz biz = iterator2.next();
				if(biz.getParentId().equals(vo.getId())){
					//找到子节点
					DictBizVO voClient = new DictBizVO();
					BeanUtils.copyProperties(biz, voClient);
					clientList.add(voClient);
					iterator2.remove();
				}
			}
			vo.setChildren(clientList);
		});

		return R.data(result);
	}

	/**
	 * 获取当前用户提交的工单服务
	 */
	@PostMapping("/queryCurrentUserOpinionList")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "获取当前用户提交的工单服务")
	public R<List<UserOpinionVO>> queryCurrentUserOpinionList(){
		return R.data(this.userOpinionService.queryCurrentUserOpinionList(AuthUtil.getUser()));
	}

	/**
	 * 新增点赞
	 * @param good 点赞数
	 * @param userOpinionId 点赞的用户工单ID
	 * @return 新增结果
	 */
	@PostMapping("/addGoodNumber")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "点赞")
	@ApiImplicitParams(value = {
			@ApiImplicitParam(name = "good", value = "点赞量", required = true),
			@ApiImplicitParam(name = "userOpinionId", value = "工单ID", required = true)
	})
	public R<Boolean> addGoodNumber(@RequestParam Integer good,@RequestParam String userOpinionId){
		if(StringUtils.isNotEmpty(userOpinionId)){
			UserOpinion opinion = this.userOpinionService.getById(userOpinionId);
			//获取原本的点赞数
			Integer oldGood = opinion.getGoodNumber();
			opinion.setGoodNumber(oldGood == null || oldGood < 0 ? good : oldGood + good);
			return R.data(this.userOpinionService.updateById(opinion));
		}
		return R.data(-1, false, "数据操作失败");
	}

	/**
	 * 工单主页列表
	 * @param query 分页信息
	 * @return 列表数据
	 */
	@GetMapping("/queryUserOpinionPage")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "获取工单服务列表")
	public R<IPage<UserOpinionVO>> queryUserOpinionPage(Query query){
		return R.data(this.userOpinionService.selectUserOpinionPage(Condition.getPage(query), new UserOpinionVO(), AuthUtil.getUser()));
	}

	/**
	 * 新增 用户意见表
	 */
	@PostMapping("/saveUserOpinion")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "新增工单服务信息", notes = "传入userOpinion")
	public R<Boolean> saveUserOpinion(@Valid @RequestBody UserOpinionVO userOpinionVo) {
		//设置用户信息
		this.setUserData(userOpinionVo);
		//生成主表ID
		long idKey = SnowFlakeUtil.getId();
		userOpinionVo.setId(idKey);

		//获取附件信息
		List<String> files = userOpinionVo.getReturnFiles();
		if(files != null && files.size() != 0){
			List<UserOpinionFile> saveFileList = new ArrayList<>();
			//存在附件，执行上传后依次新增记录
			for(String ossUrl : files){
				try{
					//上传附件
					if(StringUtils.isNotEmpty(ossUrl)){
						//新增附件信息
						UserOpinionFile userOpinionFile = new UserOpinionFile();
						//设置主表ID
						userOpinionFile.setUserOpinionId(idKey);
						//设置文件路径
						userOpinionFile.setFileUrl(ossUrl);
						saveFileList.add(userOpinionFile);
					}
				}catch (Exception e){
					e.printStackTrace();
				}
			}
			//新增附件信息
			this.userOpinionFileService.saveBatch(saveFileList);
		}
		//获取当前项目合同段下分配的维护人员
		String manageUserName = "admin", manegeUserPhone = "";
		Long manageUser = 1123598821738675201L;
		try{
			List<SaveUserInfoByProjectDTO> assignmentUserList = this.projectAssignmentUserClient.queryCurrentProjectContractAssignmentUserList(userOpinionVo.getProjectId(), userOpinionVo.getContractId());
			if(assignmentUserList != null && assignmentUserList.size() > 0){
				//有分配人员，随机获取某一个人员
				Random random = new Random();
				//随机结果集长度下的数量
				int ran = random.nextInt(assignmentUserList.size());
				SaveUserInfoByProjectDTO userDto = assignmentUserList.get(ran);
				User user = this.userClient.userInfoById(Long.parseLong(userDto.getUserId())).getData();
				if(user != null){
					manageUser = user.getId();
					manageUserName = user.getRealName();
					manegeUserPhone = user.getPhone();
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}

		//生成第一次流程
		List<UserOpinionFlow> saveFlowList = new ArrayList<>();
		String manageTime = DateUtil.format(DateUtils.addDays(new Date(), 5), "yyyy-MM-dd");
		//提交成功环节
		saveFlowList.add(setUserData(new UserOpinionFlow(idKey, 2, 1, 1, "已提交", "已成功提交您的工单信息", manageTime, manageUser, manageUserName, manegeUserPhone)));
		//分配维护人员环节
		saveFlowList.add(setUserData(new UserOpinionFlow(idKey, 1, 1, 2, "已分配专属客服", "客服：" + manageUser + "<br>电话：" + manegeUserPhone, manageTime, manageUser, manageUserName, manegeUserPhone)));
		//进入人工预处理环节
		saveFlowList.add(setUserData(new UserOpinionFlow(idKey, 0, 1, 3, "进入人工预处理环节", "预计" + manageTime + "之前完成", manageTime, manageUser, manageUserName, manegeUserPhone)));
		//问题已解决
		saveFlowList.add(setUserData(new UserOpinionFlow(idKey, 0, 1, 4, "问题已解决", null, manageTime, manageUser, manageUserName, manegeUserPhone)));
		//新增处理环节
		this.userOpinionFlowService.saveBatch(saveFlowList);
		//最后新增主表数据
		UserOpinion newUserOpinion = new UserOpinion();
		BeanUtils.copyProperties(userOpinionVo, newUserOpinion);
		newUserOpinion.setCreateTime(new Date());
		return R.status(this.userOpinionService.save(newUserOpinion));
	}

	//设置登录用户信息
	private UserOpinionFlow setUserData(UserOpinionFlow userOpinionFlow){
		//获取当前登录人
		BladeUser user = AuthUtil.getUser();
		//记录操作人信息
		userOpinionFlow.setCreateUser(user.getUserId());
		userOpinionFlow.setCreateDept(user.getDeptId().contains(",") ? Long.parseLong(user.getDeptId().split(",")[0]) : Long.parseLong(user.getDeptId()));
		return userOpinionFlow;
	}

	//设置登录用户信息
	private void setUserData(UserOpinion userOpinion){
		//获取当前登录人
		BladeUser user = AuthUtil.getUser();
		userOpinion.setCreateUser(user.getUserId());
		userOpinion.setCreateUserName(user.getRoleName());
		userOpinion.setCreateDept(user.getDeptId().contains(",") ? Long.parseLong(user.getDeptId().split(",")[0]) : Long.parseLong(user.getDeptId()));
	}
}
