package com.sw.mes.yb.pc.controller;

import com.sw.mes.agv.constant.IPCRequest;
import com.sw.mes.agv.entity.MonitorEquipmentCharge;
import com.sw.mes.agv.service.MonitorEquipmentChargeService;
import com.sw.mes.core.entity.SearchFilter;
import com.sw.mes.core.response.ResponsePage;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.*;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.yb.pc.dto.OutputChargeDto;
import com.sw.mes.yb.pc.dto.StoreMixInfoDto;
import com.sw.mes.yb.pc.dto.StoreMixInfoItemDto;
import com.sw.mes.yb.pc.entity.StoreMixInfo;
import com.sw.mes.yb.pc.entity.StoreMixInfoItem;
import com.sw.mes.yb.pc.service.CrucibleCheckDataService;
import com.sw.mes.yb.pc.service.StoreMixInfoItemService;
import com.sw.mes.yb.pc.service.StoreMixInfoService;
import com.sw.mes.utils.CodeUtil;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("pc/storeMixInfo")
@Slf4j
@Api(description = "配料登记")
public class StoreMixInfoController {

	@Autowired
    ModelMapper modelMapper;

	@Autowired
	private StoreMixInfoService storeMixInfoService;

	@Autowired
	private StoreMixInfoItemService storeMixInfoItemService;

//	@Autowired
//	private StoreOutputApplyService storeOutputApplyService;
//
//	@Autowired
//	private StoreOutputApplyItemService storeOutputApplyItemService;

	@Autowired
	private MaterialModelService materialModelService;

	@Autowired
	private CrucibleCheckDataService crucibleCheckDataService;

//	@Autowired
//	private OperationRecodService operationRecodService;

	@Autowired
    private MonitorEquipmentChargeService monitorChargeService;

	@ApiOperation(value = "分页查询列表")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
		@ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/listByPage")
	public Result<ResponsePage<StoreMixInfoDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
		Specification<StoreMixInfo> specification = DynamicSpecifications.bySearchFilter(request, StoreMixInfo.class);
    	Page<StoreMixInfo> page = storeMixInfoService.findByExample(specification, PageUtil.createPageable(requestPage));
		List<StoreMixInfoDto> dtos = page.getContent().stream()
                .map(entity -> toEagerDto(entity))
                .collect(Collectors.toList());
		ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
	}

	@ApiOperation(value = "获取所有列表")
	@GetMapping("/listAll")
	public Result<List<StoreMixInfoDto>> listAll(ServletRequest request) {
		Specification<StoreMixInfo> specification = DynamicSpecifications.bySearchFilter(request, StoreMixInfo.class);
		List<StoreMixInfo> storeMixInfos = storeMixInfoService.findByExampleSort(specification, null);
		List<StoreMixInfoDto> storeMixInfoDtos = storeMixInfos.stream()
					.map(storeMixInfo -> toLazyDto(storeMixInfo))
					.collect(Collectors.toList());
		return ResultGenerator.success(storeMixInfoDtos);
	}


	@ApiOperation(value = "分页查询列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
			@ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/listInfoByPage")
	public Result<ResponsePage<OutputChargeDto>> listInfoByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
		Specification<MonitorEquipmentCharge> specification = DynamicSpecifications.bySearchFilter(request, MonitorEquipmentCharge.class,
				new SearchFilter("sixInfo", SearchFilter.Operator.EQ, 0));
		requestPage.setOrderField("preChargeTime");
		requestPage.setOrderDirection(RequestPage.ORDER_DIRECTION_ASC);
		Page<MonitorEquipmentCharge> page = monitorChargeService.findByExample(specification, PageUtil.createPageable(requestPage));

		List<OutputChargeDto> dtos = page.getContent().stream()
				.map(this::toEagerDtoSapOrder)
				.collect(Collectors.toList());
		ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
		return ResultGenerator.success(responsePage);
	}

	@ApiOperation(value = "详细信息")
	@GetMapping("/{id}")
	public Result<StoreMixInfoDto> get(@PathVariable @ApiParam(value="配料主表id") Integer id) {
		StoreMixInfo storeMixInfo = storeMixInfoService.get(id);
		if (null == storeMixInfo) {
            return ResultGenerator.fail("该对象不存在");
        }
		return ResultGenerator.success(toEagerDto(storeMixInfo));
	}

	@ApiOperation(value = "更新查询接口")
	@GetMapping("/update")
	public Result<StoreMixInfoDto> update(@ApiParam(value="配料主表id") Integer id) {
		StoreMixInfo storeMixInfo = storeMixInfoService.get(id);
		if (null == storeMixInfo) {
            return ResultGenerator.fail("该对象不存在");
        }
		return ResultGenerator.success(toEagerDto(storeMixInfo));
	}

	@ApiOperation(value = "更换")
	@PostMapping("/change")
	public Result change(@RequestBody @Valid @ApiParam(value = "Dto对象") StoreMixInfoDto storeMixInfoDto, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
		}
		if (StringUtils.isBlank(storeMixInfoDto.getCode())) {
			return ResultGenerator.fail("坩埚编号不能为空！");
		}
		try {
			storeMixInfoService.change(storeMixInfoDto);
		} catch (Exception e) {
			return ResultGenerator.fail(e.getMessage());
		}
		return ResultGenerator.success();
	}

	@ApiOperation(value = "更换设备")
	@PostMapping("/updateDevice")
	public Result updateDevice(String lotNo, String newDeviceNo, String newLotNo) {


		return ResultGenerator.success();
	}

	@ApiOperation(value = "更换坩埚编号")
	@PostMapping("/updateCode")
	public Result updateCode(String lotNo, String newCode) {


		return ResultGenerator.success();
	}

	@ApiOperation(value = "创建")
	@PostMapping("/create")
	public Result create(@RequestBody @Valid @ApiParam(value = "Dto对象") StoreMixInfoDto storeMixInfoDto, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
		}
		if (StringUtils.isBlank(storeMixInfoDto.getDeviceNo())) {
			return ResultGenerator.fail("设备编号不能为空！");
		}
		if (StringUtils.isBlank(storeMixInfoDto.getDopant())) {
			return ResultGenerator.fail("掺杂剂不能为空！");
		}
		if (StringUtils.isBlank(storeMixInfoDto.getProductType())) {
			return ResultGenerator.fail("产品规格不能为空！");
		}
		if (StringUtils.isBlank(storeMixInfoDto.getTestTypeValue())) {
			return ResultGenerator.fail("实验类型不能为空！");
		}
		if (StringUtils.isBlank(storeMixInfoDto.getCode())) {
			return ResultGenerator.fail("坩埚编号不能为空！");
		}
		if (StringUtils.isBlank(storeMixInfoDto.getLotNo())) {
			return ResultGenerator.fail("炉次号不能为空！");
		}
		if(StringUtils.isBlank(storeMixInfoDto.getDeviceNo())){
			return ResultGenerator.fail("设备编号不能为空！");
		}
		if (storeMixInfoDto.getDeviceNo().length() != 3 ) {
			return ResultGenerator.fail("设备编号长度错误");
		}
		if(!storeMixInfoDto.getLotNo().contains(storeMixInfoDto.getDeviceNo())){
			return ResultGenerator.fail("设备编号与炉次号不对应");
		}
		Long count = storeMixInfoService.countByCode(storeMixInfoDto.getCode());
		if (count != null && count > 0) {
			return ResultGenerator.fail("坩埚编号[" + storeMixInfoDto.getCode() + "]已存在配料信息");
		}
		count = storeMixInfoService.countByLotNo(storeMixInfoDto.getLotNo());
		if (count != null && count > 0) {
			return ResultGenerator.fail("炉次号[" + storeMixInfoDto.getLotNo() + "]已存在配料信息");
		}
		try {
			storeMixInfoService.saveOrUpdate(storeMixInfoDto);
		} catch (Exception e) {
			return ResultGenerator.fail(e.getMessage());
		}
		String preNo = CodeUtil.getFullLotNo(storeMixInfoDto.getDopant(), storeMixInfoDto.getProductType(),
				storeMixInfoDto.getLotNo(), storeMixInfoDto.getTestTypeValue());
		return ResultGenerator.success(preNo);
	}

	@ApiOperation(value = "更新")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "Dto对象") StoreMixInfoDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
            StoreMixInfo entity = storeMixInfoService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            StoreMixInfo entityfromFto = fromDto(dto);
			BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
			storeMixInfoService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

	@ApiOperation(value = "删除")
	@PostMapping("/delete")
	public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Integer[] ids,ServletRequest request) {
		try {
			for (Integer id : ids) {
				StoreMixInfo storeMixInfo = storeMixInfoService.get(id);
				storeMixInfoService.deleteByMainId(id);
			//	operationRecodService.saveOperationRecod(storeMixInfo, request.getLocalAddr(), "删除", "配料记录");
//			StoreMixInfo mixInfo = storeMixInfoService.get(id);
//			if (mixInfo != null) {
//				CrucibleCheckData crucibleCheckData = crucibleCheckDataService.getByCode(mixInfo.getCode());
//				if (crucibleCheckData != null) {
//					return ResultGenerator.fail("坩埚[" + mixInfo.getCode() + "]已点检完成！");
//				}
//				MonitorEquipmentCharge charge = monitorChargeService.getByName(mixInfo.getDeviceNo());
//				if (charge != null) {
//				    charge.setSlingState(IPCRequest.ZHUANGLIAOHUJIAO);
//				    charge.setSixInfo(0);
//				    monitorChargeService.saveOrUpdate(charge);
//                }
//				storeMixInfoService.delete(id);
//				storeMixInfoItemService.deleteByStoreMixInfo_Id(id);
//			}
			}
		}catch (Exception e){
			return ResultGenerator.fail(e.getMessage());
		}
		return ResultGenerator.success();
	}

	@ApiOperation(value = "取消配料")
	@PostMapping("/cancel")
	public Result cancel(ServletRequest request,@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) throws Exception {
		String ip = request.getLocalAddr();
		for (Long id : ids) {
			MonitorEquipmentCharge entity = monitorChargeService.get(id);
			if (entity != null && 0 == entity.getSixInfo()) {
				entity.setSlingState(IPCRequest.ZHUANGLIAOHUJIAO);
				entity.setSixInfo(1);
				monitorChargeService.saveOrUpdate(entity);

				//operationRecodService.saveOperationRecod( entity, ip, "删除","待配料");
			}
		}
		return ResultGenerator.success();
	}

	@ApiOperation(value = "打印炉次号接口")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "lotNo", value = "炉次号", dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "num", value = "打印数", dataType = "Integer", paramType = "query")
	})
	@GetMapping("/printLotNo")
	public Result printLotNo(HttpServletRequest request, String lotNo, Integer num) {
		if (StringUtils.isBlank(lotNo)) {
			return ResultGenerator.fail("炉次号不能为空！");
		}

		String preNo = lotNo;
		if (lotNo.length() < 10) {
			StoreMixInfo mixInfo = storeMixInfoService.findByLotNo(lotNo);
			if (mixInfo == null) {
				return ResultGenerator.fail("炉次号[" + lotNo + "]配料信息不存在！");
			}
			preNo = CodeUtil.getFullLotNo(mixInfo.getDopant(), mixInfo.getProductType(), lotNo, mixInfo.getTestTypeValue());
		}
		if (num == null || num <= 0) {
			num = 1;
		}
//        String printUrl;
//        try {
//            printUrl = getPrintUrl(request);
//        } catch (Exception e) {
//            return ResultGenerator.fail(e.getMessage());
//        }
		try {
		// todo 	print(printUrl, num, preNo);
		} catch (Exception e) {
			return ResultGenerator.fail(e.getMessage());
		}
		return ResultGenerator.success();
	}

//	public void print(String printUrl, Integer num, String preNo) throws Exception {
//		Map<String, Object> returnMap = printerService.printByUrl(printUrl, 1, num, preNo);
//
//		if (returnMap.get("status") != null) {
//			Integer status = (Integer) returnMap.get("status");
//			if (0 == status) {
//				String msg = (String) returnMap.get("msg");
//				throw new Exception(msg);
//			}
//		}
//	}

//	public String getPrintUrl(HttpServletRequest request) throws Exception {
//		Printer printer = null;
//		String url = request.getHeader("X-Real-IP");
//		log.info("打印机IP="+url);
//		if (StringUtils.isNotBlank(url)) {
//			printer = printerService.getByPositionCode(url);
//		}
//		if (printer == null) {
//			printer = printerService.getByPositionCode("lotNo");
//		}
//		if (printer == null) {
//			throw new Exception("未找到配置打印机！");
//		}
//		if (StringUtils.isBlank(printer.getUrl())) {
//			throw new Exception("打印机配置信息异常！");
//		}
//		return printer.getUrl();
//	}

	public StoreMixInfoDto toLazyDto(StoreMixInfo entity) {
		return modelMapper.map(entity, StoreMixInfoDto.class);
	}

	public StoreMixInfoDto toEagerDto(StoreMixInfo entity) {
		StoreMixInfoDto dto = modelMapper.map(entity, StoreMixInfoDto.class);
		//填充配料明细
		List<StoreMixInfoItemDto> storeMixInfoItemDtos=null;
		if(null!=dto.getId()){
			List<StoreMixInfoItem> storeMixInfoItems = storeMixInfoItemService.findByStoreMixInfo_Id(dto.getId());
			storeMixInfoItemDtos = storeMixInfoItems.stream().map(storeMixInfoItem ->
					modelMapper.map(storeMixInfoItem, StoreMixInfoItemDto.class)).collect(Collectors.toList());
		}
		dto.setStoreMixInfoItemDtos(storeMixInfoItemDtos);
		return dto;
	}

	public StoreMixInfo fromDto(StoreMixInfoDto dto) {
		return modelMapper.map(dto, StoreMixInfo.class);
	}


	private OutputChargeDto toEagerDtoSapOrder(MonitorEquipmentCharge entity) {
		OutputChargeDto dto = modelMapper.map(entity, OutputChargeDto.class);
		String sapOrderNo = storeMixInfoService.findSapOrderNoByDeviceNo(dto.getName());
		dto.setSapOrderNo(sapOrderNo);
		return dto;
	}

}
