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

import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.entity.SearchFilter;
import com.sw.mes.core.entity.SearchFilter.Operator;
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.DynamicSpecifications;
import com.sw.mes.core.utils.PageUtil;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.mmcs.service.MMcsInterfaceService;
import com.sw.mes.yb.production.dto.*;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
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.validation.Valid;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@RestController
@RequestMapping("/productionCircleWeight")
@Slf4j
@Api(description = "圆棒生产配料重量方案接口")
public class ProductionCircleWeightController {
	@Autowired
	ModelMapper modelMapper;

	@Autowired
	private ProductionCircleWeightService productionCircleWeightService;

	@Autowired
	private ProductionCircleWeightDetailService productionCircleWeightDetailService;

	@Autowired
	private ProductionCircleRecipeService productionCircleRecipeService;

	@Autowired
	private ProductionCircleDosingListService productionCircleDosingListService;

	@Autowired
	private MMcsInterfaceService mMcsInterfaceService;

	@ApiOperation(value = "分页查询圆棒生产配料重量方案列表")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
		@ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
		@ApiImplicitParam(name = "search_EQ_status", value = "状态", dataType = "integer", paramType = "query"),
		@ApiImplicitParam(name = "search_LIKE_weightName", value = "配方名称", dataType = "string", paramType = "query"),
		@ApiImplicitParam(name = "search_LIKE_version", value = "配方版本", dataType = "string", paramType = "query"),
	})
	@GetMapping("/listByPage")
	public Result<ResponsePage<ProductionCircleWeightDto>> listByPage(ServletRequest request,@ApiIgnore RequestPage requestPage) {

		SearchFilter filter = new SearchFilter("del",Operator.EQ,0);//查询未删除的列表

		Specification<ProductionCircleWeight> specification = DynamicSpecifications.bySearchFilter(request, ProductionCircleWeight.class,filter);
    	Page<ProductionCircleWeight> page = productionCircleWeightService.findByExample(specification, PageUtil.createPageable(requestPage));
		List<ProductionCircleWeightDto> list = page.getContent().stream()
                .map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
//		if (list.size() > 0){
//			for (int q = 0;q< list.size();q++){
//				ProductionCircleWeightDetail obj = productionCircleWeightDetailService.getRecipeWeightDetailByKind
//						(list.get(q).getWeightName(),list.get(q).getWeightCode(),list.get(q).getVersion());
//				list.get(q).setSuppliesHeight(obj == null ? null :obj.getSuppliesHeight());
//				list.get(q).setSuppliesSize(obj == null ? null :obj.getSuppliesSize());
//			}
//		}
		ResponsePage responsePage = new ResponsePage(list, page.getTotalElements());
        return ResultGenerator.success(responsePage);
	}

	@ApiOperation(value = "获取所有圆棒生产配料重量方案")
	@GetMapping("/listAll")
	public Result<List<ProductionCircleWeightDto>> listAll(ServletRequest request) {

		SearchFilter filter = new SearchFilter("del",Operator.EQ,0);//查询未删除的列表

		Specification<ProductionCircleWeight> specification = DynamicSpecifications.bySearchFilter(request, ProductionCircleWeight.class,filter);
		List<ProductionCircleWeight> productionCircleWeights = productionCircleWeightService.findByExampleSort(specification, null);
		List<ProductionCircleWeightDto> productionCircleWeightDtos = productionCircleWeights.stream()
					.map(productionCircleWeight -> toLazyDto(productionCircleWeight))
					.collect(Collectors.toList());
		return ResultGenerator.success(productionCircleWeightDtos);
	}

	@ApiOperation(value = "圆棒生产配料重量方案详细信息")
	@GetMapping("/{id}")
	public Result<ProductionCircleWeightDto> get(@PathVariable @ApiParam(value="圆棒生产配料重量方案id") Long id) {
		ProductionCircleWeight productionCircleWeight = productionCircleWeightService.get(id);
		if (null == productionCircleWeight) {
            return ResultGenerator.fail("该圆棒生产配料重量方案不存在");
        }
		return ResultGenerator.success(toEagerDto(productionCircleWeight));
	}

    @ApiOperation(value = "更新圆棒生产配料重量方案")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "圆棒生产配料重量方案") ProductionCircleWeightDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        dto.setUserId(BaseContextHandler.getUserID());
        dto.setUserName(BaseContextHandler.getUsername());
		dto.setCreateTime(new Date());
        if (dto.getId() != null){
        	dto.setVersion(dto.getVersion()+1);
        	dto.setId(null);
		}else {
        	dto.setVersion(null);
		}
        try {
            ProductionCircleWeight obj = fromDto(dto);
			productionCircleWeightService.saveOrUpdate(obj);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

	@ApiOperation(value = "圆棒生产配料重量方案详情")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "weightName", value = "重量方案名称", dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "weightCode", value = "重量方案编码", dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "version", value = "版本", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/getRecipeWeightDetail")
	public Result<List> getRecipeDetails(String weightName,String weightCode,Integer version) {
		List<ProductionCircleWeightDtoVo> list = productionCircleWeightDetailService.getRecipeWeightDetail(weightName,weightCode,version);
		if(list ==null || list.size() <= 0){
			return ResultGenerator.fail("该圆棒生产配料列表详情不存在");
		}
		return ResultGenerator.success(list);
	}


	@ApiOperation(value = "更新圆棒生产配料重量方案详情")
	@PostMapping("/updateWeightDetail")
	public @ResponseBody
	Result WeightDetail(@RequestBody @Valid @ApiParam(value = "圆棒生产配料重量方案详情") List<ProductionCircleWeightDetail> data) {
		if (data == null) {
            return ResultGenerator.fail("最少也要添加一条数据");
        }
		try {
//			for (ProductionCircleWeightDetail productionCircleWeightDetail : data) {
//				if (productionCircleWeightDetail.getWeight() < 0) {
//					return ResultGenerator.fail("数据填写有误，重量不可为负数");
//				}
//				if (!StringUtils.isEmpty(productionCircleWeightDetail.getSuppliesSize()) && Integer.parseInt(productionCircleWeightDetail.getSuppliesSize()) < 0) {
//					return ResultGenerator.fail("数据填写有误，坩埚尺寸不可为负数");
//				}
//				if (!StringUtils.isEmpty(productionCircleWeightDetail.getSuppliesHeight()) && Integer.parseInt(productionCircleWeightDetail.getSuppliesHeight()) < 0) {
//					return ResultGenerator.fail("数据填写有误，坩埚高度不可为负数");
//				}
//			}
//			//根据配方用途分组
//			Map<String, List<ProductionCircleWeightDetail>> collect = data.stream().collect(Collectors.groupingBy(s));
//			List<String> list =new ArrayList<>();
//			for (int q = 0;q < collect.size(); q++){
//				list.addAll(collect.keySet());
//				//根据配方种类分组
//				Map<String, List<ProductionCircleWeightDetail>> collect1 = collect.get(list.get(q)).stream().collect(Collectors.groupingBy(ma));
//				List<String> list2 =new ArrayList<>();
//				list2.addAll(collect1.keySet());
//				for (int w = 0;w < collect1.size(); w++){
//					List<ProductionCircleWeightDetail> list1 = collect1.get(list2.get(w));
//					int ageSum = list1.stream().collect(Collectors.summingInt(ProductionCircleWeightDetail::getWeight));
//					if (ageSum != list1.get(0).getGross()){
//						return ResultGenerator.fail("重量方案填写不正确");
//					}
//
//				}
//			}
			//新增时判断名称和code是否唯一
			Integer newestVersion = 0;
			if(data.get(0).getVersion() == 0){
				String weightName = data.get(0).getWeightName();
				String weightCode = data.get(0).getWeightCode();
				if (StringUtils.isBlank(weightName) || StringUtils.isBlank(weightCode)){
					return ResultGenerator.fail("方案名称和编码不允许空字符");
				}
				List<ProductionCircleWeight> lists = productionCircleWeightService.findAll();
				List<String> weightNames = lists.stream().filter(temp->temp.getDel() == 0).map(temp->temp.getWeightName()).collect(Collectors.toList());
				if(weightNames.contains(weightName)){
					return ResultGenerator.fail("该方案名称已存在");
				}
				if(null != lists && lists.size()>0){
					List<String> weightCodes = lists.stream().filter(temp->temp.getDel() == 0).map(temp->temp.getWeightCode()).collect(Collectors.toList());
					if(weightCodes.contains(weightCode)){
						return ResultGenerator.fail("该方案编码已存在");
					}
				}
			}else{
				//查出目前的最新版本号
				newestVersion = productionCircleWeightService.getNewestVersion(data.get(0).getWeightName(),data.get(0).getWeightCode());
			}
			ProductionCircleWeight obj = new ProductionCircleWeight();
			obj.setWeightName(data.get(0).getWeightName());
			obj.setWeightCode(data.get(0).getWeightCode());
			obj.setVersion(newestVersion+1);
			obj.setUserId(BaseContextHandler.getUserID());
			obj.setUserName(BaseContextHandler.getUsername());
			obj.setCreateTime(new Date());
			productionCircleWeightService.saveOrUpdate(obj);
			for (ProductionCircleWeightDetail datum : data) {
				datum.setId(null);
				datum.setVersion(newestVersion+1);
				datum.setWeightId(obj.getId());
				datum.setCreateDate(new Date());
				productionCircleWeightDetailService.saveOrUpdate(datum);
			}

			//下发重量方案
			//mMcsInterfaceService.issueWeightSchemeInterface();


			return ResultGenerator.success();
		} catch (Exception e) {
			return ResultGenerator.fail(e.getMessage());
		}
	}

	@ApiOperation(value = "更改配料重量方案状态")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "生产配料id", value = "id", dataType = "integer", paramType = "query"),
			@ApiImplicitParam(name = "当前状态", value = "status", dataType = "integer", paramType = "query"),
	})
	@PostMapping("/updateStatus")
	public Result updateStatus( @RequestParam Long id,@RequestParam Integer status) {

		try {
			productionCircleWeightService.updateStatus(id, status);
		}catch(RuntimeException e){
			return ResultGenerator.fail(e.getMessage());
		}
		//下发重量方案
		//mMcsInterfaceService.issueWeightSchemeInterface();

		return ResultGenerator.success();
	}


	@ApiOperation(value = "通过id获取配料方案物料列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "配方列表id", dataType = "integer", paramType = "query"),

	})
	@GetMapping("/getRecipeDetailByRecipeId")
	public Result<List> getRecipeDetailByRecipeId(Long id) {
		List<ProductionCircleWeightDtoVo> map = productionCircleWeightDetailService.getRecipeWeightDetailById(id);
		if (0 == map.size()) {
            return ResultGenerator.fail("改配方还没有数据");
        }
		return ResultGenerator.success(map);
	}

	@ApiOperation(value = "圆棒生产配料重量方案详情")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "重量方案id", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/getRecipeWeightDetailById")
	public Result<List> getRecipeDetails(Long id) {
		List<ProductionCircleWeightDtoVo> map = productionCircleWeightDetailService.getRecipeWeightDetailById(id);
		if (0 == map.size()) {
            return ResultGenerator.fail("该圆棒生产配料列表详情不存在");
        }
		return ResultGenerator.success(map);
	}

	@ApiOperation(value = "删除圆棒生产配料重量方案")
	@PostMapping("/delete")
	public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
		for (Long id : ids) {
			List<ProductionCircleDosingList> list = productionCircleDosingListService.getObjectByRecipeOId(id);
			if (list != null && list.size() > 0){
				return ResultGenerator.fail("该配方已经在产品中，不可以删除");
			}else {
				ProductionCircleWeight obj = productionCircleWeightService.get(id);
				if (obj != null){
					productionCircleWeightDetailService.deleteHistory(obj.getWeightName(),obj.getWeightCode(),obj.getVersion());
				}
				productionCircleWeightService.deleteDel(id);
			}
		}

		//下发重量方案
		//mMcsInterfaceService.issueWeightSchemeInterface();

		return ResultGenerator.success();
	}

	@ApiOperation(value = "新增根据重量方案id，单通重量，配方用途回去重量详情")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "生产配料id", value = "id", dataType = "integer", paramType = "query"),
			@ApiImplicitParam(name = "配方用途", value = "recipePurpose", dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "单通重量", value = "weight", dataType = "integer", paramType = "query"),
			@ApiImplicitParam(name = "产品配方id", value = "pId", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/getWeightByRecipePurpose")
	public Result updateStatus( @RequestParam Long id,@RequestParam String recipePurpose,@RequestParam Integer weight,@RequestParam Long pId) {

		List<ProductionCircleWeightDetail> list = productionCircleWeightDetailService.getWeightByRecipePurpose(id,recipePurpose,weight,pId);
		return ResultGenerator.success(list);
	}

	public ProductionCircleWeightDto toLazyDto(ProductionCircleWeight entity) {
		return modelMapper.map(entity, ProductionCircleWeightDto.class);
	}

	public ProductionCircleWeightDto toEagerDto(ProductionCircleWeight entity) {
		return modelMapper.map(entity, ProductionCircleWeightDto.class);
	}

	public ProductionCircleWeight fromDto(ProductionCircleWeightDto dto) {
		return modelMapper.map(dto, ProductionCircleWeight.class);
	}

	public ProductionCircleWeightDetail fromDto(ProductionCircleWeightDetailDto dto) {
		return modelMapper.map(dto, ProductionCircleWeightDetail.class);
	}
//	Function<ProductionCircleWeightDetail, String> s = new Function<ProductionCircleWeightDetail, String>() {
//
//		@Override
//		public String apply(ProductionCircleWeightDetail t) {
//			Object object = t.getRecipePurpose();
//			return object.toString();
//		}
//	};

//	Function<ProductionCircleWeightDetail, String>  ma = new Function<ProductionCircleWeightDetail, String>() {
//
//		@Override
//		@Deprecated
//		public String apply(ProductionCircleWeightDetail t) {
//			Object object = t.getGross();
//			return object.toString();
//			return null;
//		}
//	};

}
