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

import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.utils.excel.ExcelUtil;
import com.sw.mes.core.annotation.TokenNotValidation;
import com.sw.mes.core.context.BaseContextHandler;
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.yb.plan.dto.PlanEquipmentOutputDto;
import com.sw.mes.yb.plan.entity.PlanEquipmentOutput;
import com.sw.mes.yb.plan.service.PlanEquipmentOutputService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
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.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@RestController
@RequestMapping("/planOutput")
@Slf4j
@Api(description = "计划单产接口")
public class PlanEquipmentOutputController {
	@Autowired
	ModelMapper modelMapper;

	@Autowired
	private PlanEquipmentOutputService planEquipmentOutputService;

	@Autowired
	private EquipmentService equipmentService;

	@ApiOperation(value = "分页查询计划单产列表")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
		@ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
	})
	@GetMapping("/listByPage")
	public Result<ResponsePage<PlanEquipmentOutputDto>> listByPage(ServletRequest request,@ApiIgnore RequestPage requestPage) {
		Specification<PlanEquipmentOutput> specification = DynamicSpecifications.bySearchFilter(request, PlanEquipmentOutput.class);
    	Page<PlanEquipmentOutput> page = planEquipmentOutputService.findByExample(specification, PageUtil.createPageable(requestPage));
		List<PlanEquipmentOutputDto> 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<PlanEquipmentOutputDto>> listAll(ServletRequest request) {
		Specification<PlanEquipmentOutput> specification = DynamicSpecifications.bySearchFilter(request, PlanEquipmentOutput.class);
		List<PlanEquipmentOutput> planEquipmentOutputs = planEquipmentOutputService.findByExampleSort(specification, null);
		List<PlanEquipmentOutputDto> planEquipmentOutputDtos = planEquipmentOutputs.stream()
					.map(planEquipmentOutput -> toLazyDto(planEquipmentOutput))
					.collect(Collectors.toList());
		return ResultGenerator.success(planEquipmentOutputDtos);
	}

	@ApiOperation(value = "计划单产详细信息")
	@GetMapping("/{id}")
	public Result<PlanEquipmentOutputDto> get(@PathVariable @ApiParam(value="计划单产id") Long id) {
		PlanEquipmentOutput planEquipmentOutput = planEquipmentOutputService.get(id);
		if (null == planEquipmentOutput)
			return ResultGenerator.fail("该计划单产不存在");
		return ResultGenerator.success(toEagerDto(planEquipmentOutput));
	}

	@ApiOperation(value = "创建计划单产")
	@PostMapping("/create")
	public Result create(@RequestBody @Valid @ApiParam(value = "计划单产对象") PlanEquipmentOutputDto dto, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
		}
		if (CollectionUtils.isEmpty(dto.getEquipmentCodeList())){
			return ResultGenerator.fail("设备集合不能为空");
		}
		if (StringUtils.isEmpty(dto.getOutputDate())){
			return ResultGenerator.fail("单产日期不能为空");
		}
		if (ObjectUtils.isEmpty(dto.getOutputCount())){
			return ResultGenerator.fail("计划单产不能为空");
		}
		for (String ec : dto.getEquipmentCodeList()) {
			PlanEquipmentOutput pot = planEquipmentOutputService.findByEquipmentAndDate(ec, dto.getOutputDate());
			if (!ObjectUtils.isEmpty(pot)){
				return ResultGenerator.fail("已存在设备【"+ec+"】,日期【"+dto.getOutputDate()+"】的记录，不能重复录入");
			}
			Equipment equipment = equipmentService.findByCode(ec);
			if (ObjectUtils.isEmpty(equipment)){
				return ResultGenerator.fail("设备【"+ec+"】不存在");
			}
		}

		// 批量保存
		Date now = new Date();
		List<PlanEquipmentOutput> potList = new ArrayList<>();
		for (String ec : dto.getEquipmentCodeList()) {
			PlanEquipmentOutput pot = fromDto(dto);
			pot.setSite("TY");
			pot.setEquipmentCode(ec);
			pot.setCreateTime(now);
			pot.setCreateUser(BaseContextHandler.getUsername());
			Equipment equipment = equipmentService.findByCode(ec);
			pot.setEquipmentId(equipment.getId());
			if (StringUtils.isBlank(dto.getWorkshop()) || StringUtils.isBlank(dto.getArea1())){
				pot.setWorkshop(equipment.getArea());
				pot.setArea1(equipment.getSeries());
			}

			potList.add(pot);
		}

		planEquipmentOutputService.saveAll(potList);

		return ResultGenerator.success();
	}

    @ApiOperation(value = "更新计划单产")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "计划单产") PlanEquipmentOutputDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors())
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        if (dto.getId() == null)
            return ResultGenerator.fail("id不能为空");
            PlanEquipmentOutput entity = planEquipmentOutputService.get(dto.getId());
        if (entity == null)
            return ResultGenerator.fail("原信息不存在");
        try {
            PlanEquipmentOutput entityfromFto = fromDto(dto);
			BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
			entity.setUpdateTime(new Date());
			entity.setUpdateUser(BaseContextHandler.getUsername());
			Equipment equipment = equipmentService.findByCode(dto.getEquipmentCode());
			entity.setEquipmentId(equipment.getId());
			if (StringUtils.isBlank(dto.getWorkshop()) || StringUtils.isBlank(dto.getArea1())){
				entity.setWorkshop(equipment.getArea());
				entity.setArea1(equipment.getSeries());
			}

			planEquipmentOutputService.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 Long[] ids) {
		for (Long id : ids) {
			planEquipmentOutputService.delete(id);
		}
		return ResultGenerator.success();
	}


	@ApiOperation(value = "模板文件下载")
	@GetMapping("/downloadTemplate")
	@TokenNotValidation
	public void download(HttpServletResponse response) {
		String path = "template/单晶产能计划单产导入模板.xlsx";
		ExcelUtil.download1(path, response);
	}

	@ApiOperation(value = "Excel导入")
	@PostMapping("/import")
	public Result importExcel(MultipartFile file) {
		try {
			Object fileRows = EasyExcelUtils.readExcel(file, new PlanEquipmentOutputDto(), 1, 1);
			if (ObjectUtils.isEmpty(fileRows)){
				return ResultGenerator.fail("未解析出导入数据");
			}
			List<PlanEquipmentOutputDto> dtoList = (List<PlanEquipmentOutputDto>) fileRows;
			if (CollectionUtils.isEmpty(dtoList)){
				return ResultGenerator.fail("未解析出导入数据");
			}
			List<PlanEquipmentOutput> entityList = new ArrayList<>();
			List<String> checkOnlyList = new ArrayList<>();
			for (PlanEquipmentOutputDto dto : dtoList) {
				String onlyKey = dto.getEquipmentCode() + ":" + dto.getOutputDate();
				if (checkOnlyList.contains(onlyKey)){
					return ResultGenerator.fail("导入数据中存在设备【"+dto.getEquipmentCode()+"】,日期【"+dto.getOutputDate()+"】的重复记录");
				}
				checkOnlyList.add(onlyKey);
				PlanEquipmentOutput pot = planEquipmentOutputService.findByEquipmentAndDate(dto.getEquipmentCode(), dto.getOutputDate());
				if (!ObjectUtils.isEmpty(pot)){
					return ResultGenerator.fail("已存在设备【"+dto.getEquipmentCode()+"】,日期【"+dto.getOutputDate()+"】的记录，不能重复录入");
				}
				Equipment equipment = equipmentService.findByCode(dto.getEquipmentCode());
				if (ObjectUtils.isEmpty(equipment)){
					return ResultGenerator.fail("设备【"+dto.getEquipmentCode()+"】不存在");
				}
				dto.setEquipmentId(equipment.getId());

				PlanEquipmentOutput entity = new PlanEquipmentOutput();
				BeanUtils.copyProperties(dto, entity);
				entityList.add(entity);
			}

			planEquipmentOutputService.saveAll(entityList);
		}catch (Exception e){
			log.error("计划单产导入异常：", e);
			return ResultGenerator.fail("导入数据异常: " + e.getMessage());
		}

		return ResultGenerator.success();
	}

	@ApiOperation(value = "导出Excel(最多1W条)")
	@GetMapping("/export")
	public void export(ServletRequest request,  HttpServletResponse response) {
		try {
			RequestPage requestPage = new RequestPage();
			requestPage.setRows(10000);
			Specification<PlanEquipmentOutput> specification = DynamicSpecifications.bySearchFilter(request, PlanEquipmentOutput.class);
			Page<PlanEquipmentOutput> page = planEquipmentOutputService.findByExample(specification, PageUtil.createPageable(requestPage));
			List<PlanEquipmentOutputDto> dtoList = page.getContent().stream()
					.map(entity -> toLazyDto(entity))
					.collect(Collectors.toList());
			EasyExcelUtils.write(response, PlanEquipmentOutputDto.class, "单晶产能计划单产", "单晶产能计划单产", dtoList);
		} catch (Exception e) {
			throw new RuntimeException("导出单晶产能计划单产失败，错误信息：" + e.getMessage());
		}
	}

	public PlanEquipmentOutputDto toLazyDto(PlanEquipmentOutput entity) {
		return modelMapper.map(entity, PlanEquipmentOutputDto.class);
	}

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

	public PlanEquipmentOutput fromDto(PlanEquipmentOutputDto dto) {
		return modelMapper.map(dto, PlanEquipmentOutput.class);
	}



}
