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

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.api.auth.AuthFeignClient;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.SpringUtils;
import com.sw.mes.base.factory.init.dto.Equipment.EquipmentDto;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.entity.MaterialType;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.factory.material.service.MaterialTypeService;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.redis.server.RedisUtils;
import com.sw.mes.yb.accessory.entity.EquipmentDeviceStatus;
import com.sw.mes.yb.accessory.service.EquipmentDeviceStatusService;
import com.sw.mes.yb.deviceCheck.dto.DeviceCheckTimeRecordInfo;
import com.sw.mes.yb.deviceCheck.entity.DeviceCheckTimeRecord;
import com.sw.mes.yb.deviceCheck.service.DeviceCheckTimeRecordService;
import com.sw.mes.yb.ipc.dto.*;
import com.sw.mes.yb.ipc.entity.BucketUseInfo;
import com.sw.mes.yb.ipc.mapping.ButtonType;
import com.sw.mes.yb.ipc.service.BucketUseInfoService;
import com.sw.mes.yb.ipc.service.IBaseButtonHandler;
import com.sw.mes.yb.pad.controller.PadDeviceCheckController;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.dto.AgainTask.AgainTaskDto;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskDetailDto;
import com.sw.mes.yb.production.dto.EquipmentClickLogDto;
import com.sw.mes.yb.production.dto.EquipmentExtendStateDto;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import com.sw.mes.yb.report.dto.CrystalPullingInfoDto;
import com.sw.mes.yb.report.entity.CrystalPullingInfo;
import com.sw.mes.yb.report.service.CrystalPullingInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author liru
 * @Description��
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/ipc")
@Slf4j
@Api(description = "工控机操作接口")
public class IpcOperationController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private BucketUseInfoService bucketUseInfoService;
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private ProductionScheduleService productionScheduleService;
    @Autowired
    private AgainTaskService againTaskService;
    @Autowired
    private InputFurnaceBurdenService inputFurnaceBurdenService;
    @Autowired
    private LoadingTaskService loadingTaskService;
    @Autowired
    private BlastFurnaceDetailService blastFurnaceDetailService;
    @Autowired
    private MaterialModelService materialModelService;
    @Autowired
    private MaterialTypeService materialTypeService;
    @Autowired
    private EquipmentExtendStateService equipmentExtendStateService;

    @Autowired
    private AuthFeignClient authFeignClient;
    @Autowired
    private EquipmentClickLogService equipmentClickLogService;
    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private CrystalPullingInfoService crystalPullingInfoService;

    @Autowired
    private AgainTaskDetailService againTaskDetailService;
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private DeviceCheckTimeRecordService deviceCheckTimeRecordService;

    @Autowired
    private EquipmentDeviceStatusService equipmentDeviceStatusService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private ProcessWorkingHoursService processWorkingHoursService;


    @ApiOperation(value = "理论工时详细信息")
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    public Result info(@RequestBody @ApiParam(value = "设备编号") @Valid IpcParam param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        Equipment equipment = equipmentService.findByCode(param.getEquimentCode());

        if (equipment == null) {
            return ResultGenerator.success();
        }

        EquipmentDto equipmentDto = toLazyDto(equipment);

        //复投桶使用情况Dto
        BucketUseInfo bucketUseInfo = bucketUseInfoService.getBySeries(equipment.getSeries());
        BucketUseInfoDto bucketUseInfoDto = toLazyDto(bucketUseInfo);

        //圆棒工单排程Dto
        ProductionSchedule current_productionSchedule = productionScheduleService.findTopByDeviceNoAndStatusOrderByIdDesc(param.getEquimentCode(), Arrays.asList(1, 4, 5));
        //圆棒工单排程Dto
        ProductionSchedule next_productionSchedule = productionScheduleService.findTopByDeviceNoAndStatusOrderByIdDesc(param.getEquimentCode(), Arrays.asList(0));

        AgainTask againTask = null;
        AgainTaskDetail detail = null;

        if (current_productionSchedule != null) {
            againTask = againTaskService.getByEquipmentLastTask(param.getEquimentCode(), current_productionSchedule.getLotNo());
            detail = againTaskDetailService.getLastSuccessTask(param.getEquimentCode(), current_productionSchedule.getLotNo());
        }


        AgainTaskInfoDto againTaskInfoDto = new AgainTaskInfoDto();
        //初始化复投信息
        initAgainTaskInfo(againTask, againTaskInfoDto);
        //初始化坩埚信息
        initCrucibleInfo(againTask, againTaskInfoDto);
        //初始化热场坩埚类型
        //热场坩埚类型
        MaterialType materialType = materialTypeService.getByEquipmentCodeAndTypeCodes(param.getEquimentCode(), "A04037", "A04038");
        if (materialType != null) {
            againTaskInfoDto.setHeatCrucible(materialType.getName());
        }

        //设备状态 扩展信息等
        EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(param.getEquimentCode());
        if (equipmentExtendState == null) {
            equipmentExtendState = new EquipmentExtendState();
            equipmentExtendState.setEquipmentCode(equipment.getCode());
            equipmentExtendState.setEquipmentState(2);
            equipmentExtendState.setLevelStickState(false);
            equipmentExtendState.setSeries(equipment.getSeries());
            equipmentExtendState.setArea(equipment.getArea());
            equipmentExtendState.setLoginState(false);
            equipmentExtendStateService.saveOrUpdate(equipmentExtendState);
        }
        EquipmentExtendStateDto equipmentExtendStateDto = toLazyDto(equipmentExtendState);


        CrystalPullingInfo crystalPullingInfo = crystalPullingInfoService.getByDeviceNo(param.getEquimentCode());
        CrystalPullingInfoDto crystalPullingInfoDto = toLazyDto(crystalPullingInfo);

        //查询最新一条操作记录
        EquipmentClickLog equipmentClickLog = equipmentClickLogService.getLastLog(param.getEquimentCode());
        EquipmentClickLogDto equipmentClickLogDto = toLazyDto(equipmentClickLog);

        Boolean storeLock = (Boolean) redisUtils.get(param.getEquimentCode() + "-store-lock");

        //拆清点检信息
        DeviceCheckTimeRecordInfo deviceCheckTimeRecordInfo = new DeviceCheckTimeRecordInfo();
        if (current_productionSchedule != null) {
            /*DeviceCheckTimeRecord deviceCheckTimeRecord = deviceCheckTimeRecordService.findByLotNo(current_productionSchedule.getLotNo());
            if (deviceCheckTimeRecord != null) {
                deviceCheckTimeRecordInfo.setDismantleStartTime(deviceCheckTimeRecord.getDismantleStartTime());
                deviceCheckTimeRecordInfo.setDismantleEndTime(deviceCheckTimeRecord.getDismantleEndTime());
            }*/
            ProcessWorkingHours workingHours = processWorkingHoursService.findByLotNoAndStep(current_productionSchedule.getLotNo(), "拆清工时");
            if (ObjectUtils.isEmpty(workingHours)){
                deviceCheckTimeRecordInfo.setDismantleStatus(0);
            }else {
                deviceCheckTimeRecordInfo.setDismantleStartTime(workingHours.getStartTime());
                deviceCheckTimeRecordInfo.setDismantleStatus(1);
                if (!ObjectUtils.isEmpty(workingHours.getEndTime())){
                    deviceCheckTimeRecordInfo.setDismantleEndTime(workingHours.getEndTime());
                    deviceCheckTimeRecordInfo.setDismantleStatus(2);
                }
            }
        }
        Integer button = (Integer) redisUtils.get(PadDeviceCheckController.DEVICE_CHECK_BUTTON_PREFIX);
        if (button == null) {
            deviceCheckTimeRecordInfo.setButton(0);
        } else {
            deviceCheckTimeRecordInfo.setButton(button);
        }
        EquipmentDeviceStatus equipmentDeviceStatus = equipmentDeviceStatusService.findByDeviceNo(param.getEquimentCode());
        if (equipmentDeviceStatus != null) {
            deviceCheckTimeRecordInfo.setShutdownTime(equipmentDeviceStatus.getEndTime());
        }

        IpcDataDto dataDto = new IpcDataDto();
        dataDto.setEquipmentDto(equipmentDto);//设备信息
        dataDto.setEquipmentExtendState(equipmentExtendStateDto);
        dataDto.setBucketUseInfo(bucketUseInfoDto);//复投桶使用情况
        dataDto.setCurrentTask(current_productionSchedule == null ? null : toMap(new ProductionTaskDto(current_productionSchedule)));
        dataDto.setNextTask(next_productionSchedule == null ? null : toMap(new ProductionTaskDto(next_productionSchedule)));
        dataDto.setAgainTaskInfoDto(againTaskInfoDto);
        dataDto.setEquipmentClickLogDto(equipmentClickLogDto);
        dataDto.setCrystalPullingInfoDto(crystalPullingInfoDto);
        dataDto.setStoreLock(storeLock == null ? false : storeLock);
        dataDto.setLotNo(current_productionSchedule == null ? null : current_productionSchedule.getLotNo());//当前炉次号
        dataDto.setAgainTask(toLazyDto(againTask));
        dataDto.setDetailTask(toLazyDto(detail));
        dataDto.setDeviceCheckTimeRecordInfo(deviceCheckTimeRecordInfo);

        return ResultGenerator.success(dataDto);
    }

    private ProductionTaskDto toMap(ProductionTaskDto productionTaskDto) {
        List<DictionaryItem> productCategory = dictionaryItemService.findByThemeValueAndEnable("product_category", true);
        Map<String, String> productCategoryMap = productCategory.stream().collect(Collectors.toMap(DictionaryItem::getValue, DictionaryItem::getName, (a1, a2) -> a1));

        productionTaskDto.setProductType(productCategoryMap.get(productionTaskDto.getProductType()));
        return productionTaskDto;
    }
    
    
    
    @ApiOperation(value = "按设备刷新IPC")
    @PostMapping("/refresh")
    public Result refresh(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        for (Long id : ids) {
        	Equipment equipment = equipmentService.get(id);
        	IpcRefresh ipcRefresh = new IpcRefresh();
        	ipcRefresh.setEquimentCode(equipment.getCode());
        	return ipcRefresh(ipcRefresh);
        }
        return ResultGenerator.success();
    }
    
    
    @ApiOperation(value = "IPC刷新页面控制")
    @PostMapping("/ipcRefresh")
    public Result ipcRefresh(@RequestBody IpcRefresh dto) {
        try {
            equipmentExtendStateService.ipcRefresh(dto);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }
    


    @ApiOperation(value = "状态/液位杆切换")
    @PostMapping("/updateState")
    public Result update(@RequestBody @Valid @ApiParam(value = "复投任务") EquipmentExtendStateDto dto) {
        if (dto.getEquipmentCode() == null) {
            return ResultGenerator.fail("设备编号不能为空不能为空");
        }

        EquipmentExtendState entity = equipmentExtendStateService.getByCode(dto.getEquipmentCode());
        if (entity == null) {
            return ResultGenerator.fail("设备状态信息不存在,请先登录");
        }

        if (!entity.getLoginState()) {
            return ResultGenerator.fail("未登录,禁止操作");
        }


        try {
            if (dto.getEquipmentState() != null) {
                entity.setEquipmentState(dto.getEquipmentState());
            }
            if (dto.getLevelStickState() != null) {
                entity.setLevelStickState(dto.getLevelStickState());
            }

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


    @ApiOperation(value = "登录接口")
    @PostMapping("/login")
    public Result login(@ApiParam(value = "用户名") String loginName, @ApiParam(value = "密码") String password, @ApiParam(value = "设备编号") String equipmentCode, @ApiParam(value = "系列") String series, @ApiParam(value = "模块") String area, @ApiParam(value = "班组") String teamGroup, @ApiParam(value = "班次") String classNo) {
        if (StringUtils.isEmpty(loginName)) {
            return ResultGenerator.fail("用户名为空！");
        }

        if (StringUtils.isEmpty(password)) {
            return ResultGenerator.fail("密码为空！");
        }
        if (StringUtils.isEmpty(equipmentCode)) {
            return ResultGenerator.fail("设备号为空！");
        }

        if (StringUtils.isEmpty(series)) {
            return ResultGenerator.fail("系列为空！");
        }

        Result result = authFeignClient.login(loginName, password, "ipc");
        try {
            if (result.getCode() == ResultCode.SUCCESS.getCode()) {
                equipmentExtendStateService.loginUpdate(equipmentCode, series, loginName, result.getData() != null ? result.getData().toString() : null, teamGroup, classNo);
            }
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return result;
    }


    @ApiOperation(value = "登出接口")
    @PostMapping("/logout")
    public Result<String> logout(@ApiParam(value = "设备编号") String equipmentCode, @ApiParam(value = "系列") String series, @ApiParam(value = "模块") String area) {
        if (StringUtils.isEmpty(equipmentCode)) {
            return ResultGenerator.fail("设备号为空！");
        }

        if (StringUtils.isEmpty(series)) {
            return ResultGenerator.fail("系列为空！");
        }


        try {
            equipmentExtendStateService.logoutUpdate(equipmentCode, series);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }


        return ResultGenerator.success();
    }


    @ApiOperation(value = "按钮操作")
    @PostMapping("/buttonClick")
    public Result<String> buttonClick(@RequestBody @Valid @ApiParam(value = "按钮点击信息") ButtonClickDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        //验证是否登录
        EquipmentExtendState state = equipmentExtendStateService.getByCode(dto.getEquipmentCode());
        if (state == null || state.getLoginState() == null && state.getLoginState() == false) {
            return ResultGenerator.fail("未登录,禁止操作");
        }
//		else if(dto.getUserName()!=null && !state.getUserName().equals(dto.getUserName())) {
//			return ResultGenerator.fail("操作人与登录人不一致");
//		}

        EquipmentClickLog clickLog = new EquipmentClickLog();
        clickLog.setArea(dto.getArea());
        clickLog.setButtonName(dto.getButtonName());
        clickLog.setClassNo(dto.getClassNo());
        clickLog.setClickParam(JSON.toJSONString(dto.getParams()));
        clickLog.setClickTime(new Date());
        clickLog.setEquipmentCode(dto.getEquipmentCode());
        clickLog.setSeries(dto.getSeries());
        clickLog.setTeamGroup(dto.getTeamGroup());
        clickLog.setUserName(dto.getUserName());
        clickLog.setLotNo(dto.getLotNo());

        try {
            IBaseButtonHandler handler = SpringUtils.getBean(ButtonType.get(dto.getButtonName()));
            if (handler == null) {
                throw new RuntimeException("未实现按钮处理逻辑");
            } else {
                Object obj = handler.execute(dto);//执行业务逻辑
                handler.writeWorkHours(dto);//写入操作工时
                String content = "";
                if (obj != null) {
                    if (obj instanceof String) {
                        content = obj.toString();
                    } else {
                        content = JSON.toJSONString(obj == null ? "" : obj);
                    }
                }
                clickLog.setContext(content);
                equipmentClickLogService.saveOrUpdate(clickLog);
            }
        } catch (IllegalArgumentException e) {
            clickLog.setContext("未实现按钮处理逻辑");
            e.printStackTrace();
            log.error("未实现按钮处理逻辑："+ExceptionUtil.stacktraceToString(e));
            equipmentClickLogService.saveOrUpdate(clickLog);
            return ResultGenerator.fail("未实现按钮处理逻辑");
        } catch (Exception e) {
            clickLog.setContext(e.getMessage());
            e.printStackTrace();
            log.error("按钮操作错误："+ExceptionUtil.stacktraceToString(e));
            equipmentClickLogService.saveOrUpdate(clickLog);
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }


    @ApiOperation(value = "查询机台当前产出单晶编号")
    @PostMapping("/getLastCrystalNo")
    public Result<LongCrystal> getLastCrystalNo(@ApiParam(value = "按钮点击信息") String equipmentCode) {
        //验证是否登录
        LongCrystal longCrystal = longCrystalService.getLastCrystalNo(equipmentCode);
        return ResultGenerator.success(longCrystal);
    }

    @ApiOperation(value = "查询当前机台未确认异常长晶棒信息")
    @PostMapping("/getConfirmCrystals")
    public Result<ConfirmCrystalsDto> getConfirmCrystals(@ApiParam(value = "按钮点击信息") String lotNo) {
        //验证是否登录
        ConfirmCrystalsDto confirmCrystalsDto = new ConfirmCrystalsDto();
        List<LongCrystal> longCrystals = longCrystalService.findByConfirmCrystals(lotNo);
        confirmCrystalsDto.setLongCrystals(longCrystals);
        List<LongCrystal> toConfirmList = longCrystals.stream().filter(item -> item.getCrystalStatus() == EnumValuesFactory.CrystalStatus.待确认.getKey()).collect(Collectors.toList());
        if (toConfirmList.size() == 1) {
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.get(longCrystals.get(0).getLotId());
            if (planProcessingOrder != null) {
                confirmCrystalsDto.setOutputMode(planProcessingOrder.getOutputMode());
            }
        }
        return ResultGenerator.success(confirmCrystalsDto);
    }

    @ApiOperation(value = "查询当前投料信息")
    @GetMapping("/getMaterialsInfo")
    public Result<List<ConfirmMaterialsDto>> getMaterialsInfo(@ApiParam(value = "炉次号") String lotNo){
        if(StringUtils.isBlank(lotNo)){
            return ResultGenerator.fail("该设备没有进行中的排程！");
        }
        List<ConfirmMaterialsDto> dtoList = new ArrayList<>();
        // 装料
        LoadingTask loadingTask = loadingTaskService.findUnconfirmedTask(lotNo);
        if (loadingTask != null){
            ConfirmMaterialsDto dto = new ConfirmMaterialsDto();
            dto.setRawType(0);
            dto.setRawTypeName("初始装料");
            dto.setTaskId(loadingTask.getId());
            dto.setWeight(loadingTask.getRealWeight());
            dto.setCarrierNo(loadingTask.getCarrierNo());
            dtoList.add(dto);
        }
        // 灌料
        List<InputFurnaceBurden> burdenList = inputFurnaceBurdenService.findUnconfirmedTask(lotNo);
        for (InputFurnaceBurden burden : burdenList) {
            ConfirmMaterialsDto dto = new ConfirmMaterialsDto();
            dto.setRawType(burden.getRawType());
            dto.setRawTypeName(dto.getRawType()==1? "初始复投": "取段复投");
            dto.setTaskId(burden.getId());
            dto.setWeight(burden.getAgainRealWeight());
            dto.setCarrierNo(burden.getVehicleCode());
            dtoList.add(dto);
        }

        return ResultGenerator.success(dtoList);
    }


    @ApiOperation(value = "IPC确认投料")
    @PostMapping("/confirmMaterials")
    public Result confirmMaterials(@RequestBody @ApiParam(value = "按钮点击信息") ConfirmMaterialsDto dto){

        if (dto.getRawType() == 0){     // 装料
           return loadingTaskService.confirmMaterials(dto.getTaskId());

        }else {     // 灌料
           return inputFurnaceBurdenService.confirmMaterials(dto.getTaskId());
        }

    }


    private void initCrucibleInfo(AgainTask againTask, AgainTaskInfoDto againTaskInfoDto) {
        if (againTask != null) {
            //当前炉台  炉次 的 装料任务信息
            LoadingTask loadingTask = loadingTaskService.getFinishTask(againTask.getEquipmentCode(), againTask.getLotNo());
            if (loadingTask != null) {
                BlastFurnaceDetail blastFurnaceDetail = blastFurnaceDetailService.getCrucibleInfo(loadingTask.getId());
                if (blastFurnaceDetail != null) {
                    MaterialModel materialModel = materialModelService.findByCode(blastFurnaceDetail.getProductCode());
                    if (materialModel != null) {
                        //设置当前使用坩埚型号
                        againTaskInfoDto.setCrucible(materialModel.getSpecification());

                        //写入坩埚型号到拉晶情况-实时表
                        CrystalPullingInfo info = crystalPullingInfoService.getByDeviceNo(againTask.getEquipmentCode());
                        if (info == null) {
                            info = new CrystalPullingInfo();
                        }
                        info.setCrucible(materialModel.getSpecification());//坩埚规格
                        crystalPullingInfoService.saveOrUpdate(info);
                    }
                }
            }
        }
    }


    private void initAgainTaskInfo(AgainTask againTask, AgainTaskInfoDto againTaskInfoDto) {
        if (againTask != null) {
            String rawType = "-";
            if (againTask.getRawType() == 1) {
                rawType = "初始复投";
            } else if (againTask.getRawType() == 2) {
                rawType = "取段复投";
            }
            againTaskInfoDto.setRawType(rawType);


            againTaskInfoDto.setAgainWeigth(againTask.getAgainWeigth());
            againTaskInfoDto.setAgainPailNum(againTask.getAgainPailNum());
            againTaskInfoDto.setAlreadyPailNum(againTask.getAlreadyPailNum());


            String pailNum = "0";

            if (againTask.getPailNum() == null || againTask.getPailNum() == 0) {
                pailNum = "0";
            } else if (againTask.getPailNum() % 2 == 0) {
                pailNum = (againTask.getPailNum() - 1) + "," + againTask.getPailNum();
            } else if (againTask.getPailNum() % 2 != 0) {
                pailNum = againTask.getPailNum() + "";
            }

            againTaskInfoDto.setPailNum(pailNum);
        }
    }


    public BucketUseInfoDto toLazyDto(BucketUseInfo entity) {
        if (entity == null) {
            return null;
        }
        return modelMapper.map(entity, BucketUseInfoDto.class);
    }

    public EquipmentDto toLazyDto(Equipment entity) {
        return modelMapper.map(entity, EquipmentDto.class);
    }

    public EquipmentExtendStateDto toLazyDto(EquipmentExtendState entity) {
        return modelMapper.map(entity, EquipmentExtendStateDto.class);
    }

    public BucketUseInfo fromDto(BucketUseInfoDto dto) {
        return modelMapper.map(dto, BucketUseInfo.class);
    }

    private EquipmentClickLogDto toLazyDto(EquipmentClickLog entity) {
        if (entity == null) {
            return null;
        }
        return modelMapper.map(entity, EquipmentClickLogDto.class);
    }

    private CrystalPullingInfoDto toLazyDto(CrystalPullingInfo entity) {
        if (entity == null) {
            return null;
        }
        return modelMapper.map(entity, CrystalPullingInfoDto.class);
    }

    private AgainTaskDto toLazyDto(AgainTask entity) {
        if (entity == null) {
            return null;
        }
        return modelMapper.map(entity, AgainTaskDto.class);
    }

    private AgainTaskDetailDto toLazyDto(AgainTaskDetail entity) {
        if (entity == null) {
            return null;
        }
        return modelMapper.map(entity, AgainTaskDetailDto.class);
    }
}
