/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.youchain.basicdata.rest;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.youchain.annotation.Log;
import com.youchain.basicdata.domain.*;
import com.youchain.basicdata.repository.AreaRepository;
import com.youchain.basicdata.repository.AutomaticPlanningRepository;
import com.youchain.basicdata.repository.ProductionPlanRepository;
import com.youchain.basicdata.service.*;
import com.youchain.basicdata.service.dto.AutomaticPlanningDto;
import com.youchain.basicdata.service.dto.AutomaticPlanningQueryCriteria;
import com.youchain.businessdata.domain.PickDetail;
import com.youchain.businessdata.domain.PickTicket;
import com.youchain.businessdata.domain.PlanPickDetail;
import com.youchain.businessdata.repository.PickTicketRepository;
import com.youchain.businessdata.repository.PlanPickDetailRepository;
import com.youchain.businessdata.service.*;
import com.youchain.businessdata.service.impl.InventoryBakServiceImpl;
import com.youchain.config.FileProperties;
import com.youchain.exception.BadRequestException;
import com.youchain.exception.handler.ApiError;
import com.youchain.modules.system.domain.Dept;
import com.youchain.utils.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @author JiangKun
* @date 2024-01-05
**/
@RestController
@RequiredArgsConstructor
@Slf4j
@Api(tags = "automaticPlanning管理")
@RequestMapping("/api/automaticPlanning")
public class AutomaticPlanningController {

    private final AutomaticPlanningService automaticPlanningService;
    private final AutomaticPlanningRepository automaticPlanningRepository;
    private final AutomaticPlanDetailService automaticPlanDetailService;
    private final InventoryBakService inventoryBakService;
    private final ProductionPlanService productionPlanService;
    private final ProductionPlanRepository productionPlanRepository;
    private final BomAccountService bomAccountService;
    private final PlanPickDetailService planPickDetailService;
    //导入
    private final FileProperties properties;
    private final AreaRepository areaRepository;
    private final CodeUtils codeUtils;

    @Log("导入上线计划")
    @PostMapping(value = "/importAutomaticPlanning")
    @ApiOperation("导入上线计划")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> importAutomaticPlanning(@RequestParam("file") MultipartFile multipartFile,@RequestParam(value = "isSx")Boolean isSx) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize());
        String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        String type = FileUtil.getFileType(suffix);
        File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator);
        ExcelReader reader = ExcelUtil.getReader(file);
        List<Map<String, Object>> readAll = reader.readAll();
        String code =  codeUtils.getCode_yyMMdd("ZD",3);
        int i = 0;
        for (i = 0; i < readAll.size(); i++) {
            Timestamp jhDate = null;
            String jhrq = OptionalUtils.getTrimmedString(readAll.get(i), "计划日期", null);
            int fxQuantity =OptionalUtils.getTrimmedInteger(readAll.get(i), "已铺线数量", 0);
            int sxQuantity = OptionalUtils.getTrimmedInteger(readAll.get(i), "上线计划数", 0);
            if(isSx==false){
                sxQuantity = OptionalUtils.getTrimmedInteger(readAll.get(i), "上线耗用数", 0);
            }
            int batchNum = OptionalUtils.getTrimmedInteger(readAll.get(i), "分批次数", 0);
            int shHour = OptionalUtils.getTrimmedInteger(readAll.get(i), "送货小时", 0);
            Boolean isEnd = OptionalUtils.getBooleanValue(readAll.get(i), "是否手工", false);
            String zdStartNum = OptionalUtils.getTrimmedString(readAll.get(i), "指定开始机号", null);
            String endNum = OptionalUtils.getTrimmedString(readAll.get(i), "结束IDNO", null);
            String description =OptionalUtils.getTrimmedString(readAll.get(i), "备注", null);
            String shck = OptionalUtils.getTrimmedString(readAll.get(i), "收货仓库", null);
            if(shck.equals("")){
                break;
            }
            if (!"".equals(jhrq)) {
                jhDate = Timestamp.valueOf(jhrq);
            }
            Area shArea = areaRepository.getByName(shck);
            if (shArea == null) {
                throw new BadRequestException(shck + "收货仓库不存在");
            }
            List<AutomaticPlanning> plans = automaticPlanningRepository.existSxData(shArea.getId(),isSx);
            AutomaticPlanning automaticPlanning = null;
            if (plans.size() > 0) {
                automaticPlanning = plans.get(0);
            } else {
                automaticPlanning = new AutomaticPlanning();
                automaticPlanning.setShArea(shArea);
                automaticPlanning.setDept(UserUtils.getDept());
                automaticPlanning.setIsSx(isSx);
            }
            automaticPlanning.setCode(code);
            automaticPlanning.setZdStartNum(zdStartNum);
            automaticPlanning.setJhDate(jhDate);
            automaticPlanning.setFxQuantity(fxQuantity);
            automaticPlanning.setSxQuantity(sxQuantity);
            automaticPlanning.setBatchNum(batchNum);
            automaticPlanning.setShHour(shHour);
            automaticPlanning.setDescription(description);
            automaticPlanning.setIsEnd(isEnd);
            if (plans.size() == 0) {
                automaticPlanningService.create(automaticPlanning);
            }
            String gw=automaticPlanning.getShArea().getWorkingStation();
            HashMap<String,String> map= productionPlanService.getEndIdNO(gw,automaticPlanning.getSxQuantity());
            List<ProductionPlan> whyList =null;
            if(!automaticPlanning.getIsEnd()) {
                whyList=productionPlanRepository.getIdNoAllData(gw, map.get("endNum"));
                automaticPlanning.setEndNum(map.get("endNum"));
            }else {
                automaticPlanning.setEndNum(endNum);
                whyList = productionPlanRepository.getList(gw,map.get("startNum"),automaticPlanning.getEndNum());
            }
            if(zdStartNum!=null&&!zdStartNum.equals("")){
                whyList = productionPlanRepository.getList(gw,zdStartNum,automaticPlanning.getEndNum());
            }
            automaticPlanning.setStartNum(map.get("startNum"));
            automaticPlanning.setJhQuantity(whyList.size());
            automaticPlanning.setScEndNum(productionPlanRepository.getIdNoWhyScGw(gw));
            automaticPlanning.setStatus("未审核");
            automaticPlanningService.update(automaticPlanning);
        }
        return new ResponseEntity<>("导入成功",HttpStatus.OK);
    }


    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('super:man')")
    public void exportAutomaticPlanning(HttpServletResponse response, AutomaticPlanningQueryCriteria criteria) throws Exception {
        automaticPlanningService.download(automaticPlanningService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询automaticPlanning")
    @ApiOperation("查询automaticPlanning")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> queryAutomaticPlanning(AutomaticPlanningQueryCriteria criteria, Pageable pageable){
        return new ResponseEntity<>(automaticPlanningService.queryAll(criteria,pageable),HttpStatus.OK);
    }

    @PostMapping
    @Log("新增automaticPlanning")
    @ApiOperation("新增automaticPlanning")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> createAutomaticPlanning(@Validated @RequestBody AutomaticPlanning resources){
        resources.setDept(UserUtils.getDept());
        String gw=resources.getShArea().getWorkingStation();
        HashMap<String,String> map= productionPlanService.getEndIdNO(gw,resources.getSxQuantity());
        List<ProductionPlan> whyList =null;
        if(!resources.getIsEnd()) {
            whyList=productionPlanRepository.getIdNoAllData(gw, map.get("endNum"));
            resources.setEndNum(map.get("endNum"));
        }else {
            whyList = productionPlanRepository.getList(gw,map.get("startNum"),resources.getEndNum());
        }
        resources.setStartNum(map.get("startNum"));
        resources.setJhQuantity(whyList.size());
        resources.setStatus("未审核");
        return new ResponseEntity<>(automaticPlanningService.create(resources),HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改automaticPlanning")
    @ApiOperation("修改automaticPlanning")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> updateAutomaticPlanning(@Validated @RequestBody AutomaticPlanning resources){
        //计算逻辑
        String gw=resources.getShArea().getWorkingStation();
        HashMap<String,String> map= productionPlanService.getEndIdNO(gw,resources.getSxQuantity());
        List<ProductionPlan> whyList =null;
        if(!resources.getIsEnd()) {
            whyList=productionPlanRepository.getIdNoAllData(gw, map.get("endNum"));
            resources.setEndNum(map.get("endNum"));
        }else {
            whyList = productionPlanRepository.getList(gw,map.get("startNum"),resources.getEndNum());
        }
        resources.setStartNum(map.get("startNum"));
        resources.setJhQuantity(whyList.size());
        resources.setStatus("未审核");
        automaticPlanningService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除automaticPlanning")
    @ApiOperation("删除automaticPlanning")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> deleteAutomaticPlanning(@RequestBody Long[] ids) {
        automaticPlanningService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/batchOrder")
    @Log("铺线计划-自动叫料")
    @ApiOperation("铺线计划-自动叫料")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> batchOrder(@RequestBody Long[] ids) {
        for (Long id:ids){
            AutomaticPlanning automaticPlanning=automaticPlanningRepository.getById(id);
            if(automaticPlanning.getStatus().equals("已审核")){
               throw new BadRequestException(automaticPlanning.getShArea().getCode()+ "状态不正确");
            }
            //得到该工位下的实际数量
            String gw=automaticPlanning.getShArea().getWorkingStation();
            HashMap<String,String> map= productionPlanService.getEndIdNO(gw,automaticPlanning.getSxQuantity());
            String endNum=map.get("endNum");
            String startNum=map.get("startNum");
            List<ProductionPlan> whyList =null;
            if(!automaticPlanning.getIsEnd()){
                whyList= productionPlanRepository.getIdNoAllData(gw,endNum);
                automaticPlanning.setEndNum(endNum);
            }else {
                whyList = productionPlanRepository.getList(gw,map.get("startNum"),automaticPlanning.getEndNum());
            }
            String zdStartNum=automaticPlanning.getZdStartNum();
            if(zdStartNum!=null&&!zdStartNum.equals("")){
                whyList = productionPlanRepository.getList(gw,zdStartNum,automaticPlanning.getEndNum());
            }
            automaticPlanning.setStatus("已审核");
            automaticPlanning.setStartNum(startNum);
            automaticPlanning.setJhQuantity(whyList.size());
            ProductionPlan plan=whyList.get(0);
            //自动生成对应的明细数据
            AutomaticPlanDetail detail=automaticPlanDetailService.storeAutomaticPlanDetail(automaticPlanning);
            detail.setCode(automaticPlanning.getCode());
            Long shAreaId=detail.getShArea().getId();
            //自动生成线边库存
            inventoryBakService.insertBatch(detail.getId(),shAreaId);
            //将BOM的批次数改为0
            bomAccountService.updateBatch(shAreaId);
            //铺线数量不做平均,不参与计算
            int num=detail.getJhQuantity();
            int s=num/detail.getBatchNum();//商
            int ys=num%detail.getBatchNum();//余数
            Boolean isLast=Boolean.FALSE;//是不是最后一批次
            String des="";
            //计算时段，9小时按批次-1计算,第一批默认8：30到,11:30-12:30休息
            int agv_sd=0;
            if(detail.getBatchNum()>1){
                agv_sd=detail.getShHour()*60/(detail.getBatchNum()-1);
            }
            for(int i=1;i<=detail.getBatchNum();i++){
                String batch="第"+i+"批";
//                num=detail.getFxQuantity()+ys+s*i;
                num=ys+s*i;
                if(i>1&&s==0){
                    continue;
                }
                if(i==detail.getBatchNum()){
                    isLast=Boolean.TRUE;
                }
                Timestamp batchTime= DateUtil.getBatchTime(agv_sd*(i-1),automaticPlanning.getJhDate());
                //可以生成的
                String code=productionPlanService.manualGenerationSavePlanPick(whyList,num,batch,detail,isLast,batchTime);
                planPickDetailService.createAutoPlan(i,code,shAreaId,detail,isLast,batchTime);
                des+=code+";";
            }
            detail.setDescription(des);
            automaticPlanDetailService.update(detail);
        }
        return new ResponseEntity<>("操作成功",HttpStatus.OK);
    }

    @PostMapping("/batchOrderZone")
    @Log("铺线计划-自动叫料库区")
    @ApiOperation("铺线计划-自动叫料库区")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> batchOrderZone(@RequestBody HashMap res) {
//        Long[] ids=map.get("ids").toString().toCharArray();
        String plan_code =  codeUtils.getCode_yyMMdd("JH",3);
        List<String> codes=new ArrayList<>();
        List<Long> detailIds=new ArrayList<>();
        List<Object> ids= (List) res.get("ids");
        String type=res.get("type").toString();
        for (Object id:ids){
            AutomaticPlanning automaticPlanning=automaticPlanningRepository.getById(Long.parseLong(id.toString()));
            if(automaticPlanning.getStatus().equals("已审核")){
                throw new BadRequestException(automaticPlanning.getShArea().getCode()+ "状态不正确");
            }
            //得到该工位下的实际数量
            String gw=automaticPlanning.getShArea().getWorkingStation();
            HashMap<String,String> map= productionPlanService.getEndIdNO(gw,automaticPlanning.getSxQuantity());
            String endNum=map.get("endNum");
            String startNum=map.get("startNum");
            List<ProductionPlan> whyList =null;
            if(!automaticPlanning.getIsEnd()){
                whyList= productionPlanRepository.getIdNoAllData(gw,endNum);
                automaticPlanning.setEndNum(endNum);
            }else {
                whyList = productionPlanRepository.getList(gw,map.get("startNum"),automaticPlanning.getEndNum());
            }
            String zdStartNum=automaticPlanning.getZdStartNum();
            if(zdStartNum!=null&&!zdStartNum.equals("")){
                whyList = productionPlanRepository.getList(gw,zdStartNum,automaticPlanning.getEndNum());
            }
            automaticPlanning.setStatus("已审核");
            automaticPlanning.setStartNum(startNum);
            automaticPlanning.setJhQuantity(whyList.size());
            ProductionPlan plan=whyList.get(0);
            //自动生成对应的明细数据
            AutomaticPlanDetail detail=automaticPlanDetailService.storeAutomaticPlanDetail(automaticPlanning);
            detail.setCode(automaticPlanning.getCode());
            Long shAreaId=detail.getShArea().getId();
            //自动生成线边库存
            inventoryBakService.insertBatch(detail.getId(),shAreaId);
            //自动生成备货库存
            if(type.equals(BizStatus.PX_BH)){
                inventoryBakService.insertBhBatch(detail.getId(), shAreaId);
            }

            //将BOM的批次数改为0
            bomAccountService.updateBatch(shAreaId);
            //铺线数量不做平均,不参与计算
            int num=detail.getJhQuantity();
            int pxQty=detail.getFxQuantity();
            if(type.equals(BizStatus.PX)||type.equals(BizStatus.PX_BH)){
                num = num - pxQty;//该数量计入批次平均
            }
            if(num<0){
                num=0;
            }
            int s=num/detail.getBatchNum();
            int ys=num%detail.getBatchNum();
            Boolean isLast=Boolean.FALSE;
            String des="";
            //计算时段，9小时按批次-1计算,第一批默认8：30到,11:30-12:30休息
            int agv_sd=0;
            if(detail.getBatchNum()>1){
                agv_sd=detail.getShHour()*60/(detail.getBatchNum()-1);
            }
            for(int i=1;i<=detail.getBatchNum();i++){
                String batch="第"+i+"批";
//                num=detail.getFxQuantity()+ys+s*i;
                num=ys+s*i;
                if(type.equals(BizStatus.PX)||type.equals(BizStatus.PX_BH)){
                    num=num+ pxQty;
                    if(pxQty>detail.getJhQuantity()){
                        num=detail.getJhQuantity();
                    }
                }
                if(i>1&&s<=0){
                    continue;
                }
                if(i==detail.getBatchNum()){
                    isLast=Boolean.TRUE;
                }
                log.info(num+"===="+batch);
                Timestamp batchTime= DateUtil.getBatchTime(agv_sd*(i-1),automaticPlanning.getJhDate());
                //可以生成的
                String code=productionPlanService.manualGenerationSavePlanPick(whyList,num,batch,detail,isLast,batchTime);
                codes.add(code);
                //planPickDetailService.createAutoPlan(i,code,shAreaId,detail,isLast,batchTime);
                des+=code+";";
            }
            detailIds.add(detail.getId());
            detail.setDescription(des);
            automaticPlanDetailService.update(detail);
        }
        planPickDetailService.createAutoPlan(codes.toArray(new String[codes.size()]),detailIds.toArray(new Long[detailIds.size()]),type);
        return new ResponseEntity<>("操作成功",HttpStatus.OK);
    }

    @PostMapping("/batchHy")
    @Log("铺线计划-自动耗用")
    @ApiOperation("铺线计划-自动耗用")
    @PreAuthorize("@el.check('automaticPlanning:batchOrder')")
    @Transactional
    public ResponseEntity<Object> batchHy(@RequestBody Long[] ids) {
        for (Long id:ids){
            AutomaticPlanning automaticPlanning=automaticPlanningRepository.getById(id);
            if(automaticPlanning.getStatus().equals("已审核")){
                throw new BadRequestException(automaticPlanning.getShArea().getCode()+ "状态不正确");
            }
            //得到该工位下的实际数量
            String gw=automaticPlanning.getShArea().getWorkingStation();
            HashMap<String,String> map= productionPlanService.getEndIdNO(gw,automaticPlanning.getSxQuantity());
            String endNum=map.get("endNum");
            String startNum=map.get("startNum");
            List<ProductionPlan> whyList =null;
            if(!automaticPlanning.getIsEnd()){
                whyList= productionPlanRepository.getIdNoAllData(gw,endNum);
                automaticPlanning.setEndNum(endNum);
            }else {
                whyList = productionPlanRepository.getList(gw,map.get("startNum"),automaticPlanning.getEndNum());
            }
            automaticPlanning.setStatus("已审核");
            automaticPlanning.setJhQuantity(whyList.size());
            automaticPlanning.setStartNum(startNum);
            automaticPlanningService.update(automaticPlanning);
            AutomaticPlanDetail detail=automaticPlanDetailService.storeAutomaticPlanDetail(automaticPlanning);
            productionPlanService.scsxHaoyong(whyList,detail.getShArea().getId(), "上线计划自动耗用:"+detail.getId());
        }
        return new ResponseEntity<>("操作成功",HttpStatus.OK);
    }
}