package com.foreverwin.mesnac.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.common.constant.Constants;
import com.foreverwin.mesnac.common.constant.CustomFieldConstant;
import com.foreverwin.mesnac.common.enums.HandleEnum;
import com.foreverwin.mesnac.common.mapper.ProdReadyTaskMapper;
import com.foreverwin.mesnac.common.model.ProdReadyTask;
import com.foreverwin.mesnac.common.model.ProdReadyTaskDetail;
import com.foreverwin.mesnac.common.service.ProdReadyTaskDetailService;
import com.foreverwin.mesnac.common.service.ProdReadyTaskService;
import com.foreverwin.mesnac.common.util.StringUtil;
import com.foreverwin.mesnac.meapi.dto.BomComponentDto;
import com.foreverwin.mesnac.meapi.model.ShopOrder;
import com.foreverwin.mesnac.meapi.model.WorkCenter;
import com.foreverwin.mesnac.meapi.service.BomComponentService;
import com.foreverwin.mesnac.meapi.service.CustomFieldsService;
import com.foreverwin.mesnac.meapi.service.ShopOrderService;
import com.foreverwin.mesnac.meapi.service.WorkCenterService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 生产准备任务主表 服务实现类
 * </p>
 *
 * @author Philip
 * @since 2021-06-23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProdReadyTaskServiceImpl extends ServiceImpl<ProdReadyTaskMapper, ProdReadyTask> implements ProdReadyTaskService {

    public static final String P01="P01";
    public static final String P02="P02";
    public static final String P03="P03";
    public static final String STATUS_WAITING="W";
    public static final String STATUS_DOING="I";
    public static final String STATUS_FINSH="F";
    public static final String STATUS_CANCEL="C";

    @Autowired
    private ProdReadyTaskMapper prodReadyTaskMapper;
    @Autowired
    private ProdReadyTaskDetailService prodReadyTaskDetailService;
    @Autowired
    private BomComponentService bomComponentService;
    @Autowired
    private CustomFieldsService customFieldsService;
    @Autowired
    private ShopOrderService shopOrderService;
    @Autowired
    private WorkCenterService workCenterService;
    @Override
    public IPage<ProdReadyTask> selectPage(FrontPage<ProdReadyTask> frontPage, ProdReadyTask prodReadyTask) {
        QueryWrapper<ProdReadyTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(prodReadyTask);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<ProdReadyTask> selectList(ProdReadyTask prodReadyTask) {
        QueryWrapper<ProdReadyTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(prodReadyTask);
        return super.list(queryWrapper);
    }
    @Override
    public void createTask(String sfcDispatchBO, String dispatchStatus, String shopOrder,String sfc, String operation, String resrce, String stepId, String workCenter, String planStartTime)  {
        //根据站点及派工BO查询数据
        String site = CommonMethods.getSite();
        String user = CommonMethods.getUser();

        Date planTime = null;
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            planTime = dateFormat.parse(planStartTime);
        }
        catch (Exception e) {
            throw new BaseException("工单[" + shopOrder + "]计划开始时间格式错误，请核查！");
        }
        ShopOrder byId = shopOrderService.getById(HandleEnum.SHOP_ORDER.getHandle(site, shopOrder));
        if ("RELEASE".equals(dispatchStatus)) {
            ProdReadyTask prodReadyTask=new ProdReadyTask();
            prodReadyTask.setSite(site);
            prodReadyTask.setTaskNo(StringUtil.createQUID());
            prodReadyTask.setHandle(HandleEnum.PROD_READY_TASK.getHandle(site,prodReadyTask.getTaskNo()));
            prodReadyTask.setSfcDispatchBo(sfcDispatchBO);
            prodReadyTask.setShopOrder(shopOrder);
            prodReadyTask.setWorkCenter(workCenter);
            prodReadyTask.setSfc(sfc);
            prodReadyTask.setOperation(operation);
            prodReadyTask.setStepId(stepId);
            prodReadyTask.setItem(StringUtil.trimHandle(byId.getItemBo()));
            prodReadyTask.setResrce(resrce);
            prodReadyTask.setCreateUser(user);
            prodReadyTask.setCreatedDateTime(LocalDateTime.now());
            prodReadyTask.setModifyUser(user);
            prodReadyTask.setModifiedDateTime(LocalDateTime.now());
            List<ProdReadyTaskDetail> prodReadyTaskDetailList = new ArrayList<>();

            String sfcBo = HandleEnum.SFC.getHandle(site, sfc);
            List<BomComponentDto> bomComponentList = bomComponentService.getSfcBomComponent(sfcBo);
            if (!bomComponentList.isEmpty()){
                bomComponentList.forEach(bomComponentDto ->{
                    if (bomComponentDto.getOperation().equals(operation)&&bomComponentDto.getStepId().equals(stepId)){
                        String accessoryType = bomComponentDto.getAccessoryType();
                        //物料P001，校验当前派工单（SFC+工序/步骤）加工是否需要准备物料
                        if (accessoryType==null||accessoryType.equals("0")){
                            ProdReadyTaskDetail prodReadyTaskDetail=new ProdReadyTaskDetail();
                            prodReadyTaskDetail.setHandle(HandleEnum.PROD_READY_TASK_DETAIL.getHandle(prodReadyTask.getHandle(),P01));
                            prodReadyTaskDetail.setProdReadyTaskBo(prodReadyTask.getHandle());
                            prodReadyTaskDetail.setInspectionItem(P01);
                            prodReadyTaskDetail.setResult("");
                            prodReadyTaskDetail.setRemarks("");
                            prodReadyTaskDetail.setCreateUser(user);
                            prodReadyTaskDetail.setCreatedDateTime(LocalDateTime.now());
                            prodReadyTaskDetail.setModifyUser(user);
                            prodReadyTaskDetail.setModifiedDateTime(LocalDateTime.now());
                            prodReadyTaskDetailList.add(prodReadyTaskDetail);
                        }else if (accessoryType.equals("1")){
                            //刀具P002，校验当前派工单（SFC+工序/步骤）加工是否需要准备物料
                            ProdReadyTaskDetail prodReadyTaskDetail=new ProdReadyTaskDetail();
                            prodReadyTaskDetail.setHandle(HandleEnum.PROD_READY_TASK_DETAIL.getHandle(prodReadyTask.getHandle(),P02));
                            prodReadyTaskDetail.setProdReadyTaskBo(prodReadyTask.getHandle());
                            prodReadyTaskDetail.setInspectionItem(P02);
                            prodReadyTaskDetail.setResult("");
                            prodReadyTaskDetail.setRemarks("");
                            prodReadyTaskDetail.setCreateUser(user);
                            prodReadyTaskDetail.setCreatedDateTime(LocalDateTime.now());
                            prodReadyTaskDetail.setModifyUser(user);
                            prodReadyTaskDetail.setModifiedDateTime(LocalDateTime.now());
                            prodReadyTaskDetailList.add(prodReadyTaskDetail);
                        }
                    }
                } );
            }
            //工控程序P003，工控程序，校验是否需要准备工控程序
            String customFieldsValue = customFieldsService.getCustomFieldsValue(HandleEnum.WORK_CENTER.getHandle(site, workCenter), CustomFieldConstant.WORK_CENTER_CUSTOM_FIELD_PROCESS_CONTROL);
            if (StringUtil.notBlank(customFieldsValue)&&customFieldsValue.equals(Constants.STATUS_Y)){
                customFieldsValue = customFieldsService.getCustomFieldsValue(HandleEnum.RESOURCE.getHandle(site, resrce), CustomFieldConstant.RESRCE_CUSTOM_FIELD_PROCESS_CONTROL);
                if (StringUtil.notBlank(customFieldsValue)&&customFieldsValue.equals(Constants.STATUS_Y)) {
                    ProdReadyTaskDetail prodReadyTaskDetail=new ProdReadyTaskDetail();
                    prodReadyTaskDetail.setHandle(HandleEnum.PROD_READY_TASK_DETAIL.getHandle(prodReadyTask.getHandle(),P03));
                    prodReadyTaskDetail.setProdReadyTaskBo(prodReadyTask.getHandle());
                    prodReadyTaskDetail.setInspectionItem(P03);
                    prodReadyTaskDetail.setResult("");
                    prodReadyTaskDetail.setRemarks("");
                    prodReadyTaskDetail.setCreateUser(user);
                    prodReadyTaskDetail.setCreatedDateTime(LocalDateTime.now());
                    prodReadyTaskDetail.setModifyUser(user);
                    prodReadyTaskDetail.setModifiedDateTime(LocalDateTime.now());
                    prodReadyTaskDetailList.add(prodReadyTaskDetail);
                }
            }
            if (prodReadyTaskDetailList.size()>0){
                prodReadyTask.setStatus(STATUS_WAITING);
                prodReadyTaskDetailService.saveBatch(prodReadyTaskDetailList);
            }else {
                prodReadyTask.setStatus(STATUS_FINSH);
                prodReadyTask.setCompleteUser(user);
                prodReadyTask.setCompleteDateTime(LocalDateTime.now());
            }
            save(prodReadyTask);
        }else if("CANCEL".equals(dispatchStatus)){
            LambdaQueryWrapper<ProdReadyTask> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ProdReadyTask::getSfcDispatchBo,sfcDispatchBO);
            lambdaQueryWrapper.orderByDesc(ProdReadyTask::getCreatedDateTime);
            List<ProdReadyTask> list = list(lambdaQueryWrapper);
            if (list.size()<1){
                throw new BaseException("根据派工主键未找到产前准备任务");
            }
            if (list.get(0).getStatus().equals(STATUS_CANCEL)){
                throw new BaseException("产前准备任务任务已取消");
            }
            LambdaUpdateWrapper<ProdReadyTask> updateWrapper=new LambdaUpdateWrapper<>();
            updateWrapper.set(ProdReadyTask::getStatus,STATUS_CANCEL);
            updateWrapper.set(ProdReadyTask::getCancelUser,user);
            updateWrapper.set(ProdReadyTask::getCancelDateTime,LocalDateTime.now());
            updateWrapper.eq(ProdReadyTask::getSfcDispatchBo,sfcDispatchBO);
            update(updateWrapper);
        }

    }

    @Override
    public List<ProdReadyTask> getTaskList(ProdReadyTask prodReadyTask) {
        return prodReadyTaskMapper.getTaskList(prodReadyTask, LocaleContextHolder.getLocale().getLanguage());
    }

    @Override
    public ProdReadyTask loadProExecute(String taskBo) {
        ProdReadyTask prodReadyTask = prodReadyTaskMapper.selectById(taskBo);
        if (prodReadyTask.getStatus().equals(STATUS_WAITING)){
            prodReadyTask.setReadyUser(CommonMethods.getUser());
            prodReadyTask.setReadyDateTime(LocalDateTime.now());
            prodReadyTask.setModifyUser(CommonMethods.getUser());
            prodReadyTask.setModifiedDateTime(LocalDateTime.now());
            prodReadyTask.setStatus(STATUS_DOING);
            updateById(prodReadyTask);
        }
        WorkCenter workCenter=new WorkCenter();
        workCenter.setWorkCenter(prodReadyTask.getWorkCenter());
        workCenter.setSite(CommonMethods.getSite());
        List<WorkCenter> workCenters = workCenterService.selectList(workCenter);
        prodReadyTask.setWorkCenterDesc(workCenters.get(0).getDescription());
        prodReadyTask.setDispatchNo(StringUtil.trimHandle(prodReadyTask.getSfcDispatchBo()));
        LambdaQueryWrapper<ProdReadyTaskDetail> lambdaQuery=new LambdaQueryWrapper<>();
        lambdaQuery.eq(ProdReadyTaskDetail::getProdReadyTaskBo,taskBo);
        List<ProdReadyTaskDetail> list = prodReadyTaskDetailService.list(lambdaQuery);
        prodReadyTask.setProdReadyTaskDetailList(list);
        return prodReadyTask;
    }

    @Override
    public List<Map<String, Object>> getInspectionDetailList(Map<String, String> param) {
        String type = param.get("type");
        String dispatchNo = param.get("dispatchNo");
        List<Map<String, Object>> returnMap = null;
        String site = CommonMethods.getSite();
        if (type.equals(P01)){
            //物料接收数据
             returnMap=prodReadyTaskMapper.getItemDetail(site,LocaleContextHolder.getLocale().getLanguage(),dispatchNo);
        }else if (type.equals(P02)){
            //刀具
            returnMap=prodReadyTaskMapper.getToolDetail(site,LocaleContextHolder.getLocale().getLanguage(),dispatchNo);
        }else {
            //通过加工的零件号、设备类型、设备获取发布状态的工控程序
        }
        return returnMap;
    }

    @Override
    public boolean saveResult(ProdReadyTask prodReadyTask) {
        String user = CommonMethods.getUser();
        ProdReadyTask byId = getById(prodReadyTask.getHandle());
        if (byId.getStatus().equals(STATUS_CANCEL)){
            throw new BaseException("产前准备任务任务已取消");
        }
        if (byId.getStatus().equals(STATUS_FINSH)){
            throw new BaseException("产前准备任务任务已完成");
        }
        List<ProdReadyTaskDetail> prodReadyTaskDetailList = prodReadyTask.getProdReadyTaskDetailList();
        prodReadyTask.setStatus(STATUS_FINSH);
        prodReadyTask.setCompleteUser(user);
        prodReadyTask.setCompleteDateTime(LocalDateTime.now());
        prodReadyTask.setModifyUser(user);
        prodReadyTask.setModifiedDateTime(LocalDateTime.now());
        boolean update = updateById(prodReadyTask);
        if (prodReadyTaskDetailList!=null&&prodReadyTaskDetailList.size()>0){
            for (ProdReadyTaskDetail prodReadyTaskDetail:prodReadyTaskDetailList) {
                prodReadyTaskDetail.setModifyUser(user);
                prodReadyTaskDetail.setModifiedDateTime(LocalDateTime.now());
                prodReadyTaskDetailService.updateById(prodReadyTaskDetail);
            }
        }
        return update;
    }


}