package com.yeejoin.precontrol.controller;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yeejoin.precontrol.common.annotations.OpsLog;
import com.yeejoin.precontrol.common.dto.CommonPageableDto;
import com.yeejoin.precontrol.common.dto.HazardousWorkDto;
import com.yeejoin.precontrol.common.dto.HazardousWorkPageDto;
import com.yeejoin.precontrol.common.dto.InputItemDto;
import com.yeejoin.precontrol.common.entity.HazardousWork;
import com.yeejoin.precontrol.common.entity.HazardousWorkRefInputItem;
import com.yeejoin.precontrol.common.entity.InputItem;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.RiskWorkHazadousWork;
import com.yeejoin.precontrol.common.enums.OpsLogEnum;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.IHazardousWorkRefInputItemService;
import com.yeejoin.precontrol.common.service.IHazardousWorkService;
import com.yeejoin.precontrol.common.service.IInputItemService;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.service.IRiskWorkHazadousWorkService;
import com.yeejoin.precontrol.common.utils.FileHelper;
import com.yeejoin.precontrol.common.utils.StringUtil;
import com.yeejoin.precontrol.common.vo.HazardousWorkPageVo;
import com.yeejoin.precontrol.common.vo.HazardousWorkVo;
import com.yeejoin.precontrol.controller.publics.BaseController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 危险作业表
 *
 * @author duanwei
 * @date 2020-08-24
 */
@RestController
@Api(tags = "危险作业表Api")
@RequestMapping(value = "/hazardous-work", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class HazardousWorkController extends BaseController {

	/**
	 * 危险作业服务
	 */
	@Autowired
	IHazardousWorkService iHazardousWorkService;

	/**
	 * 检查项服务
	 */
	@Autowired
	IInputItemService iInputItemService;

	/**
	 * 用户服务
	 */
	@Autowired
	IPersonService iPersonService;

	/**
	 * 检查项关联危险作业服务
	 */
	@Autowired
	IHazardousWorkRefInputItemService iHazardousWorkRefInputItemService;

	@Autowired
	IRiskWorkHazadousWorkService iRiskWorkHazadousWorkService;

	/**
	 * 新增危险作业表
	 *
	 * @return
	 */
	@RequestMapping(value = "/saveOrUpdate", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "新增危险作业表", notes = "新增危险作业表")
	@OpsLog(value = OpsLogEnum.EDIT_HAZARDOUSWORK)
	public boolean saveOrUpdate(HttpServletRequest request, @RequestBody HazardousWorkDto hazardousWorkDto) {
		Person person = getPerson();
		HazardousWork hazardousWork = new HazardousWork();
		BeanUtils.copyProperties(hazardousWorkDto, hazardousWork);
		hazardousWork.setCPersonId(person.getId());
		if (hazardousWorkDto.getId() == null) {
			// 存储
			List<HazardousWork> list = iHazardousWorkService.list(
					new LambdaQueryWrapper<HazardousWork>().eq(HazardousWork::getName, hazardousWorkDto.getName()));
			if (StringUtil.isNotEmpty(list)) {
				throw new BaseException("作业名称重复,已经存在");
			}
			iHazardousWorkService.save(hazardousWork);
		} else {
			iHazardousWorkService.updateById(hazardousWork);
			deleteHazarDousWork(hazardousWork.getId());
		}
		saveHazarDousWork(hazardousWorkDto, hazardousWork);
		return true;
	}

	/**
	 * 根据id删除
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
	@ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
	public boolean deleteById(HttpServletRequest request, @PathVariable Long id) {
		// 删除风险作业
		iHazardousWorkService.removeById(id);
		// 根据风险作业id删除 检查项和关联关系
		deleteHazarDousWork(id);
		return true;
	}

	/**
	 * 根据ids删除 多个
	 *
	 * @return
	 */
	@RequestMapping(value = "/ids/{ids}", method = RequestMethod.DELETE)
	@ApiOperation(httpMethod = "DELETE", value = "根据ids删除", notes = "根据ids删除")
	@OpsLog(value = OpsLogEnum.DELETE_HAZARDOUSWORK)
	public boolean deleteById(HttpServletRequest request, @PathVariable List<Long> ids) {
		int count = iRiskWorkHazadousWorkService.count(
				new LambdaQueryWrapper<RiskWorkHazadousWork>().in(RiskWorkHazadousWork::getHarzadousWorkId, ids));
		if (count > 0) {
			throw new BaseException("被风险作业引用,无法删除");
		}
		for (Long id : ids) {
			// 删除风险作业
			iHazardousWorkService.removeById(id);
			// 根据风险作业id删除 检查项和关联关系
			deleteHazarDousWork(id);
		}
		return true;
	}

	/**
	 * 根据id查询
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
	public Object selectById(HttpServletRequest request, @PathVariable Long id) {
		HazardousWorkVo hazardousWorkVo = iHazardousWorkService.getHazardousWorkVo(id);
		return hazardousWorkVo;
	}

	/**
	 * 列表分页查询
	 *
	 * @return
	 */
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
	public Object listPage(@ApiParam(value = "分页条件 isAll=0 具体分页必传") CommonPageableDto pageable,
			@ApiParam(value = "查询参数") HazardousWorkPageDto hazardousWorkPageDto,
			@ApiParam(value = "类型 0查询列表 1 导出列表") @RequestParam Long operType,
			@ApiParam(value = "查询Ids") @RequestParam(required = false) List<Long> ids, HttpServletResponse response) {
		String fileName = UUID.randomUUID().toString() + ".xls";
		if (StringUtil.isNotEmpty(ids)) {
			hazardousWorkPageDto.setIds(ids);
		}
		IPage<HazardousWorkPageVo> page = iHazardousWorkService.listByPage(pageable, hazardousWorkPageDto);
		if (operType == 1) {
			List<HazardousWorkPageVo> excelList = page.getRecords();
			for (HazardousWorkPageVo hazardousWorkPageVo : excelList) {
				Long cPersonId = hazardousWorkPageVo.getCreatePersonId();
				Person person = iPersonService.getById(cPersonId);
				if (person != null) {
					hazardousWorkPageVo.setCreatePersonName(person.getName());
				}
			}
			FileHelper.exportExcel(excelList, "危险作业管理", "危险作业管理信息", HazardousWorkPageVo.class, fileName, response);
			return null;
		} else {
			return page;
		}
	}

	@RequestMapping(value = "/list-all", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "下拉列表查询", notes = "下拉列表查询")
	public List<HazardousWork> listAll() {
		return iHazardousWorkService.list();
	}

	/**
	 * 保存风险作业和检查项
	 *
	 * @param hazardousWorkDto
	 */
	public void saveHazarDousWork(HazardousWorkDto hazardousWorkDto, HazardousWork hazardousWork) {
		List<InputItemDto> inputItemDtos = hazardousWorkDto.getInputItemDtos();
		if (StringUtil.isNotEmpty(inputItemDtos)) {
			inputItemDtos.forEach(inputItemDto -> {
				InputItem inputItem = new InputItem();
				BeanUtils.copyProperties(inputItemDto, inputItem);
				iInputItemService.save(inputItem);
				HazardousWorkRefInputItem hazardousWorkRefInputItem = new HazardousWorkRefInputItem();
				hazardousWorkRefInputItem.setHazardousWorkId(hazardousWork.getId());
				hazardousWorkRefInputItem.setInputItemId(inputItem.getId());
				hazardousWorkRefInputItem.setOrders(0L);
				iHazardousWorkRefInputItemService.save(hazardousWorkRefInputItem);
			});
		}
	}

	/**
	 * 根据风险作业id删除 检查项和关联关系
	 *
	 * @param id
	 */
	public void deleteHazarDousWork(Long id) {
		// 删除检查项
		List<HazardousWorkRefInputItem> list = iHazardousWorkRefInputItemService.list(
				new LambdaQueryWrapper<HazardousWorkRefInputItem>().select(HazardousWorkRefInputItem::getInputItemId)
						.eq(HazardousWorkRefInputItem::getHazardousWorkId, id));
		if (StringUtil.isNotEmpty(list)) {
			List<Long> collect = list.stream().map(l -> l.getInputItemId()).collect(Collectors.toList());
			iInputItemService.removeByIds(collect);
		}

		// 删除关联关系
		List<HazardousWorkRefInputItem> hazardousWorkRefInputItemServices = iHazardousWorkRefInputItemService
				.list(new LambdaQueryWrapper<HazardousWorkRefInputItem>().select(HazardousWorkRefInputItem::getId)
						.eq(HazardousWorkRefInputItem::getHazardousWorkId, id));
		if (StringUtil.isNotEmpty(hazardousWorkRefInputItemServices)) {
			List<Long> collect = hazardousWorkRefInputItemServices.stream().map(l -> l.getId())
					.collect(Collectors.toList());
			iHazardousWorkRefInputItemService.removeByIds(collect);
		}
	}
}
