package com.ximai.mes.pro.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ximai.common.annotation.Log;
import com.ximai.common.core.controller.BaseController;
import com.ximai.common.core.domain.AjaxResult;
import com.ximai.common.core.page.TableDataInfo;
import com.ximai.common.enums.BusinessType;
import com.ximai.common.utils.SecurityUtils;
import com.ximai.common.utils.data.ExceptionUtil;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.common.utils.poi.ExcelUtil;
import com.ximai.mes.constant.TaskWorkunitStatusEnum;
import com.ximai.mes.md.domain.MdWorkunit;
import com.ximai.mes.md.domain.MdWorkunitWorker;
import com.ximai.mes.md.mapper.MdWorkunitWorkerMapper;
import com.ximai.mes.md.service.IMdWorkstationService;
import com.ximai.mes.md.service.IMdWorkunitService;
import com.ximai.mes.md.vo.MdWorkunitVo;
import com.ximai.mes.pro.domain.ProFeedback;
import com.ximai.mes.pro.domain.task.ProTaskAssistProcess;
import com.ximai.mes.pro.domain.vo.ProFeedbackVo;
import com.ximai.mes.pro.dto.ProFeedbackCheckListDto;
import com.ximai.mes.pro.mapper.ProFeedbackMapper;
import com.ximai.mes.pro.mapper.task.ProTaskAssistProcessMapper;
import com.ximai.mes.pro.service.IProFeedbackService;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkOrderSoSizeItemService;
import com.ximai.mes.report.response.FeedbackResponseExportByList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产报工记录Controller
 *
 * @date 2022-07-10
 */
@RestController
@Api(tags = "生产报工记录")
@RequestMapping("/mes/pro/feedback")
public class ProFeedbackController extends BaseController {
    @Autowired
    private IProFeedbackService proFeedbackService;
    @Resource
    private MdWorkunitWorkerMapper mdWorkunitWorkerMapper;
    @Resource
    private ProFeedbackMapper proFeedbackMapper;

    @Autowired
    private IProWorkOrderSoSizeItemService proWorkOrderSoSizeItemService;
    @Resource
    private ProTaskAssistProcessMapper proTaskAssistProcessMapper;

    @Autowired
    private IMdWorkunitService mdWorkunitService;
    /**
     * 查询生产报工记录列表
     */
    @GetMapping("/list")
    public TableDataInfo<ProFeedbackVo> list(ProFeedbackCheckListDto proFeedbackCheckListDto) {
        ProFeedback proFeedback = new ProFeedback();
        BeanUtils.copyProperties(proFeedbackCheckListDto,proFeedback);
        QueryWrapper<ProFeedback> query = new QueryWrapper<>();
        query.eq(StringUtils.isNotEmpty(proFeedback.getFeedbackType()), "f.feedback_type", proFeedback.getFeedbackType());
        query.eq(StringUtils.isNotEmpty(proFeedback.getStatus()), "f.status", proFeedback.getStatus());
        query.eq(StringUtils.isNotEmpty(proFeedback.getAssistProcessCode()), "ap.assist_process_code", proFeedback.getAssistProcessCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkstationName()), "f.workstation_name", proFeedback.getWorkstationName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getItemName()), "it.item_name", proFeedback.getItemName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkorderCode()), "f.workorder_code", proFeedback.getWorkorderCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getSapItemCode()), "it.sap_item_code", proFeedback.getSapItemCode());

        query.like(StringUtils.isNotEmpty(proFeedback.getOrderCode()), "workorder.order_code",
                proFeedback.getOrderCode());
        query.like(StringUtils.isNotEmpty(proFeedback.getOrderSerial()), "workorder.order_serial",
                proFeedback.getOrderSerial());
        query.like(StringUtils.isNotEmpty(proFeedback.getCustomerDrawingNo()), "workorder.Customer_Drawing_No",
                proFeedback.getCustomerDrawingNo());
        query.eq(proFeedback.getLastFeedback() != null , "f.Last_Feedback", proFeedback.getLastFeedback());
//        query.eq(StringUtils.isNotEmpty(proFeedback.getUserId()), "pww.user_id", proFeedback.getUserId());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkunitId()), "tw.workunit_id", proFeedback.getWorkunitId());
        if(proFeedbackCheckListDto.getIsCheckUser() && StringUtils.isEmpty(proFeedback.getWorkunitId())){

            List<MdWorkunitVo> mdWorkunitVolist = mdWorkunitService.selectMdWorkunitListByUser(new QueryWrapper<MdWorkunit>().eq("user_name", SecurityUtils.getUsername()));
            if(mdWorkunitVolist.size() < 1)
                return  getDataTable(new ArrayList<>());
            query.in(mdWorkunitVolist.size() > 0 , "tw.workunit_id", mdWorkunitVolist.stream().map(mdWorkunitVo -> mdWorkunitVo.getWorkunitId()).collect(Collectors.toList()));
        }
        query.eq(StringUtils.isNotEmpty(proFeedback.getTaskWorkunitId()), "tw.task_workunit_id", proFeedback.getTaskWorkunitId());
        query.between(StringUtils.isNotEmpty(proFeedback.getCreateStartTime()) && StringUtils.isNotEmpty(proFeedback.getCreateEndTime()), "f.update_time", proFeedback.getCreateStartTime(), proFeedback.getCreateEndTime());
        query.like(StringUtils.isNotEmpty(proFeedback.getNickName()), "f.nick_name", proFeedback.getNickName());
        query.notIn("tw.status", TaskWorkunitStatusEnum.CLOSE.getStatus());
        query.like(StringUtils.isNotEmpty(proFeedbackCheckListDto.getProcessName()), "f.process_name", proFeedbackCheckListDto.getProcessName());
        query.eq(StringUtils.isNotEmpty(proFeedbackCheckListDto.getTaskBatch()), "SUBSTRING_INDEX(ta.task_batch, '-', -1)", proFeedbackCheckListDto.getTaskBatch());
        query.between(proFeedbackCheckListDto.getFeedbackTimeStart() != null && proFeedbackCheckListDto.getFeedbackTimeEnd() != null,
                "f.feedback_time", proFeedbackCheckListDto.getFeedbackTimeStart(), proFeedbackCheckListDto.getFeedbackTimeEnd());
        query.orderByDesc("f.create_time");
        startPage();
        List<ProFeedbackVo> list = proFeedbackService.queryProFeedbackListJoinTaskWorkUnit(query);
        List<ProFeedbackVo> proFeedbackVoList = new ArrayList<>();
        if (proFeedback.getUserId() != null) {
            List<MdWorkunitWorker> mdWorkunitWorkers = mdWorkunitWorkerMapper.selectListByQw(new QueryWrapper<MdWorkunitWorker>().eq("user_id", proFeedback.getUserId()));
            Set<Long> collect = mdWorkunitWorkers.stream().map(MdWorkunitWorker::getWorkunitId).collect(Collectors.toSet());
//            objects = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getFeedbackTime).reversed()).collect(Collectors.toList());
            proFeedbackVoList = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getUpdateTime).reversed()).collect(Collectors.toList());
        }
        proFeedbackVoList = proFeedbackVoList.isEmpty() ? list : proFeedbackVoList;
        proFeedbackVoList.forEach(s->{
            if(IMdWorkstationService.OUTSOURCE_WORKSTATION_ID.equals(s.getWorkstationId())){
                s.setAssistProcessCode(s.getTaskCode());
            }
        });


        return getDataTable(proFeedbackVoList);
    }
    /**
     * 查询生产报工记录列表
     */
    @PostMapping("/list/export")
    @ApiOperation("查询生产报工记录列表导出")
    public void listExport(HttpServletResponse response,@RequestBody  ProFeedbackCheckListDto proFeedbackCheckListDto) {
        ProFeedback proFeedback = new ProFeedback();
        BeanUtils.copyProperties(proFeedbackCheckListDto,proFeedback);
        QueryWrapper<ProFeedback> query = new QueryWrapper<>();
        query.eq(StringUtils.isNotEmpty(proFeedback.getFeedbackType()), "f.feedback_type", proFeedback.getFeedbackType());
        query.eq(StringUtils.isNotEmpty(proFeedback.getStatus()), "f.status", proFeedback.getStatus());
        query.eq(StringUtils.isNotEmpty(proFeedback.getAssistProcessCode()), "ap.assist_process_code", proFeedback.getAssistProcessCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkstationName()), "f.workstation_name", proFeedback.getWorkstationName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getItemName()), "it.item_name", proFeedback.getItemName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkorderCode()), "f.workorder_code", proFeedback.getWorkorderCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getSapItemCode()), "it.sap_item_code", proFeedback.getSapItemCode());

        query.like(StringUtils.isNotEmpty(proFeedback.getOrderCode()), "workorder.order_code",
                proFeedback.getOrderCode());
        query.like(StringUtils.isNotEmpty(proFeedback.getOrderSerial()), "workorder.order_serial",
                proFeedback.getOrderSerial());
        query.like(StringUtils.isNotEmpty(proFeedback.getCustomerDrawingNo()), "workorder.Customer_Drawing_No",
                proFeedback.getCustomerDrawingNo());
        query.eq(proFeedback.getLastFeedback() != null , "f.Last_Feedback", proFeedback.getLastFeedback());
//        query.eq(StringUtils.isNotEmpty(proFeedback.getUserId()), "pww.user_id", proFeedback.getUserId());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkunitId()), "tw.workunit_id", proFeedback.getWorkunitId());
        if(proFeedbackCheckListDto.getIsCheckUser() && StringUtils.isEmpty(proFeedback.getWorkunitId())){

            List<MdWorkunitVo> mdWorkunitVolist = mdWorkunitService.selectMdWorkunitListByUser(new QueryWrapper<MdWorkunit>().eq("user_name", SecurityUtils.getUsername()));
            if(mdWorkunitVolist.size() < 1){
                ExcelUtil<ProFeedbackVo> util = new ExcelUtil<>(ProFeedbackVo.class);
                util.exportExcel(response, new ArrayList<>(), "生产报工记录列表","生产报工记录列表");
            }
            query.in(mdWorkunitVolist.size() > 0 , "tw.workunit_id", mdWorkunitVolist.stream().map(mdWorkunitVo -> mdWorkunitVo.getWorkunitId()).collect(Collectors.toList()));
        }
        query.eq(StringUtils.isNotEmpty(proFeedback.getTaskWorkunitId()), "tw.task_workunit_id", proFeedback.getTaskWorkunitId());
        query.between(StringUtils.isNotEmpty(proFeedback.getCreateStartTime()) && StringUtils.isNotEmpty(proFeedback.getCreateEndTime()), "f.update_time", proFeedback.getCreateStartTime(), proFeedback.getCreateEndTime());
        query.like(StringUtils.isNotEmpty(proFeedback.getNickName()), "f.nick_name", proFeedback.getNickName());
        query.notIn("tw.status", TaskWorkunitStatusEnum.CLOSE.getStatus());
        query.like(StringUtils.isNotEmpty(proFeedbackCheckListDto.getProcessName()), "f.process_name", proFeedbackCheckListDto.getProcessName());
        query.eq(StringUtils.isNotEmpty(proFeedbackCheckListDto.getTaskBatch()), "SUBSTRING_INDEX(ta.task_batch, '-', -1)", proFeedbackCheckListDto.getTaskBatch());
        query.between(proFeedbackCheckListDto.getFeedbackTimeStart() != null && proFeedbackCheckListDto.getFeedbackTimeEnd() != null,
                "f.feedback_time", proFeedbackCheckListDto.getFeedbackTimeStart(), proFeedbackCheckListDto.getFeedbackTimeEnd());
        query.orderByDesc("f.create_time");
        List<ProFeedbackVo> list = proFeedbackService.queryProFeedbackListJoinTaskWorkUnit(query);
        List<ProFeedbackVo> proFeedbackVoList = new ArrayList<>();
        if (proFeedback.getUserId() != null) {
            List<MdWorkunitWorker> mdWorkunitWorkers = mdWorkunitWorkerMapper.selectListByQw(new QueryWrapper<MdWorkunitWorker>().eq("user_id", proFeedback.getUserId()));
            Set<Long> collect = mdWorkunitWorkers.stream().map(MdWorkunitWorker::getWorkunitId).collect(Collectors.toSet());
//            objects = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getFeedbackTime).reversed()).collect(Collectors.toList());
            proFeedbackVoList = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getUpdateTime).reversed()).collect(Collectors.toList());
        }
        proFeedbackVoList = proFeedbackVoList.isEmpty() ? list : proFeedbackVoList;
        proFeedbackVoList.forEach(s->{
            if(IMdWorkstationService.OUTSOURCE_WORKSTATION_ID.equals(s.getWorkstationId())){
                s.setAssistProcessCode(s.getTaskCode());
            }
            if(s.getFeedbackType().equals("SELF")){
                s.setFeedbackType("自行报工");
            }else{
                s.setFeedbackType("外协报工");
            }
        });


        ExcelUtil<ProFeedbackVo> util = new ExcelUtil<>(ProFeedbackVo.class);
        util.exportExcel(response, proFeedbackVoList, "生产报工记录列表","生产报工记录列表");
    }
    /**
     * 查询生产报工记录列表
     */
    @GetMapping("/listByUserId")
    public TableDataInfo<ProFeedbackVo> listByUserId(ProFeedback proFeedback) {
        startPage();
        List<MdWorkunitVo> mdWorkunitVolist = mdWorkunitService.selectMdWorkunitListByUser(new QueryWrapper<MdWorkunit>().eq("user_name", SecurityUtils.getUsername()));
        if(mdWorkunitVolist.size() < 1)
            return  getDataTable(new ArrayList<>());
        QueryWrapper<ProFeedback> query = new QueryWrapper<>();
        query.eq(StringUtils.isNotEmpty(proFeedback.getFeedbackType()), "f.feedback_type", proFeedback.getFeedbackType());
        query.eq(StringUtils.isNotEmpty(proFeedback.getStatus()), "f.status", proFeedback.getStatus());
        query.eq(StringUtils.isNotEmpty(proFeedback.getAssistProcessCode()), "ap.assist_process_code", proFeedback.getAssistProcessCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkstationName()), "f.workstation_name", proFeedback.getWorkstationName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getItemName()), "it.item_name", proFeedback.getItemName());
        query.eq(StringUtils.isNotEmpty(proFeedback.getWorkorderCode()), "f.workorder_code", proFeedback.getWorkorderCode());
        query.eq(StringUtils.isNotEmpty(proFeedback.getSapItemCode()), "it.sap_item_code", proFeedback.getSapItemCode());
        query.eq(proFeedback.getLastFeedback() != null , "f.Last_Feedback", proFeedback.getLastFeedback());
        //query.eq(StringUtils.isNotEmpty(proFeedback.getUserId()), "pww.user_id", proFeedback.getUserId());
        //query.eq(StringUtils.isNotEmpty(proFeedback.getWorkunitId()), "tw.workunit_id", proFeedback.getWorkunitId());
        query.in(mdWorkunitVolist.size() > 0 , "tw.workunit_id", mdWorkunitVolist.stream().map(mdWorkunitVo -> mdWorkunitVo.getWorkunitId()).collect(Collectors.toList()));
        query.eq(StringUtils.isNotEmpty(proFeedback.getTaskWorkunitId()), "tw.task_workunit_id", proFeedback.getTaskWorkunitId());
        query.between(StringUtils.isNotEmpty(proFeedback.getCreateStartTime()) && StringUtils.isNotEmpty(proFeedback.getCreateEndTime()), "f.update_time", proFeedback.getCreateStartTime(), proFeedback.getCreateEndTime());
        query.like(StringUtils.isNotEmpty(proFeedback.getNickName()), "f.nick_name", proFeedback.getNickName());
        query.notIn("tw.status", TaskWorkunitStatusEnum.CLOSE.getStatus());
        query.orderByDesc("f.create_time");
        List<ProFeedbackVo> list = proFeedbackService.queryProFeedbackListJoinTaskWorkUnit(query);
        List<ProFeedbackVo> proFeedbackVoList = new ArrayList<>();
        if (proFeedback.getUserId() != null) {
            List<MdWorkunitWorker> mdWorkunitWorkers = mdWorkunitWorkerMapper.selectListByQw(new QueryWrapper<MdWorkunitWorker>().eq("user_id", proFeedback.getUserId()));
            Set<Long> collect = mdWorkunitWorkers.stream().map(MdWorkunitWorker::getWorkunitId).collect(Collectors.toSet());
//            objects = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getFeedbackTime).reversed()).collect(Collectors.toList());
            proFeedbackVoList = list.stream().filter(x -> !collect.add(x.getWorkunitId())).sorted(Comparator.comparing(ProFeedbackVo::getUpdateTime).reversed()).collect(Collectors.toList());
        }
        proFeedbackVoList = proFeedbackVoList.isEmpty() ? list : proFeedbackVoList;
        proFeedbackVoList.forEach(s->{
            if(IMdWorkstationService.OUTSOURCE_WORKSTATION_ID.equals(s.getWorkstationId())){
                s.setAssistProcessCode(s.getTaskCode());
            }
        });


        return getDataTable(proFeedbackVoList);
    }
    /**
     * 获取生产报工记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:query')")
    @GetMapping(value = "/{recordId}")
    public AjaxResult getInfo(@PathVariable("recordId") Long recordId) {
        return AjaxResult.success(proFeedbackService.selectProFeedbackByRecordId(recordId));
    }

    /**
     * 新增生产报工记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:add')")
    @Log(title = "生产报工记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ProFeedback proFeedback) {
        return toAjax(proFeedbackService.insertObj(proFeedback));
    }

    /**
     * 修改生产报工记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:edit')")
    @Log(title = "生产报工记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ProFeedback proFeedback) {
        return toAjax(proFeedbackService.updateObj(proFeedback));
    }

    /**
     * 修改生产报工记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:edit')")
    @Log(title = "生产报工记录", businessType = BusinessType.UPDATE)
    @PutMapping("/editOut5Min")
    public AjaxResult editOut5Min(@RequestBody ProFeedback proFeedback) {
        return toAjax(proFeedbackService.updateObj(proFeedback));
    }

    /**
     * 删除生产报工记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:remove')")
    @Log(title = "生产报工记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/deleteOut5Min/{recordIds}")
    public AjaxResult deleteOut5Min(@PathVariable Long[] recordIds) {
        List<ProFeedback> proFeedbacks = proFeedbackMapper.selectListByQw(new QueryWrapper<ProFeedback>().in("record_id", Arrays.asList(recordIds)));
        return toAjax(proFeedbackService.deleteProFeedbackByRecordIds(recordIds));
    }

    /**
     * 删除生产报工记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:remove')")
    @Log(title = "生产报工记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{recordIds}")
    public AjaxResult remove(@PathVariable Long[] recordIds) {
        return toAjax(proFeedbackService.deleteProFeedbackByRecordIds(recordIds));
    }


    /**
     * 执行报工
     * 1.更新生产任务和生产工单的进度
     * 2.物料消耗
     * 3.产品产出
     *
     * @param recordId
     * @return
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:edit')")
    @Log(title = "生产报工执行", businessType = BusinessType.UPDATE)
    @Transactional
    @PutMapping("/{recordId}")
    public AjaxResult execute(@PathVariable("recordId") Long recordId) {
        return toAjax(proFeedbackService.syncSap(recordId));
    }

    /**
     * 批量推送 SAP：末道工序推生产入库，非末道工序推生产转移单
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:edit')")
    @Log(title = "生产报工推送SAP", businessType = BusinessType.UPDATE)
    @PostMapping("/syncSap")
    public AjaxResult syncSapBatch(@RequestBody Long[] recordIds) {
        return AjaxResult.success(proFeedbackService.syncSapBatch(recordIds));
    }

    /**
     * 报工修改记录
     */
    @PreAuthorize("@ss.hasPermi('mes:pro:feedback:query')")
    @GetMapping("/modifyRecord/{recordId}")
    public AjaxResult listModifyRecord(@PathVariable Long recordId) {
        return AjaxResult.success(proFeedbackService.listModifyRecord(recordId));
    }


}
