package org.jeecg.modules.stm.base.domain.controller;

import java.util.*;
import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


import org.apache.commons.lang3.StringUtils;

import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.stm.base.domain.entity.StDomain;
import org.springframework.util.CollectionUtils;
import org.jeecg.modules.stm.base.domain.service.IStDomainService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.function.Function;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

 /**
 * @Description: st_domain
 * @Author: yzh
 * @Date:   2023-03-04
 * @Version: V1.0
 */

@RestController
@RequestMapping("/base.domain/stDomain")
@Slf4j
public class StDomainController extends JeecgController<StDomain, IStDomainService> {
	 @Autowired
	 private IStDomainService stDomainService;

	 /**
	  * 分页列表查询
	  *
	  * @param stDomain
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 //@AutoLog(value = "领域管理-分页列表查询")

	 @GetMapping(value = "/rootList")
	 public Result<IPage<StDomain>> queryPageList(StDomain stDomain,
												  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
												  HttpServletRequest req) {
		 String hasQuery = req.getParameter("hasQuery");
		 if(hasQuery != null && "true".equals(hasQuery)){
			 QueryWrapper<StDomain> queryWrapper =  QueryGenerator.initQueryWrapper(stDomain, req.getParameterMap());
			 List<StDomain> list = stDomainService.queryTreeListNoPage(queryWrapper);
			 IPage<StDomain> pageList = new Page<>(1, 10, list.size());
			 pageList.setRecords(list);
			 return Result.OK(pageList);
		 }else{
			 String parentId = stDomain.getUpperDomainCode();
			 if (oConvertUtils.isEmpty(parentId)) {
				 parentId = "0";
			 }
			 stDomain.setUpperDomainCode(null);
			 QueryWrapper<StDomain> queryWrapper = QueryGenerator.initQueryWrapper(stDomain, req.getParameterMap());
			 // 特定树形查询带出一级标签处理
			 if(!StringUtils.isEmpty(stDomain.getDomainName()) || stDomain.getLevel()!=null ) {
				List<StDomain> list = stDomainService.list(queryWrapper);
				if(!CollectionUtils.isEmpty(list)){
//					List<String> upperDomainCode = list.stream().map(item-> "0".equals(item.getUpperDomainCode())? item.getDomainCode():
//							item.getUpperDomainCode()).distinct().collect(Collectors.toList());
					List<String> upperDomainCode = new ArrayList<>();
					getRootDomainCodes(list,upperDomainCode);
					queryWrapper = new QueryWrapper<>();
					queryWrapper.in("domain_code",upperDomainCode);
				}
			 }
			 // 使用 eq 防止模糊查询
			 queryWrapper.eq("upper_domain_code", parentId);
			 Page<StDomain> page = new Page<StDomain>(pageNo, pageSize);
			 IPage<StDomain> pageList = stDomainService.page(page, queryWrapper);
			 return Result.OK(pageList);
		 }
	 }

	 private void getRootDomainCodes(List<StDomain> list, List<String> upperDomainCode) {
	 	if(list==null){
	 		return;
		}
	 	if(upperDomainCode == null){
	 		upperDomainCode = new ArrayList<>();
		}
	 	List<String> nextComCodes = new ArrayList<>();
	 	for(StDomain stDomain:list){
		 	if("0".equals(stDomain.getUpperDomainCode())){
			 	upperDomainCode.add(stDomain.getDomainCode());
		 	}else{
				nextComCodes.add(stDomain.getUpperDomainCode());
		 	}
	 	}
	 	if(!CollectionUtils.isEmpty(nextComCodes)){
			QueryWrapper<StDomain> queryWrapper = new QueryWrapper<>();
			queryWrapper.in("domain_code",nextComCodes);
			List<StDomain> upperlist = stDomainService.list(queryWrapper);
			getRootDomainCodes(upperlist,upperDomainCode);
		}
	 }

	 /**
	  * 【vue3专用】加载节点的子数据
	  *
	  * @param pid
	  * @return
	  */
	 @RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET)
	 public Result<List<SelectTreeModel>> loadTreeChildren(@RequestParam(name = "pid") String pid) {
		 Result<List<SelectTreeModel>> result = new Result<>();
		 try {
			 List<SelectTreeModel> ls = stDomainService.queryListByPid(pid);
			 result.setResult(ls);
			 result.setSuccess(true);
		 } catch (Exception e) {
			 e.printStackTrace();
			 result.setMessage(e.getMessage());
			 result.setSuccess(false);
		 }
		 return result;
	 }

	 /**
	  * 【vue3专用】加载一级节点/如果是同步 则所有数据
	  *
	  * @param async
	  * @param pcode
	  * @return
	  */
	 @RequestMapping(value = "/loadTreeRoot", method = RequestMethod.GET)
	 public Result<List<SelectTreeModel>> loadTreeRoot(@RequestParam(name = "async") Boolean async, @RequestParam(name = "pcode") String pcode) {
		 Result<List<SelectTreeModel>> result = new Result<>();
		 try {
			 List<SelectTreeModel> ls = stDomainService.queryListByCode(pcode);
			 //if (!async) {
			    loadAllChildren(ls,async);
			 //}
			 result.setResult(ls);
			 result.setSuccess(true);
		 } catch (Exception e) {
			 e.printStackTrace();
			 result.setMessage(e.getMessage());
			 result.setSuccess(false);
		 }
		 return result;
	 }

	 /**
	  * 【vue3专用】递归求子节点 同步加载用到
	  *
	  * @param ls
	  */
	 private void loadAllChildren(List<SelectTreeModel> ls,boolean async) {
		 for (SelectTreeModel tsm : ls) {
			 List<SelectTreeModel> temp = stDomainService.queryListByPid(tsm.getKey());
			 if (temp != null && temp.size() > 0) {
				 tsm.setChildren(temp);
				 if (!async) {
					 loadAllChildren(temp,async);
				 }
			 }
		 }
	 }

	 /**
	  * 获取子数据
	  * @param stDomain
	  * @param req
	  * @return
	  */
	 //@AutoLog(value = "领域管理-获取子数据")

	 @GetMapping(value = "/childList")
	 public Result<IPage<StDomain>> queryPageList(StDomain stDomain,HttpServletRequest req) {
	 	 Integer org_level = stDomain.getLevel();
		 if(StringUtils.isNotEmpty(stDomain.getUpperDomainCode())){
			 if(2==stDomain.getUpperDomainCode().length()){
				 stDomain.setLevel(2);
				// req.getParameterMap().put("level",new String[]{"2"});
			 }
			 if(4==stDomain.getUpperDomainCode().length()){
				 stDomain.setLevel(3);
			 }
//		 	if("4".equals(stDomain.getUpperDomainCode().length()) && 2!= stDomain.getLevel()){
//			 	stDomain.setLevel(2);
//			 }
		 }
		 String org_domname = stDomain.getDomainName();
		 Map<String,Boolean> isExit = new HashMap<>();
		 if(StringUtils.isNotEmpty(org_domname)){
		 	stDomain.setDomainName(null);
			 QueryWrapper<StDomain> queryWrapper = new QueryWrapper<>();
			 queryWrapper.like("domain_name",org_domname.replace("*",""));
			 List<StDomain> list = stDomainService.list(queryWrapper);
			 if(!CollectionUtils.isEmpty(list)){
				 for(StDomain stDomain1:list){
				 	isExit.put(stDomain1.getDomainCode(),Boolean.TRUE);
				 	isExit.put(stDomain1.getUpperDomainCode(),Boolean.TRUE);
				 }
			 }
		 }
		 QueryWrapper<StDomain> queryWrapper = QueryGenerator.initQueryWrapper(stDomain, req.getParameterMap());
		 if(org_level!=null && org_level == 3){
		 	queryWrapper.eq("HAS_CHILD","1");
		 }
		 List<StDomain> list = stDomainService.list(queryWrapper);
		 if(StringUtils.isNotEmpty(org_domname)){
		 	Iterator<StDomain> it = list.iterator();
		 	while (it.hasNext()){
		 		StDomain stDomain1= it.next();
		 		if(isExit.size() >0 && isExit.get(stDomain1.getDomainCode())==null){
		 			it.remove();
				}
			}
		 }
		 IPage<StDomain> pageList = new Page<>(1, 10, list.size());
		 pageList.setRecords(list);
		 return Result.OK(pageList);
	 }

	 /**
	  * 批量查询子节点
	  * @param parentIds 父ID（多个采用半角逗号分割）
	  * @return 返回 IPage
	  * @param parentIds
	  * @return
	  */
	 //@AutoLog(value = "领域管理-批量获取子数据")

	 @GetMapping("/getChildListBatch")
	 public Result getChildListBatch(@RequestParam("parentIds") String parentIds,
									 @RequestParam("level") String level,
									 @RequestParam("domainName") String domainName) {
		 try {
			 QueryWrapper<StDomain> queryWrapper = new QueryWrapper<>();
			 List<String> parentIdList = Arrays.asList(parentIds.split(","));
			 // 去重
			 List<String> distParentIdList = parentIdList.stream().distinct().collect(Collectors.toList());
			 if(CollectionUtils.isEmpty(distParentIdList)){
				 return Result.OK(new ArrayList<>());
			 }
			 queryWrapper.in("id", distParentIdList);
			 List<StDomain> listids = stDomainService.list(queryWrapper);
			 // 查询子级
			 QueryWrapper<StDomain> searchCodeQueryWrapper = new QueryWrapper<>();
			 List<String> upperDomainCodes = listids.stream().
					 map(StDomain::getDomainCode).distinct().collect(Collectors.toList());
			 if(CollectionUtils.isEmpty(upperDomainCodes)){
				 return Result.OK(new ArrayList<>());
			 }
			 searchCodeQueryWrapper.in("upper_domain_code",upperDomainCodes);
			 if(!StringUtils.isEmpty(level)){
			 	if("3".equals(level)){
					searchCodeQueryWrapper.in("level","1","2","3");
				}else if("2".equals(level)){
					searchCodeQueryWrapper.in("level","1","2");
				}else{
					searchCodeQueryWrapper.eq("level","1");
				}
			 }
			 Map<String,Boolean> isExit = new HashMap<>();
			 if(!StringUtils.isEmpty(domainName)){
				 QueryWrapper<StDomain> queryWrapperExit = new QueryWrapper<>();
				 queryWrapperExit.like("domain_name",domainName.replace("*",""));
				 List<StDomain> list = stDomainService.list(queryWrapperExit);
				 if(!CollectionUtils.isEmpty(list)){
					 for(StDomain stDomain1:list){
						 isExit.put(stDomain1.getDomainCode(),Boolean.TRUE);
						 isExit.put(stDomain1.getUpperDomainCode(),Boolean.TRUE);
					 }
				 }
			 }
			 List<StDomain> list = stDomainService.list(searchCodeQueryWrapper);
			 Iterator<StDomain> it = list.iterator();
			 while (it.hasNext()){
			 	StDomain stDomain = it.next();
			 	boolean isRemove = false;
				 if(!StringUtils.isEmpty(level)) {
					 if ("3".equals(level) && stDomain.getLevel()==2) {
					 	if("0".equals(stDomain.getHasChild())){
					 		it.remove();
							isRemove = true;
						}
					 }
				 }
				 if(!isRemove && isExit.size() >0 && isExit.get(stDomain.getDomainCode())==null){
					 it.remove();
				 }
			 }
			 IPage<StDomain> pageList = new Page<>(1, 10, list.size());
			 pageList.setRecords(list);
			 return Result.OK(pageList);
		 } catch (Exception e) {
			 log.error(e.getMessage(), e);
			 return Result.error("批量查询子节点失败：" + e.getMessage());
		 }
	 }

	 /**
	  *   添加
	  *
	  * @param stDomain
	  * @return
	  */
	 @AutoLog(value = "领域管理-添加")

	 @RequiresPermissions("base.domain:st_domain:add")
	 @PostMapping(value = "/add")
	 public Result<String> add(@RequestBody StDomain stDomain) {
		 stDomainService.addStDomain(stDomain);
		 return Result.OK("添加成功！");
	 }

	 /**
	  *  编辑
	  *
	  * @param stDomain
	  * @return
	  */
	 @AutoLog(value = "领域管理-编辑")

	 @RequiresPermissions("base.domain:st_domain:edit")
	 @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	 public Result<String> edit(@RequestBody StDomain stDomain) {
		 stDomainService.updateStDomain(stDomain);
		 return Result.OK("编辑成功!");
	 }

	 @AutoLog(value = "领域管理-变更父级")

	 @RequiresPermissions("base.domain:st_domain:edit")
	 @RequestMapping(value = "/changeParent", method = {RequestMethod.PUT,RequestMethod.POST})
	 public Result<String> changeParent(@RequestBody StDomain stDomain) {
		 stDomainService.changeParent(stDomain);
		 return Result.OK("编辑成功!");
	 }
	 /**
	  *   通过id删除
	  *
	  * @param id
	  * @return
	  */
	 @AutoLog(value = "领域管理-通过id删除")

	 @RequiresPermissions("base.domain:st_domain:delete")
	 @DeleteMapping(value = "/delete")
	 public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		 stDomainService.deleteStDomain(id);
		 return Result.OK("删除成功!");
	 }

	 /**
	  *  批量删除
	  *
	  * @param ids
	  * @return
	  */
	 @AutoLog(value = "领域管理-批量删除")

	 @RequiresPermissions("base.domain:st_domain:deleteBatch")
	 @DeleteMapping(value = "/deleteBatch")
	 public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		 this.stDomainService.removeByIds(Arrays.asList(ids.split(",")));
		 return Result.OK("批量删除成功！");
	 }

	 /**
	  * 通过id查询
	  *
	  * @param id
	  * @return
	  */
	 //@AutoLog(value = "领域管理-通过id查询")

	 @GetMapping(value = "/queryById")
	 public Result<StDomain> queryById(@RequestParam(name="id",required=true) String id) {
		 StDomain stDomain = stDomainService.getById(id);
		 if(stDomain==null) {
			 return Result.error("未找到对应数据");
		 }
		 return Result.OK(stDomain);
	 }

	 @GetMapping(value = "/queryByCode")
	 public Result<List<String>> queryByCode(@RequestParam(name="code",required=true) String code) {

		 List<String> codeList = new ArrayList<>();
		 for (int i = 0; i < code.length(); i += 2) {
			 if (i + 2 <= code.length()) {
				 codeList.add(code.substring(0, i + 2));
			 }
		 }

		 QueryWrapper<StDomain> queryWrapper = new QueryWrapper<>();
		 queryWrapper.in("domain_code", codeList);
		 List<StDomain> stDomainList = stDomainService.list(queryWrapper);

		 if(stDomainList.isEmpty()) {
			 return Result.error("未找到对应数据");
		 }

		 List<String> domainNameList = new ArrayList<>();
		 Map<String, StDomain> domainMap = stDomainList.stream()
				 .collect(Collectors.toMap(StDomain::getDomainCode, Function.identity()));

		 for (String codeItem : codeList) {
			 StDomain domain = domainMap.get(codeItem);
			 if (domain != null) {
				 domainNameList.add(domain.getDomainName());
			 } else {
				 domainNameList.add(null); // 或者添加空字符串，根据需求决定
			 }
		 }

		 return Result.OK(domainNameList);
	 }

	 /**
	  * 导出excel
	  *
	  * @param request
	  * @param stDomain
	  */
	 @RequiresPermissions("base.domain:st_domain:exportXls")
	 @RequestMapping(value = "/exportXls")
	 public ModelAndView exportXls(HttpServletRequest request, StDomain stDomain) {
		 return super.exportXls(request, stDomain, StDomain.class, "st_domain");
	 }

	 /**
	  * 通过excel导入数据
	  *
	  * @param request
	  * @param response
	  * @return
	  */
	 @RequiresPermissions("base.domain:st_domain:importExcel")
	 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
	 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
		 return super.importExcel(request, response, StDomain.class);
	 }

	 @RequestMapping(value = "/loadAllDomain", method = RequestMethod.GET)
	 public Result<List<StDomain>> loadAllDomain(StDomain stDomain, HttpServletRequest req) {
		 List<StDomain> list = stDomainService.list();
		 return Result.OK(list);
	 }
}
