/*
*  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.businessdata.service.impl;

import com.youchain.basicdata.domain.Area;
import com.youchain.basicdata.domain.AutomaticPlanDetail;
import com.youchain.basicdata.domain.BomAccount;
import com.youchain.basicdata.repository.AreaRepository;
import com.youchain.basicdata.repository.BillTypeRepository;
import com.youchain.basicdata.service.BillTypeService;
import com.youchain.basicdata.service.BomAccountService;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.repository.PickDetailRepository;
import com.youchain.businessdata.repository.PickInstructionRepository;
import com.youchain.businessdata.repository.PickTicketRepository;
import com.youchain.businessdata.service.PickDetailService;
import com.youchain.businessdata.service.PickInstructionService;
import com.youchain.businessdata.service.PickTicketService;
import com.youchain.businessdata.service.dto.PickInstructionDto;
import com.youchain.businessdata.service.dto.PickInstructionQueryCriteria;
import com.youchain.exception.BadRequestException;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.businessdata.repository.PickKitPlanRepository;
import com.youchain.businessdata.service.PickKitPlanService;
import com.youchain.businessdata.service.dto.PickKitPlanDto;
import com.youchain.businessdata.service.dto.PickKitPlanQueryCriteria;
import com.youchain.businessdata.service.mapstruct.PickKitPlanMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestBody;

import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author DengJiangKun
* @date 2024-02-28
**/
@Service
@RequiredArgsConstructor
public class PickKitPlanServiceImpl implements PickKitPlanService {

    private final PickKitPlanRepository pickKitPlanRepository;
    private final PickKitPlanMapper pickKitPlanMapper;
    private final BomAccountService bomAccountService;
    private final PickInstructionService pickInstructionService;
    private final CodeUtils codeUtil;
    private final BillTypeRepository billTypeRepository;
    private final PickTicketService pickTicketService;
    private final PickDetailService pickDetailService;
    private final AreaRepository areaRepository;
    private final PickTicketRepository pickTicketRepository;
    private final PickDetailRepository pickDetailRepository;

    @Override
    public Map<String,Object> queryAll(PickKitPlanQueryCriteria criteria, Pageable pageable){
        Page<PickKitPlan> page = pickKitPlanRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(pickKitPlanMapper::toDto));
    }

    @Override
    public List<PickKitPlanDto> queryAll(PickKitPlanQueryCriteria criteria){
        return pickKitPlanMapper.toDto(pickKitPlanRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public PickKitPlanDto findById(Long id) {
        PickKitPlan pickKitPlan = pickKitPlanRepository.findById(id).orElseGet(PickKitPlan::new);
        ValidationUtil.isNull(pickKitPlan.getId(),"PickKitPlan","id",id);
        return pickKitPlanMapper.toDto(pickKitPlan);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickKitPlanDto create(PickKitPlan resources) {
        return pickKitPlanMapper.toDto(pickKitPlanRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PickKitPlan resources) {
        PickKitPlan pickKitPlan = pickKitPlanRepository.findById(resources.getId()).orElseGet(PickKitPlan::new);
        ValidationUtil.isNull( pickKitPlan.getId(),"PickKitPlan","id",resources.getId());
        pickKitPlan.copy(resources);
        pickKitPlanRepository.save(pickKitPlan);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            pickKitPlanRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<PickKitPlanDto> all, HttpServletResponse response) throws Exception {
        List<Map<String, Object>> list = ExcelDownUtils.CreateMap(all,"PickKitPlan");
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional
    public void audit(Long[] ids) {//成套计划审核
        List<String> list = pickKitPlanRepository.queryYcds(ids);
        String[] codes = list.toArray(new String[list.size()]);
        for(String code:codes) {
            List<Long> areaIds=pickKitPlanRepository.queryCodeArea(code);
            for (Long areaId : areaIds) {
                List<PickKitPlan> plans = pickKitPlanRepository.getPickKitPlansCodeArea(code, areaId);
                for (PickKitPlan pickKitPlan : plans) {
                    if (pickKitPlan.getStatus().equals(BizStatus.YCD)) {
                        throw new BadRequestException("选择记录已出单！");
                    }
                    List<BomAccount> bomAccounts = bomAccountService.queryBomAccount(pickKitPlan.getBigItem().getId(), areaId, null);
                    if (bomAccounts.isEmpty()) {
                        throw new BadRequestException("该成套计划未配置BOM，不能审核！");
                    }
                    pickKitPlan.setAllocatedQty(pickKitPlan.getOrderQty());
                    pickKitPlan.setStatus(BizStatus.YCD);
                    this.update(pickKitPlan);
                }
            }
        }
        //直接生成备货操作
            //按照所属工厂+批次查找对应数据
            List<String> gcs = pickKitPlanRepository.groupGc(codes);
            for (String gc : gcs) {
                //查找出库库区是否有多个
                List<Long> cAreaIds = pickKitPlanRepository.groupCArea(codes,gc);
                for (Long cAreaId : cAreaIds) {
                    Area oArea=areaRepository.getById(cAreaId);
                    PickTicket pickTicket = pickTicketService.storePick(billTypeRepository.findByName(BaseStatus.BT_SGDD), null,oArea, "大", Arrays.toString(codes));
                    pickTicket.setGcCode(gc);
                    pickTicket.setOrderDate(new Timestamp(new Date().getTime()));
                    double orderQty = 0;
                    List<Object[]> objs = pickKitPlanRepository.sumBomSingle(codes,gc,cAreaId);
                    //需求数量
                    double xqty = 0d;
                    //纯需求数量
                    double cxqty = 0d;
                    for (Object[] obj : objs) {
                        Long rAreaId = (Long) obj[1];
                        Long bId = (Long) obj[1];
                        double xqQty = (Double) obj[2];
                        BomAccount ba = bomAccountService.findByEntity(bId);
                        PickDetail ptd = new PickDetail();
                        //需求数xq_qty=数量*单用
                        ptd.setXqQty(xqQty);
                        ptd.setBomId(ba.getId());
                        ptd.setPropC4(xqQty-ptd.getPureReqQty()-ptd.getXbQty());
                        if(ptd.getPropC4().intValue()<=0){
                            ptd.setPropC4(0d);
                        }else{
                            //备货需求=（纯需求数/收容数向上取整）*收容数
                            ptd.setOrderQty(Math.ceil(ptd.getPropC4()));
                        }
                        ba.setPcQty(ptd.getOrderQty()+ba.getPcQty());
                        bomAccountService.update(ba);
                        xqty += ptd.getXqQty();
                        cxqty += ptd.getPropC4();
                        ptd.setPoint(ba.getZPoint());
                        ptd.setItem(ba.getItem());
                        ptd.setPickTicket(pickTicket);
                        ptd.setContents(ba.getContents());
                        ptd.setAc(ba.getAc());
                        ptd.setSupplier(ba.getSupplier());
                        ptd.setArea(pickTicket.getArea());
                        ptd.setShArea(ba.getRArea());
                        pickDetailService.create(ptd);
                        orderQty += ptd.getOrderQty();
                        //查询组合物料，数量是否一致，不一致改成一致
                        String largeClass="";
                        if(largeClass!=null&&!largeClass.equals("")){
                            int maxQty=pickDetailService.getMaxBomQty(pickTicket.getId(),largeClass).intValue();
                            if(maxQty>0) {
                                List<PickDetail> ptds = pickDetailService.getBomList(pickTicket.getId(), largeClass);
                                for (PickDetail d : ptds) {
                                    if (d.getOrderQty().intValue() != maxQty) {
                                        orderQty -= d.getOrderQty();
                                        d.setRemark("原" + d.getOrderQty() + "调整到" + maxQty);
                                        d.setOrderQty(maxQty + 0d);
                                        pickDetailService.update(d);
                                        orderQty += d.getOrderQty();
                                    }
                                }
                            }
                        }
                    }
                    pickTicket.setOrderQuantity(orderQty);
                    pickTicket.setBhQty(orderQty);
                    //纯需求数
                    pickTicket.setPureReqQty(cxqty);
                    //需求数量
                    pickTicket.setXqQty(xqty);
                    pickTicket.setPc("成套指示");
                    pickTicketService.update(pickTicket);
                }

        }

//        for(String code:codes) {
//            List<Long> areaIds=pickKitPlanRepository.queryCodeArea(code);
//            for (Long areaId : areaIds) {
//                List<PickKitPlan> plans = pickKitPlanRepository.getPickKitPlansCodeArea(code, areaId);
//                String zscode = codeUtil.getCode_yyMMdd("ZS", 3);
//                for (PickKitPlan pickKitPlan : plans) {
//                    if (pickKitPlan.getStatus().equals(BizStatus.YCD)) {
//                        throw new BadRequestException("选择记录已出单！");
//                    }
//                    List<BomAccount> bomAccounts = bomAccountService.queryBomAccount(pickKitPlan.getBigItem().getId(), areaId, null);
//                    if (bomAccounts.isEmpty()) {
//                        throw new BadRequestException("该成套计划未配置BOM，不能审核！");
//                    }
//                    for (BomAccount bomAccount : bomAccounts) {
//                        //生成手指示数据
//                        PickInstruction pickInstruction = new PickInstruction();
//                        //单号
//                        pickInstruction.setAllocationNumber(zscode);
//                        pickInstruction.setAllocationDate(new Timestamp(new Date().getTime()));
//                        //成套单号
//                        pickInstruction.setKitNumber(pickKitPlan.getPlanNumber());
//                        pickInstruction.setIndicatedQty((Double.valueOf(bomAccount.getSingles()) * pickKitPlan.getOrderQty()));
//                        pickInstruction.setItem(bomAccount.getItem());
//                        pickInstruction.setOutKType(billTypeRepository.findByName(BaseStatus.BT_SGDD));
//                        pickInstruction.setRkArea(bomAccount.getRArea());
//                        pickInstruction.setCkArea(bomAccount.getCArea());
//                        pickInstruction.setZzkwPoint(bomAccount.getZPoint());
//                        pickInstruction.setAc(bomAccount.getAc());
//                        pickInstruction.setProcessContent(bomAccount.getContents());
//                        pickInstruction.setTaxCategory(bomAccount.getBonded());
//                        pickInstructionService.create(pickInstruction);
//                    }
//                    pickKitPlan.setAllocatedQty(pickKitPlan.getOrderQty());
//                    pickKitPlan.setStatus(BizStatus.YCD);
//                    this.update(pickKitPlan);
//                }
//            }
//        }
    }

    @Override
    public void qxAudit(Long id) {//取消成套审核
        PickKitPlan pickKitPlan = pickKitPlanRepository.getById(id);
        //其他出库的删除
        List<PickTicket> pickTickets = pickTicketRepository.queryPickTicketByCodeAll(BizStatus.OPEN, "%"+pickKitPlan.getPlanNumber()+"%");
        for (PickTicket pt : pickTickets) {
            //查明细表的数据
            List<PickDetail> pickDetails = pickDetailRepository.queryByPickTicketId(pt.getId());
            for (PickDetail pd : pickDetails) {
                pickDetailRepository.delete(pd);
            }
            pickTicketRepository.deleteById(pt.getId());
        }
        List<PickKitPlan> ds = pickKitPlanRepository.queryPickKitPlanCode(pickKitPlan.getPlanNumber());
        for (PickKitPlan d : ds) {
            d.setStatus(BizStatus.WCD);
            this.update(d);
        }

//        PickInstructionQueryCriteria pickInstructionQueryCriteria = new PickInstructionQueryCriteria();
//        pickInstructionQueryCriteria.setKitNumber(pickKitPlan.getPlanNumber());
//        List<PickInstructionDto> pickInstructionDtos = pickInstructionService.queryAll(pickInstructionQueryCriteria);
//        for (PickInstructionDto pickInstructionDto : pickInstructionDtos) {
//            if(!pickInstructionDto.getStatus().equals(BizStatus.WCD)){
//                throw  new BadRequestException("指示已出单，不能撤回");
//            }
//            pickInstructionService.deleteAll(new Long[]{pickInstructionDto.getId()});
//        }
//        pickKitPlan.setStatus(BizStatus.WCD);
//        pickKitPlan.setAllocatedQty(0d);
//        this.update(pickKitPlan);
//        List<PickKitPlan> plans=pickKitPlanRepository.queryPickKitPlanCode(pickKitPlan.getPlanNumber());
//        for (PickKitPlan p:plans){
//            p.setStatus(BizStatus.WCD);
//            p.setAllocatedQty(0d);
//            this.update(p);
//        }

    }
}
