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

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.yb.turnstore.dto.TurnstoreOutDto;
import com.sw.mes.yb.turnstore.dto.TurnstoreOutItemDto;
import com.sw.mes.yb.turnstore.dto.TurnstoreOutPostDto;
import com.sw.mes.yb.turnstore.entity.TurnstoreOut;
import com.sw.mes.yb.turnstore.entity.TurnstoreOutItem;
import com.sw.mes.yb.turnstore.service.TurnstoreOutItemService;
import com.sw.mes.yb.turnstore.service.TurnstoreOutService;
import com.sw.mes.yb.turnstore.statics.EnumValues;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
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.List;
import java.util.stream.Collectors;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@RestController
@RequestMapping("/turnstoreOut")
@Slf4j
@Api(description = "周转库出库申请接口")
public class TurnstoreOutController {
	@Autowired
    ModelMapper modelMapper;

	@Autowired
	private TurnstoreOutService turnstoreOutService;

	@Autowired
	private TurnstoreOutItemService turnstoreOutItemService;



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

	@ApiOperation(value = "获取所有周转库出库申请")
	@GetMapping("/listAll")
	public Result<List<TurnstoreOutDto>> listAll(ServletRequest request) {
		Specification<TurnstoreOut> specification = DynamicSpecifications.bySearchFilter(request, TurnstoreOut.class);
		List<TurnstoreOut> turnstoreOuts = turnstoreOutService.findByExampleSort(specification, null);
		List<TurnstoreOutDto> turnstoreOutDtos = turnstoreOuts.stream()
					.map(turnstoreOut -> toLazyDto(turnstoreOut))
					.collect(Collectors.toList());
		return ResultGenerator.success(turnstoreOutDtos);
	}

	@ApiOperation(value = "周转库出库申请详细信息")
	@GetMapping("/{id}")
	public Result<TurnstoreOutPostDto> get(@PathVariable @ApiParam(value="周转库出库申请id") Integer id) {
		TurnstoreOut turnstoreOut = turnstoreOutService.get(id);
		if (null == turnstoreOut) {
            return ResultGenerator.fail("该周转库出库申请不存在");
        }
		TurnstoreOutPostDto entity = fromDto(turnstoreOut);
		List<TurnstoreOutItem> items = turnstoreOutItemService.getItemsByOutId(id);
		entity.setItems(toDto(items));
		return ResultGenerator.success(entity);
	}

	@ApiOperation(value = "创建周转库出库申请")
	@PostMapping("/create")
	public Result create(@RequestBody @Valid @ApiParam(value = "周转库出库申请对象") TurnstoreOutPostDto turnstoreOutPostDto, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
		}
		if(turnstoreOutPostDto==null){
			return ResultGenerator.fail("出库申请错误");
		}
		if(turnstoreOutPostDto.getItems()==null||turnstoreOutPostDto.getItems().size()==0){
			return ResultGenerator.fail("出库申请明细错误");
		}
		TurnstoreOut turnstoreOut = fromDto(turnstoreOutPostDto);
		List<TurnstoreOutItem> items = fromDto(turnstoreOutPostDto.getItems());
		//turnstoreInService.saveOrUpdate(turnstoreIn);
		turnstoreOutService.createOut(turnstoreOut,items);
		return ResultGenerator.success();
	}

	//方棒AGV运走调用接口，直接出库
	@ApiOperation(value = "方棒AGV运走调用接口，直接出库")
	@PostMapping("/outBySectionNos")
	public Result outBySectionNos(@RequestBody @Valid @ApiParam(value = "晶段编号list") List<String> list){
		turnstoreOutService.outBySectionNos(list);
		return ResultGenerator.success();
	}

    @ApiOperation(value = "更新周转库出库申请")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "周转库出库申请") TurnstoreOutPostDto turnstoreOutPostDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (turnstoreOutPostDto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
            TurnstoreOut entity = turnstoreOutService.get(turnstoreOutPostDto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
		if(turnstoreOutPostDto.getItems()==null||turnstoreOutPostDto.getItems().size()==0){
			return ResultGenerator.fail("出库申请明细错误");
		}
		if(entity.getState().equals(EnumValues.OutState.已出库.getValue())){
			return ResultGenerator.fail("已出库申请不能编辑");
		}
        try {
			TurnstoreOut turnstoreOut = fromDto(turnstoreOutPostDto);
			List<TurnstoreOutItem> items = fromDto(turnstoreOutPostDto.getItems());
			turnstoreOutService.updateOut(turnstoreOut,items);
            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) {
		for (Integer id : ids) {
				turnstoreOutService.deleteOut(id);
		}
		return ResultGenerator.success();
	}


	//周转库操作确认出库
	@ApiOperation(value = "周转库操作确认出库")
	@PostMapping("/confirmOut")
	public Result confirmOut(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Integer[] ids, @ApiParam(value = "操作人", type = "query") @RequestParam String user) {
		for (Integer id : ids) {
			turnstoreOutService.confirmOut(id, user);
		}
		return ResultGenerator.success();
	}

	//周转库操作退回出库
	@ApiOperation(value = "周转库操作退回出库")
	@PostMapping("/backOut")
	public Result backOut(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Integer[] ids, @ApiParam(value = "操作人", type = "query") @RequestParam String user) {
		for (Integer id : ids) {
			turnstoreOutService.backOut(id, user);
		}
		return ResultGenerator.success();
	}


	@ApiOperation(value = "查询重复已经存在的单晶详情")
	@PostMapping("/repetition")
	public Result repetition(@RequestBody @Valid @ApiParam(value = "周转库出库申请对象") TurnstoreOutPostDto turnstoreOutPostDto, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
		}
		StringBuilder stringBuilder=new StringBuilder();
		List<TurnstoreOutItem> items = fromDto(turnstoreOutPostDto.getItems());
		if(items!=null&&!items.isEmpty()){
			for(TurnstoreOutItem item:items){
				String section=item.getSectionNo();
				List<TurnstoreOutItem>list=turnstoreOutItemService.findBySectionNoOrderByIdDesc(section);
				if(!list.isEmpty()){
					if(item.getId()==null){
						stringBuilder.append(section+",");
					}else if(list.size()>1||!list.get(0).getId().equals(item.getId())) {
						stringBuilder.append(section+",");
					}
				}
			}
		}
		String restr=stringBuilder.toString();
		if(StringUtils.isNotBlank(restr)){
			restr=restr+"单晶已出库,请确认单晶是否再次出库!";
			return ResultGenerator.success(restr);
		}
		return ResultGenerator.success();
	}


	public TurnstoreOutDto toLazyDto(TurnstoreOut entity) {
		return modelMapper.map(entity, TurnstoreOutDto.class);
	}

	public TurnstoreOutDto toEagerDto(TurnstoreOut entity) {
		TurnstoreOutDto dto = modelMapper.map(entity, TurnstoreOutDto.class);
		return dto;
	}

	public TurnstoreOut fromDto(TurnstoreOutDto dto) {
		//ModelMapper modelMapper = new ModelMapper();
		modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
		modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
		return modelMapper.map(dto, TurnstoreOut.class);
	}
	public TurnstoreOut fromDto(TurnstoreOutPostDto dto) {
		//ModelMapper modelMapper = new ModelMapper();
		modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
		modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
		return modelMapper.map(dto, TurnstoreOut.class);
	}
	public TurnstoreOutPostDto fromDto(TurnstoreOut dto) {
		//ModelMapper modelMapper = new ModelMapper();
		modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
		modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
		return modelMapper.map(dto, TurnstoreOutPostDto.class);
	}

	public List<TurnstoreOutItem> fromDto(List<TurnstoreOutItemDto> dto){
		//ModelMapper modelMapper = new ModelMapper();
		modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
		modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
		List<TurnstoreOutItem> listEntity = dto.stream().map(turnstoreOutItem -> modelMapper.map(turnstoreOutItem, TurnstoreOutItem.class)).collect(Collectors.toList());
		return listEntity;
	}

	public List<TurnstoreOutItemDto> toDto(List<TurnstoreOutItem> dto){
		//ModelMapper modelMapper = new ModelMapper();
		modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
		modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
		List<TurnstoreOutItemDto> listEntity = dto.stream().map(turnstoreOutItemDto -> modelMapper.map(turnstoreOutItemDto, TurnstoreOutItemDto.class)).collect(Collectors.toList());
		return listEntity;
	}
}
