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

import com.sw.mes.base.factory.inspect.entity.ProductAssemblyRule;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.exception.BusinessException;
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.production.entity.RecycledMaterialManage;
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.data.redis.core.RedisTemplate;
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.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.sw.mes.yb.pc.entity.CarrierConfig;
import com.sw.mes.yb.pc.dto.CarrierConfigDto;
import com.sw.mes.yb.pc.service.CarrierConfigService;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/CarrierConfig")
@Slf4j
@Api(description = "载具配置关联接口", value = "载具配置关联接口")
public class CarrierConfigController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private CarrierConfigService carrierConfigService;
    @Autowired
    private DictionaryItemService dictionaryItemService;
    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation(value = "分页查询载具配置关联列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<CarrierConfigDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<CarrierConfig> specification = DynamicSpecifications.bySearchFilter(request, CarrierConfig.class);
        Page<CarrierConfig> page = carrierConfigService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<CarrierConfigDto> 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<CarrierConfigDto>> listAll(ServletRequest request) {
        Specification<CarrierConfig> specification = DynamicSpecifications.bySearchFilter(request, CarrierConfig.class);
        List<CarrierConfig> carrierConfigs = carrierConfigService.findByExampleSort(specification, null);
        List<CarrierConfigDto> carrierConfigDtos = carrierConfigs.stream()
                .map(carrierConfig -> toLazyDto(carrierConfig))
                .collect(Collectors.toList());
        return ResultGenerator.success(carrierConfigDtos);
    }

    @ApiOperation(value = "载具配置关联详细信息")
    @GetMapping("/{id}")
    public Result<CarrierConfigDto> get(@PathVariable @ApiParam(value = "载具配置关联id") Integer id) {
        CarrierConfig carrierConfig = carrierConfigService.get(id);
        if (null == carrierConfig) {
            return ResultGenerator.fail("该载具配置关联不存在");
        }
        return ResultGenerator.success(toEagerDto(carrierConfig));
    }

    @ApiOperation(value = "创建载具配置关联")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "载具配置关联对象") CarrierConfigDto carrierConfigDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        CarrierConfig carrierConfig = fromDto(carrierConfigDto);

        Integer type = carrierConfigDto.getType();
        if (null == type) {
            throw new BusinessException("载具类型不能为空!");
        }
        DictionaryItem dictionaryItem = dictionaryItemService.findByThemeValueAndValue("carrier_config", carrierConfigDto.getType().toString());
        if (null == dictionaryItem) {
            throw new BusinessException("载具配置信息字典不能为空!");
        }
        String prefixCode = dictionaryItem.getExtendValue();
        //生成载具编码:载具类型code+000001流水号
        String carrierNo = createCarrierNo(prefixCode);
        carrierConfig.setCarrierNo(carrierNo);
        carrierConfig.setCreateUser(BaseContextHandler.getUsername());
        carrierConfigService.saveOrUpdate(carrierConfig);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新载具配置关联")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "载具配置关联") CarrierConfigDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        CarrierConfig entity = carrierConfigService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            CarrierConfig entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            entity.setUpdateUser(BaseContextHandler.getUsername());
            carrierConfigService.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) {
        for (Integer id : ids) {
            CarrierConfig config = carrierConfigService.get(id);
            if(1==config.getStatus()){
                throw new BusinessException("箱号:"+config.getCarrierNo()+"正在使用,不可删除!");
            }
            carrierConfigService.delete(id);
        }
        return ResultGenerator.success();
    }


    @ApiOperation(value = "通过载具号更新载具配置")
    @PostMapping("/updateByCarrierNo")
    public Result updateByCarrierNo(@RequestBody @Valid @ApiParam(value = "载具配置") CarrierConfigDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        CarrierConfig entity = carrierConfigService.checkCarrierNo(dto.getCarrierNo());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            CarrierConfig entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            entity.setUpdateUser(BaseContextHandler.getUsername());
            entity.setUpdateTime(new Date());
            carrierConfigService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    /**
     * 通过卡板箱号确定箱子的使用状态
     *
     * @param boxNo
     * @return
     */
    @ApiOperation(value = "通过卡板箱号确定箱子的使用状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "boxNo", value = "卡板箱号", dataType = "String", paramType = "query"),
    })
    @GetMapping(value = "/findCarrierInfoBoxNo")
    Result<CarrierConfig> findCarrierInfoBoxNo(String boxNo) {
        //查看料箱配置使用状态
        CarrierConfig config = carrierConfigService.findCarrierInfoBoxNo(boxNo);
        if (null == config) {
            return ResultGenerator.fail("该箱号: " + boxNo + "不存在!");
        }
        return ResultGenerator.success(config);
    }
    public CarrierConfigDto toLazyDto(CarrierConfig entity) {
        return modelMapper.map(entity, CarrierConfigDto.class);
    }

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

    public CarrierConfig fromDto(CarrierConfigDto dto) {
        return modelMapper.map(dto, CarrierConfig.class);
    }


    /**
     * 生成载具编号
     */
    private String createCarrierNo(String prefixCode) {

        StringBuilder carrierNo = new StringBuilder();
        String order5Num = "";
        String num5Value;
        String key5 = "carrierNo_" + prefixCode;

        if (redisTemplate.hasKey(key5)) {
            //先获取redis中的顺序号
            num5Value = (String) redisTemplate.opsForValue().get(key5);
            order5Num = String.valueOf(Integer.parseInt(num5Value) + 1);
            if (order5Num.length() == 1) {
                order5Num = "0000" + order5Num;
            } else if (order5Num.length() == 2) {
                order5Num = "000" + order5Num;
            } else if (order5Num.length() == 3) {
                order5Num = "00" + order5Num;
            } else if (order5Num.length() == 4) {
                order5Num = "0" + order5Num;
            }
        } else {
            order5Num = "00001";
        }
        carrierNo.append(prefixCode);
        carrierNo.append(order5Num);
        //判断拖号是否重复
        if (null != carrierConfigService.checkCarrierNo(carrierNo.toString())) {
            throw new RuntimeException("错误，生成的载具编码已存在");
        }
        //更新缓存
        redisTemplate.opsForValue().set(key5, order5Num);
        return String.valueOf(carrierNo);
    }
}
