package org.jeecg.modules.stm.audit.controller;

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.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.stm.audit.entity.*;
import org.jeecg.modules.stm.audit.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import org.jeecg.modules.stm.utils.StmConstans;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 内控制度
 * @Author: jeecg-boot
 * @Date:   2024-08-23
 * @Version: V1.0
 */
  
@RestController
@RequestMapping("/audit/auditInnerOrder")
@Slf4j
public class AuditInnerOrderController extends JeecgController<AuditInnerOrder, IAuditInnerOrderService> {
	@Autowired
	private IAuditInnerOrderService auditInnerOrderService;
	@Autowired
	private IAuditLabelRelLibService stLabelRelLibService;
	@Autowired
	private IAuditActRelOthersService stActRelOthersService;
	@Autowired
	private IAuditInnerCheckmethodService auditInnerCheckmethodService;
	@Autowired
	private IAuditInnerOrderRelCheckService auditInnerOrderRelCheckService;
	@Autowired
	private IAuditFileContentCategoriesService auditFileContentCategoriesService;
	@Autowired
	private IAuditInnerCheckmethodItemService auditInnerCheckmethodItemService;

	/**
	 * 分页列表查询
	 *
	 * @param auditInnerOrder
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	//@AutoLog(value = "内控制度-分页列表查询")
	  
	@GetMapping(value = "/list")
	public Result<IPage<AuditInnerOrder>> queryPageList(AuditInnerOrder auditInnerOrder,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<AuditInnerOrder> queryWrapper = QueryGenerator.initQueryWrapper(auditInnerOrder, req.getParameterMap());
		Page<AuditInnerOrder> page = new Page<AuditInnerOrder>(pageNo, pageSize);
		IPage<AuditInnerOrder> pageList = auditInnerOrderService.page(page, queryWrapper);

		return Result.OK(pageList);
	}

	@GetMapping(value = "/listAll")
	public Result<List<AuditInnerOrder>> listAll(AuditInnerOrder auditInnerOrder,

														HttpServletRequest req) {
		QueryWrapper<AuditInnerOrder> queryWrapper = QueryGenerator.initQueryWrapper(auditInnerOrder, req.getParameterMap());
		List<AuditInnerOrder> list = auditInnerOrderService.list(queryWrapper);

		return Result.OK(list);
	}
	
	/**
	 *   添加
	 *
	 * @param auditInnerOrder
	 * @return
	 */
	@AutoLog(value = "内控制度-添加")
	  
	@PostMapping(value = "/add")
	public Result<AuditInnerOrder> add(@RequestBody AuditInnerOrder auditInnerOrder) {

		if(getComplianeItemNameIsExist(auditInnerOrder)) {
			return  Result.error("条目名称和内容已经村存在");
		}
		setSgrpPath(auditInnerOrder);
		auditInnerOrderService.save(auditInnerOrder);
		String labels = auditInnerOrder.getLabels();
		Integer tid =  auditInnerOrder.getId();
		if(labels!=null&&!labels.equals("")){
			stLabelRelLibService.saveLabelRel(labels,tid, StmConstans.Audit_TP_INNER_ORDER);
		}

		List<AuditInnerCheckmethod> checkMethods = auditInnerOrder.getCheckMethods();
		if(checkMethods!=null){
			//checMethodExist(checkMethods);
			auditInnerCheckmethodService.saveOrUpdateBatch(checkMethods);
			List<AuditInnerOrderRelCheck> auditItemRelCheckList = new ArrayList<>();
			Integer itemId = auditInnerOrder.getId();
			List<AuditActRelOthers> actRelOthers = new ArrayList<>();
			List<AuditInnerCheckmethodItem> allCmItems = new ArrayList<>();
			List<Integer> checkIds = new ArrayList<>();
			for(AuditInnerCheckmethod method : checkMethods){
				AuditInnerOrderRelCheck auditInnerOrderRelCheck = new AuditInnerOrderRelCheck();
				auditInnerOrderRelCheck.setCheckid(method.getId());
				auditInnerOrderRelCheck.setCitemid(itemId);
				auditItemRelCheckList.add(auditInnerOrderRelCheck);
				checkIds.add(method.getId());
				String actIds = method.getActIds();
				if(actIds!=null&&!actIds.equals("")) {
					stActRelOthersService.setActRelations(actRelOthers,actIds,method.getId(),StmConstans.Audit_TP_INNER_ORDER_CHECK_METHOD);
				}
				List<AuditInnerCheckmethodItem> cmItems = method.getCheckMethodItems();
				if(cmItems!=null&&cmItems.size()>0) {
					for(AuditInnerCheckmethodItem item:cmItems) {
						item.setCheckid(method.getId());
						allCmItems.add(item);
					}
				}
			}

			if(actRelOthers.size()>0) {
				stActRelOthersService.saveBatch(actRelOthers);
			}
			if(auditItemRelCheckList.size()>0) {
				auditInnerOrderRelCheckService.saveBatch(auditItemRelCheckList);
			}
			if(allCmItems.size()>0) {
				auditInnerCheckmethodItemService.saveBatch(allCmItems);
			}

		}
		return Result.OK(auditInnerOrder);
	}
	
	/**
	 *  编辑
	 *
	 * @param auditInnerOrder
	 * @return
	 */
	@AutoLog(value = "内控制度-编辑")
	  
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<AuditInnerOrder> edit(@RequestBody AuditInnerOrder auditInnerOrder) {

		if(getComplianeItemNameIsExist(auditInnerOrder)) {
			return  Result.error("条目名称和内容已经村存在!");
		}
		setSgrpPath(auditInnerOrder);
		auditInnerOrderService.updateById(auditInnerOrder);
		Integer complianeItemId =  auditInnerOrder.getId();
		String labels = auditInnerOrder.getLabels();
		stLabelRelLibService.deleteLabelRel(complianeItemId, StmConstans.Audit_TP_INNER_ORDER);
		if(labels!=null && labels.trim().length()>0) {
			stLabelRelLibService.saveLabelRel(labels, complianeItemId, StmConstans.Audit_TP_INNER_ORDER);
		}

		List<AuditInnerCheckmethod> checkMethods = auditInnerOrder.getCheckMethods();
		if(checkMethods!=null&&checkMethods.size()>0){
			checkAndDeleteCheckMethod(checkMethods,complianeItemId);
			auditInnerCheckmethodService.saveOrUpdateBatch(checkMethods);

			List<AuditInnerOrderRelCheck> auditItemRelCheckList = new ArrayList<>();
			List<AuditActRelOthers> actRelOthers = new ArrayList<>();
			List<AuditInnerCheckmethodItem> allCmItems = new ArrayList<>();
			List<Integer> checkIds = new ArrayList<>();

			for(AuditInnerCheckmethod method : checkMethods){
				AuditInnerOrderRelCheck auditItemRelCheck = new AuditInnerOrderRelCheck();
				auditItemRelCheck.setCheckid(method.getId());
				auditItemRelCheck.setCitemid(complianeItemId);
				auditItemRelCheckList.add(auditItemRelCheck);
				checkIds.add(method.getId());
				String actIds = method.getActIds();
				if(actIds!=null&&!actIds.equals("")) {
					stActRelOthersService.setActRelations(actRelOthers,actIds,method.getId(),StmConstans.Audit_TP_INNER_ORDER_CHECK_METHOD);
				}

				List<AuditInnerCheckmethodItem> cmItems = method.getCheckMethodItems();
				if(cmItems!=null&&cmItems.size()>0) {
					for(AuditInnerCheckmethodItem item:cmItems) {
						item.setCheckid(method.getId());
						allCmItems.add(item);
					}
				}
			}

			deleteItemAndCheckRel(checkIds,complianeItemId);
			if(auditItemRelCheckList.size()>0) {
				auditInnerOrderRelCheckService.saveOrUpdateBatch(auditItemRelCheckList);
			}

			deleteActAndCheckRel(checkIds);
			if(actRelOthers.size()>0) {
				stActRelOthersService.saveOrUpdateBatch(actRelOthers);
			}

			deleteCheckItms(checkIds);
			if(allCmItems.size()>0) {
				auditInnerCheckmethodItemService.saveOrUpdateBatch(allCmItems);
			}

		}
		return Result.OK(auditInnerOrder);
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "内控制度-通过id删除")
	  
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		auditInnerOrderService.removeById(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "内控制度-批量删除")
	  
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.auditInnerOrderService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	//@AutoLog(value = "内控制度-通过id查询")
	  
	@GetMapping(value = "/queryById")
	public Result<AuditInnerOrder> queryById(@RequestParam(name="id",required=true) String id) {
		AuditInnerOrder auditInnerOrder = auditInnerOrderService.getById(id);
		if(auditInnerOrder==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(auditInnerOrder);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param auditInnerOrder
    */
    @RequiresPermissions("audit:audit_inner_order:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, AuditInnerOrder auditInnerOrder) {
        return super.exportXls(request, auditInnerOrder, AuditInnerOrder.class, "内控制度");
    }

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


	private boolean getComplianeItemNameIsExist(AuditInnerOrder order) {
		QueryWrapper<AuditInnerOrder> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("item",order.getItem()).eq("content",order.getContent());
		if(order.getId()!=null) {
			queryWrapper.ne("id",order.getId());
		}
		List<AuditInnerOrder>  list  = auditInnerOrderService.list(queryWrapper);
		if(list.size()>0) {
			return  true;
		} else {
			return  false;
		}
	}

	private void checkMethodExist(List<AuditInnerCheckmethod> checkMethods) {
		List<String> listContent = new ArrayList<>();
		for(AuditInnerCheckmethod method : checkMethods) {
			listContent.add(method.getContent());
		}
		QueryWrapper<AuditInnerCheckmethod> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("content",listContent);
		List<AuditInnerCheckmethod> retList = auditInnerCheckmethodService.list(queryWrapper);
		if(retList!=null&&retList.size()>0) {
			for (AuditInnerCheckmethod method : retList) {
				for (int i=0;i< checkMethods.size(); i++){
					AuditInnerCheckmethod method2 = checkMethods.get(i);
					if(method.getContent().equals(method2.getContent())) {
						method.setContent(method2.getContent());
						method.setDes(method2.getDes());
						method.setActIds(method2.getActIds());
						break;
					}
				}
			}
		}
	}
	private void deleteItemAndCheckRel(List<Integer> checkids,Integer citemid) {
		AuditItemRelCheck relCheck = new AuditItemRelCheck();
		QueryWrapper<AuditInnerOrderRelCheck> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("citemid",citemid).in("checkid",checkids);
		auditInnerOrderRelCheckService.remove(queryWrapper);
	}

	private void deleteActAndCheckRel(Integer chkid) {
		AuditItemRelCheck relCheck = new AuditItemRelCheck();
		QueryWrapper<AuditActRelOthers> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("tid",chkid).eq("tp",StmConstans.Audit_TP_INNER_ORDER_CHECK_METHOD);
		stActRelOthersService.remove(queryWrapper);
	}

	private void deleteActAndCheckRel(List<Integer> chkidList) {
		AuditItemRelCheck relCheck = new AuditItemRelCheck();
		QueryWrapper<AuditActRelOthers> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("tid",chkidList).eq("tp",StmConstans.Audit_TP_INNER_ORDER_CHECK_METHOD);
		stActRelOthersService.remove(queryWrapper);
	}

	private void setSgrpPath(AuditInnerOrder auditInnerOrder) {
		String crgpid = auditInnerOrder.getCgrp();
		if(crgpid!=null) {
			Integer fileId = auditInnerOrder.getFileId();
			AuditFileContentCategories cat = auditFileContentCategoriesService.getById(crgpid);
			String strPath = auditFileContentCategoriesService.queryFullPathNodeId(cat,fileId);
			auditInnerOrder.setCgrpPath(strPath);
		} else {
			auditInnerOrder.setCgrpPath("");
		}
	}

	private void deleteOtherTable(List<String> itemIdList){
		//删除与检查方法的关系表
		QueryWrapper<AuditInnerOrderRelCheck> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("citemid",itemIdList);
		List<AuditInnerOrderRelCheck> relCheckList =  auditInnerOrderRelCheckService.list(queryWrapper);
		List<Integer> checkIdList = new ArrayList<>();
		for(AuditInnerOrderRelCheck check:relCheckList) {
			checkIdList.add(check.getCheckid());

		}
		if(checkIdList.size()>0) {
			auditInnerCheckmethodService.removeBatchByIds(checkIdList);
			auditInnerOrderRelCheckService.remove(queryWrapper);
			QueryWrapper<AuditInnerCheckmethodItem> queryCheckWrapper = new QueryWrapper<>();
			queryCheckWrapper.in("checkid",checkIdList);
			auditInnerCheckmethodItemService.remove(queryCheckWrapper);
		}
	}



	private void deleteCheckItms(List<Integer> checkidList) {
		QueryWrapper<AuditInnerCheckmethodItem> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("checkid",checkidList);
		auditInnerCheckmethodItemService.remove(queryWrapper);
	}

	private void checkAndDeleteCheckMethod(List<AuditInnerCheckmethod> checkMethods,Integer itemid) {
		QueryWrapper<AuditInnerOrderRelCheck> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("citemid",itemid);
		List<AuditInnerOrderRelCheck> relCheckList =  auditInnerOrderRelCheckService.list(queryWrapper);
		List<Integer> deleteCheckId = new ArrayList<>();

		for(AuditInnerOrderRelCheck refCheck:relCheckList) {
			deleteCheckId.add(refCheck.getCheckid());
		}

		for(AuditInnerCheckmethod method:checkMethods) {
			Integer checkid = method.getId();
			if(checkid!=null) {
				if(deleteCheckId.contains(checkid)) {
					deleteCheckId.remove(checkid);
				}
			}
		}

		if(deleteCheckId.size()>0) {
			auditInnerCheckmethodService.removeBatchByIds(deleteCheckId);
			auditInnerOrderRelCheckService.remove(queryWrapper);
			QueryWrapper<AuditInnerCheckmethodItem> queryCheckWrapper = new QueryWrapper<>();
			queryCheckWrapper.in("checkid",deleteCheckId);
			auditInnerCheckmethodItemService.remove(queryCheckWrapper);
		}
	}

}
