package org.springblade.business.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;
import org.springblade.business.entity.ImageClassificationShow;
import org.springblade.business.service.ImageClassificationShowService;
import org.springblade.business.vo.ImageClassificationShowVO;
import org.springblade.business.vo.TreeVo;
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.Func;
import org.springblade.manager.entity.ImageClassificationConfig;
import org.springblade.manager.feign.ImageClassificationConfigClient;
import org.springblade.manager.feign.WbsTreeContractClient;
import org.springblade.manager.vo.ImageClassificationConfigVO;
import org.springblade.manager.vo.WbsTreeContractTreeVOS;
import org.springblade.system.entity.Dict;
import org.springblade.system.feign.IDictClient;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import org.springblade.business.entity.ImageClassificationFile;
import org.springblade.business.vo.ImageClassificationFileVO;
import org.springblade.business.service.IImageClassificationFileService;
import org.springblade.core.boot.ctrl.BladeController;
import java.util.*;
import java.util.stream.Collectors;

/**
 *  影音资料控制器（客户端）
 *
 * @author BladeX
 * @since 2022-05-24
 */
@RestController
@AllArgsConstructor
@RequestMapping("/imageClassificationFile")
@Api(tags = "影音资料接口（客户端）")
public class ImageClassificationFileController extends BladeController {

	private final IImageClassificationFileService imageClassificationFileService;

	private final ImageClassificationShowService imageClassificationShowService;

	/**
	 * 调用blade-manager的api
	 */
	private final ImageClassificationConfigClient imageClassificationConfigClient;

	private final WbsTreeContractClient wbsTreeContractClient;

	private final IDictClient dictClient;

	/**
	 * 获取当前合同段的工程划分
	 * @param parentId 父节点，为空则查询第一级节点
	 * @return tree
	 */
	@GetMapping("/queryContractWbsTreeByContractIdAndType")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "获取当前合同段的工程划分")
	@ApiImplicitParams(value = {
			@ApiImplicitParam(name = "parentId", value = "父节点，为空则查询第一级节点")
	})
	public R<List<WbsTreeContractTreeVOS>> queryContractWbsTreeByContractIdAndType(@RequestParam String parentId, @RequestParam String contractId){
		List<WbsTreeContractTreeVOS> rootTreeNode;
		if(StringUtils.isEmpty(parentId)){
			//为空，说明初始化
			//获取根节点
			rootTreeNode = this.wbsTreeContractClient.queryContractWbsTreeByContractIdAndType(contractId, 1, "0");
//			if(rootTreeNode != null && rootTreeNode.size() != 0){
//				rootTreeNode.forEach(vo -> {
//					//获取一级子节点
//					List<WbsTreeContractTreeVOS> treeNodes = this.wbsTreeContractClient.queryContractWbsTreeByContractIdAndType(contractId, 1, vo.getId());
//					if(treeNodes != null && treeNodes.size() != 0){
//						vo.setChildren(treeNodes);
//					}
//				});
//			}
		} else {
			//不为空，获取其下子节点
			rootTreeNode = this.wbsTreeContractClient.queryContractWbsTreeByContractIdAndType(contractId, 1, parentId);
		}
		return R.data(rootTreeNode);
	}

	/**
	 * 保存或修改客户端显隐记录
	 * @param showsVo 需要保存或修改的数据集合
	 * @return 操作结果
	 */
	@PostMapping("/saveClassifyShowConfig")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "保存客户端分类显隐记录")
	public R<Boolean> saveOrUpdateClassifyShowConfig(@RequestBody ImageClassificationShowVO showsVo){
		if(showsVo == null || showsVo.getShowList() == null || showsVo.getShowList().size() == 0){
			return R.data(-1, false, "提交数据异常");
		}
		//获取集合
		List<ImageClassificationShow> shows = showsVo.getShowList();
		//判断提交的数据哪些是新增哪些是修改
		List<ImageClassificationShow> saveShow = new ArrayList<>(), updateShow = new ArrayList<>();
		shows.forEach(show -> {
			if(show.getId() == null || show.getId() == -1){
				setUserData(show, true);
				ImageClassificationShow newShow = new ImageClassificationShow();
				BeanUtils.copyProperties(show, newShow);
				newShow.setId(null);
				saveShow.add(newShow);
			} else {
				setUserData(show, false);
				updateShow.add(show);
			}
		});

		boolean result = this.imageClassificationShowService.saveOrUpdateClassifyShowConfig(saveShow, updateShow);
		if(!result){
			return R.data(-1, false, "新增或修改失败");
		}
		return R.data(true);
	}

	/**
	 * 获取当前项目类型的显隐配置列表
	 * @return 结果数据集合
	 */
	@GetMapping("/getClassifyShowConfigList")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "获取当前项目类型的显隐配置列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "projectId", value = "项目ID", required = true),
			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
	})
	public R<List<ImageClassificationConfigVO>> getClassifyShowConfigList(@RequestParam String projectId, @RequestParam String contractId){
		//首先获取显隐
		List<ImageClassificationShow> showClassifyIdList = this.imageClassificationShowService.queryShowClassify(projectId, contractId, null);
		//获取当前系统配置的所有有效分类
		List<ImageClassificationConfig> sysClassifyConfigList = this.imageClassificationConfigClient.queryClassificationConfigList();

		if(sysClassifyConfigList == null || sysClassifyConfigList.size() == 0){
			return R.data(-1, null, "不存在数据，请联系管理员或维护人员");
		}
		//返回的数据
		List<ImageClassificationConfigVO> sysClassifyConfigVoList = JSONArray.parseArray(JSONObject.toJSONString(sysClassifyConfigList), ImageClassificationConfigVO.class);
		if(showClassifyIdList != null && showClassifyIdList.size() != 0){
			//存在显隐记录，只要存在一条记录其它的就默认不显示
			showClassifyIdList.forEach(show -> {
				for(ImageClassificationConfigVO vo : sysClassifyConfigVoList){
					if(show.getClassifyId().equals(vo.getId())){
						vo.setIsShow(new Integer("1").equals(show.getIsShow()));
						vo.setShowId(show.getId());
						break;
					}
				}
			});
			//处理没有显隐的数据
			sysClassifyConfigVoList.forEach(vo -> {
				if(StringUtils.isEmpty(String.valueOf(vo.getShowId()))){
					//默认为不显示
					vo.setIsShow(false);
				}
			});
		} else {
			//不存在显隐记录，全部默认为显示
			sysClassifyConfigVoList.forEach(vo -> vo.setIsShow(true));
		}

		return R.data(sysClassifyConfigVoList);
	}

	/**
	 * 获取类型列表(类型主页)
	 * @return 结果列表集合
	 */
	@GetMapping("/getClassIfyList")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "获取类型列表(类型主页)")
	public R<List<ImageClassificationConfigVO>> getClassIfyList(@RequestParam String projectId, @RequestParam String contractId){
		//获取当前项目下的类型显隐情况
		List<ImageClassificationShow> showClassifyIdList = this.imageClassificationShowService.queryShowClassify(projectId, contractId, "valid");

		//根据当前项目显示的类型ID获取系统默认的分类
		List<ImageClassificationConfig> configList;
		if(showClassifyIdList != null && showClassifyIdList.size() != 0){
			//获取分类ID集合
			List<Long> classifyIds = showClassifyIdList.stream().map(ImageClassificationShow::getClassifyId).distinct().collect(Collectors.toList());
			configList = this.imageClassificationConfigClient.queryClassificationConfigListByIds(classifyIds);
		} else {
			configList = this.imageClassificationConfigClient.queryClassificationConfigList();
		}
		//转换类型
		List<ImageClassificationConfigVO> configVoList = JSONArray.parseArray(JSONObject.toJSONString(configList), ImageClassificationConfigVO.class);

		//获取项目阶段字典
		List<Dict> dictBizList = this.dictClient.getList("project_stage").getData();

		configVoList.forEach(vo -> {
			//转换项目阶段
			for(Dict biz : dictBizList){
				if(biz.getDictKey().equals(vo.getProjectStage())){
					vo.setProjectStage(biz.getDictValue());
					break;
				}
			}

			//获取当前节点下的文件
			Integer count = this.imageClassificationFileService.queryCurrentClassifyAllFileCount(projectId, contractId, vo.getId());
			vo.setCount(count);

		});

		return R.data(configVoList);
	}

	/**
	 * 获取时间结构树
	 * @param classifyId 分类ID
	 * @return 树结构
	 */
	@GetMapping("/getYearDateTree")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "获取时间结构")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "classifyId", value = "分类ID"),
			@ApiImplicitParam(name = "projectId", value = "项目ID"),
			@ApiImplicitParam(name = "contractId", value = "合同段ID")
	})
	public R<List<TreeVo>> getYearDateTree(@RequestParam String classifyId, @RequestParam String projectId, @RequestParam String contractId){
		//获取当前分类下当前项目的拍摄时间并形成tree结构
		return R.data(this.imageClassificationFileService.getYearDateTree(classifyId, projectId, contractId));
	}

	/**
	 * 自定义分页
	 * @param fileVO 查询条件
	 * @param query 分页信息
	 * @return 列表集合
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "分页")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "classifyId", value = "分类ID"),
			@ApiImplicitParam(name = "projectId", value = "项目ID"),
			@ApiImplicitParam(name = "queryStr", value = "输入框查询"),
			@ApiImplicitParam(name = "queryDate", value = "时间查询"),
			@ApiImplicitParam(name = "wbsIdsStr", value = "节点查询"),
	})
	public R<IPage<ImageClassificationFileVO>> page(ImageClassificationFileVO fileVO, Query query){
		IPage<ImageClassificationFileVO> page = this.imageClassificationFileService.selectImageClassificationFilePage(Condition.getPage(query), fileVO);
		return R.data(page);
	}

	/**
	 * 详情页
	 * @param id 主键
	 * @return 详情信息
	 */
	@PostMapping("/queryById")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "详情", notes = "传入主键")
	public R<ImageClassificationFileVO> queryById(@RequestParam String id){
		ImageClassificationFile file = this.imageClassificationFileService.getById(id);
		if(file != null){
			ImageClassificationFileVO vo = new ImageClassificationFileVO();
			BeanUtils.copyProperties(file, vo);
			vo.setShootingTimeStr(DateUtil.format(file.getShootingTime(), "yyyy-MM-dd"));
			return R.data(vo);
		}
		return R.data(null);
	}

	/**
	 * 修改数据
	 * @param fileVO 表单数据
	 * @return 修改结果
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "修改影音资料信息", notes = "传入表单数据")
	public R<Boolean> update(@Valid @RequestBody ImageClassificationFileVO fileVO){
		ImageClassificationFile newData = this.copyBeanData(fileVO, false);
		return R.data(this.imageClassificationFileService.updateById(newData));
	}

	/**
	 * 新增数据
	 * @param fileVO 表单参数
	 * @return 新增结果
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "新增影音资料信息", notes = "传入表单数据")
	public R<Boolean> save(@Valid @RequestBody ImageClassificationFileVO fileVO){
		try{
			ImageClassificationFile newFile = this.copyBeanData(fileVO, true);
			this.setUserData(newFile, false);
			//落库数据
			return R.status(this.imageClassificationFileService.save(newFile));
		}catch (Exception e){
			e.printStackTrace();
		}
		return R.data(-1, false, "数据操作失败");
	}

	//处理参数
	private ImageClassificationFile copyBeanData(ImageClassificationFileVO fileVO, boolean isCreate){
		ImageClassificationFile newFile = new ImageClassificationFile();
		//复制数据
		BeanUtils.copyProperties(fileVO, newFile);
		try{
			String shootingTime = fileVO.getShootingTimeStr();
			String format = "yyyy-MM-dd";
			if(shootingTime.contains(":")){
				format = "yyyy-MM-dd HH:mm:ss";
			}
			newFile.setShootingTime(DateUtil.parseLocalDateTime(shootingTime, format));
		}catch (Exception e){
			e.printStackTrace();
		}
		//设置用户信息
		setUserData(newFile, isCreate);
		return newFile;
	}

	/**
	 * 删除 
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "影音资料信息逻辑删除", notes = "传入ids")
	public R<Boolean> remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(imageClassificationFileService.deleteLogic(Func.toLongList(ids)));
	}

	//设置登录用户信息
	private void setUserData(ImageClassificationShow imageClassificationShow, boolean isCreate){
		//获取当前登录人
		BladeUser user = AuthUtil.getUser();
		//记录操作人信息
		if(isCreate){
			imageClassificationShow.setCreateUser(user.getUserId());
			imageClassificationShow.setCreateDept(user.getDeptId().contains(",") ? Long.parseLong(user.getDeptId().split(",")[0]) : Long.parseLong(user.getDeptId()));
		} else {
			imageClassificationShow.setUpdateUser(user.getUserId());
			imageClassificationShow.setUpdateTime(new Date());
		}
	}

	//设置登录用户信息
	private void setUserData(ImageClassificationFile imageClassificationFile, boolean isCreate){
		//获取当前登录人
		BladeUser user = AuthUtil.getUser();
		//记录操作人信息
		if(isCreate){
			imageClassificationFile.setCreateUser(user.getUserId());
			imageClassificationFile.setCreateDept(user.getDeptId().contains(",") ? Long.parseLong(user.getDeptId().split(",")[0]) : Long.parseLong(user.getDeptId()));
		} else {
			imageClassificationFile.setUpdateUser(user.getUserId());
			imageClassificationFile.setUpdateTime(new Date());
		}
	}

}
