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

import com.youchain.basicdata.domain.*;
import com.youchain.basicdata.repository.*;
import com.youchain.basicdata.service.*;
import com.youchain.basicdata.service.mapstruct.AreaMapper;
import com.youchain.basicdata.service.mapstruct.PointMapper;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.inputJson.imports.BaseImport;
import com.youchain.businessdata.repository.*;
import com.youchain.businessdata.service.*;
import com.youchain.config.FileProperties;
import com.youchain.exception.BadRequestException;
import com.youchain.modules.system.domain.DictDetail;
import com.youchain.modules.system.repository.DictDetailRepository;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HJL
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-08-14
 **/
@Service
@RequiredArgsConstructor
@Slf4j
public class ImportDataServiceImpl implements ImportDataService {
    private final BigItemRepository bigItemRepository;
    private final AreaRepository areaRepository;
    private final ItemRepository itemRepository;
    private final DictDetailRepository dictDetailRepository;
    private final PointRepository pointRepository;
    private final BomAccountRepository bomAccountRepository;

    private final PointService pointService;
    private final ItemService itemService;
    private final AsnDetailService asnDetailService;
    private final AsnService asnService;
    private final PickDetailService pickDetailService;
    private final PickTicketService pickTicketService;
    private final InventoryService inventoryService;
    private final BigItemService bigItemService;
    private final BomAccountService bomAccountService;
    private final BomAccountLogService bomAccountLogService;
    private final CodeUtils codeUtils;
    private final BillTypeRepository billTypeRepository;
    private final PickInstructionService pickInstructionService;
    private final CountMoveRepository countMoveRepository;
    private final ItemKeyRepository itemKeyRepository;
    private final InventoryRepository inventoryRepository;
    private final CountMoveService countMoveService;

    @Override
    public void importBomAccount(int row, Map<String, Object> readAll) {
        String bigItemCode = readAll.get("完成品品番") == null ? null : readAll.get("完成品品番").toString();
        String station_type = readAll.get("工位") == null ? null : readAll.get("工位").toString();
        String itemCode = readAll.get("部品品番") == null ? null : readAll.get("部品品番").toString();
        String ac = readAll.get("AC") == null ? null : readAll.get("AC").toString();
        String contents = readAll.get("加工内容") == null ? null : readAll.get("加工内容").toString();
        String single = readAll.get("单用") == null ? null : readAll.get("单用").toString();
        String r_area_name = readAll.get("入库库区") == null ? null : readAll.get("入库库区").toString();
        String c_area_name = readAll.get("出库库区") == null ? null : readAll.get("出库库区").toString();
        String z_point_code = readAll.get("制造库位") == null ? null : readAll.get("制造库位").toString();
//        String c_point_code =readAll.get("暂存库位")==null?null:readAll.get("暂存库位").toString();
        String out_type = readAll.get("出库类型") == null ? null : readAll.get("出库类型").toString();
        String supplier = readAll.get("供应商") == null ? null : readAll.get("供应商").toString();
        String bp_type = readAll.get("部品种类") == null ? null : readAll.get("部品种类").toString();

        BigItem bigItem = null;
        if (bigItemCode!=null&&!bigItemCode.equals("")) {
            bigItem = bigItemRepository.findByCode(bigItemCode);
            if (bigItem == null) {
                throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + bigItemCode + "完成品品番无效");
            }
        } else {
            throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + "请输入完成品品番");
        }
        Item item = null;
        if (itemCode.length() > 0) {
            item = itemRepository.findByCode(itemCode);
            if (item == null) {
                throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + itemCode + "部品品番无效");
            }
        } else {
            throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + "请输入部品品番");
        }
        Area r_area = null;
        if (r_area_name.length() > 0) {
            r_area = areaRepository.getByName(r_area_name);
            if (r_area == null) {
                throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + r_area_name + "入库库区无效");
            }
        } else {
            throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + "请输入入库库区");
        }
        Area c_area = null;
        if (c_area_name.length() > 0) {
            c_area = areaRepository.getByName(c_area_name);
            if (c_area == null) {
                throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + c_area_name + "出库库区无效");
            }
        } else {
            throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + "请输入出库库区");
        }
//        Point c_point = null;
//        if (c_point_code!=null&&!c_point_code.equals("")) {
//            c_point = pointRepository.findByCode(c_point_code);
//            if (c_point == null) {
//                c_point = pointService.createPoint(c_point_code, "ZCKW", r_area,c_point);
//            }
//        }
        Point z_point = null;
        if (z_point_code != null && !z_point_code.equals("")) {
            z_point = pointRepository.findByCode(z_point_code);
            if (z_point == null) {
//               z_point = pointService.createPoint(z_point_code, "ZZKW", r_area,c_point);
                z_point = pointService.createPoint(z_point_code, "ZZKW", r_area);
            }

        } else {
            throw new BadRequestException(HttpStatus.NOT_FOUND, row + "行" + "请输入制造库位");
        }
        Boolean isNew = Boolean.FALSE;
        BomAccount bomAccount = bomAccountRepository.findByOnly(bigItem.getId(), item.getId(), r_area.getId(), z_point.getId());
        if (bomAccount == null) {
            bomAccount = new BomAccount();
            bomAccount.setBigItem(bigItem);
            bomAccount.setItem(item);
            bomAccount.setRArea(r_area);
            bomAccount.setDept(r_area.getDept());
            bomAccount.setZPoint(z_point);
            bomAccount.setBp_type(bp_type);
            isNew = Boolean.TRUE;
        }
        bomAccount.setStationType(station_type);
        bomAccount.setCArea(c_area);
        bomAccount.setAc(ac);
        bomAccount.setContents(contents);
        bomAccount.setEnabled(true);
        bomAccount.setSingles(Integer.parseInt(single));
        bomAccount.setOutType(out_type);
        bomAccount.setSupplier(supplier);
        if (isNew) {
            bomAccountService.create(bomAccount);
            bomAccountLogService.copyBomAccount(bomAccount.getId(), "import_add");
        } else {
            bomAccountService.update(bomAccount);
            bomAccountLogService.copyBomAccount(bomAccount.getId(), "import_update");
        }
    }

    @Override
    public String importBigItem(Map<String, Object> readAll) {
        String re = "";
        String code = readAll.get("完成品品番") == null ? null : readAll.get("完成品品番").toString().trim();
        String name = readAll.get("完成品型式名") == null ? null : readAll.get("完成品型式名").toString().trim();
        String masterName = readAll.get("主型式名") == null ? null : readAll.get("主型式名").toString().trim();
        String models = readAll.get("机种") == null ? null : readAll.get("机种").toString().trim();
        String country = readAll.get("国别") == null ? null : readAll.get("国别").toString().trim();
        String description = readAll.get("备注") == null ? null : readAll.get("备注").toString().trim();
        String outboundType = readAll.get("出库类型") == null ? null : readAll.get("出库类型").toString().trim();
        if (code.length() > 0) {
            BigItem bigItem = bigItemRepository.findByCode(code);
            if (bigItem == null) {
                re = "a";
                bigItem = new BigItem();
                bigItem.setCode(code);
                bigItem.setDeptId(UserUtils.getDept().getId());
            } else {
                re = "b";
            }
            bigItem.setModels(models);
            bigItem.setMasterName(masterName);
            bigItem.setDescription(description);
            bigItem.setName(name);
            bigItem.setCountry(country);
            bigItem.setOutboundType(outboundType);
            bigItem.setEnabled(true);
            if (re.equals("a")) {
                bigItemService.create(bigItem);
            } else if (re.equals("b")) {
                bigItemService.update(bigItem);
            }
        }
        return re;
    }

    @Override
    public String importAsnDetail(Map<String, Object> readAll, Asn asn) {
        String re = "";
        String code = readAll.get("品番") == null ? null : readAll.get("品番").toString();
        String qty = readAll.get("数量") == null ? null : readAll.get("数量").toString();
        String zzkw = readAll.get("制造库位") == null ? null : readAll.get("制造库位").toString();
        if (code.length() > 0) {
            Item item = itemRepository.findByCode(code);
            if (item == null) {
                return "部品品番无效";
            }
            Point point = pointService.getPoint(zzkw, null, null, null);
            if (point == null) {
                return "制造库位无效";
            }
            List<BomAccount> boms = bomAccountRepository.queryBomUnique(asn.getArea().getId(), item.getId(), point.getId());
            if (boms.size() <= 0) {
                return "BOM工位清单不存在";
            }
            AsnDetail asnDetail = new AsnDetail();
            asnDetail.setAsn(asn);
            asnDetail.setDept(UserUtils.getDept());
            asnDetail.setStatus(BizStatus.OPEN);
            asnDetail.setItem(item);
            asnDetail.setPoint(point);
            asnDetail.setOrderQty(Double.parseDouble(qty));
            asnDetailService.create(asnDetail);
            asn.setOrderQuantity(asn.getOrderQuantity() + asnDetail.getOrderQty());
            asnService.update(asn);
        }
        return re;
    }

    @Override
    public String importPickDetail(Map<String, Object> readAll, PickTicket pickTicket) {
        String re = "";
        String code = "" + readAll.get("品番");
        String qty = "" + readAll.get("数量");
        String zzkw = "" + readAll.get("制造库位");
        String remark = "" + readAll.get("备注");
        if (code.length() > 0) {
            Item item = itemRepository.findByCode(code);
            if (item == null) {
                return "部品品番无效";
            }
            Point point = pointService.getPoint(zzkw, null, null, null);
            Long zzkwId = null;
            if (point == null) {
                if (pickTicket.getArea().getBexb()) {
                    return "制造库位无效";
                }
            } else {
                zzkwId = point.getId();
            }
//            List<BomAccount> boms= bomAccountRepository.queryBomUnique(pickTicket.getArea().getId(),item.getId(), point.getId());
//            if(boms.size()<=0){
//                return "BOM工位清单不存在";
//            }
            Double xbQty = inventoryService.getInvQty(item.getId(), pickTicket.getArea().getId(), zzkwId);
            if (xbQty.intValue() < Double.parseDouble(qty)) {
                return "库存不足";
            }
            PickDetail pickDetail = new PickDetail();
            pickDetail.setPickTicket(pickTicket);
            pickDetail.setDept(UserUtils.getDept());
            pickDetail.setStatus(BizStatus.OPEN);
            pickDetail.setItem(item);
            pickDetail.setPoint(point);
            pickDetail.setRemark(remark);
            pickDetail.setArea(pickTicket.getArea());
            pickDetail.setOrderQty(Double.parseDouble(qty));
            pickDetailService.create(pickDetail);
            pickTicket.setOrderQuantity(pickTicket.getOrderQuantity() + pickDetail.getOrderQty());
            pickTicketService.update(pickTicket);

        }
        return re;
    }

    @Override
    public void importPickInstruction(List<Map<String, Object>> readAll) {
        String zsCode = codeUtils.getCode_yyMMdd("ZS", 3);
        BillType billType = billTypeRepository.findByName(BaseStatus.BT_SGDD);
        for (int i = 0; i < readAll.size(); i++) {
            Map<String, Object> map = readAll.get(i);
            String code = map.get("品番") == null ? null : map.get("品番").toString().trim();
            String qty = map.get("数量") == null ? null : map.get("数量").toString().trim();
            String areaName = map.get("纳所") == null ? null : map.get("纳所").toString().trim();
            if (code.length() > 0) {
                PickInstruction pickInstruction = new PickInstruction();
                Item item = itemRepository.findByCode(code);
                if (item == null) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + code + "部品品番无效");
                }
                Area r_area = null;
                if (areaName.length() > 0) {
                    r_area = areaRepository.getByName(areaName);
                    if (r_area == null) {
                        throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + areaName + "纳所无效");
                    }
                } else {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + "请输入纳所");
                }
                List<BomAccount> boms = bomAccountRepository.getBomList(r_area.getId(), item.getId());
                if (boms.size() <= 0) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + code + "找不到BOM清单");
                }
                BomAccount bomAccount = boms.get(0);
                pickInstruction.setAllocationNumber(zsCode);
                pickInstruction.setOutKType(billType);
                pickInstruction.setItem(item);
                pickInstruction.setAc(bomAccount.getAc());
                pickInstruction.setStatus(BizStatus.OPEN);
                pickInstruction.setBomId(bomAccount.getId());
                pickInstruction.setIndicatedQty(Double.parseDouble(qty));
                pickInstruction.setCkArea(bomAccount.getCArea());
                pickInstruction.setRkArea(bomAccount.getRArea());
                pickInstruction.setZzkwPoint(bomAccount.getZPoint());
                pickInstruction.setAllocationDate(new Timestamp(new Date().getTime()));
                pickInstructionService.create(pickInstruction);
            } else {
                break;
            }
        }
    }

    @Override
    public void importCountMoveDetail(Long countId, List<Map<String, Object>> readAll) {
        for (int i = 0; i < readAll.size(); i++) {
            Map<String, Object> map = readAll.get(i);
            String code = map.get("品番") == null ? null : map.get("品番").toString().trim();
            String src_point_code = map.get("原库位") == null ? null : map.get("原库位").toString().trim();
            String dst_point_code = map.get("目标库位") == null ? null : map.get("目标库位").toString().trim();
            String pc1 = map.get("批次号") == null ? null : map.get("批次号").toString().trim();
            if (code.length() > 0) {
                CountMove countMove = countMoveRepository.getById(countId);
                Item item = itemRepository.findByCode(code);
                if (item == null) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + code + "部品品番无效");
                }
                Point point = pointService.getPoint(src_point_code, null, null, countMove.getSrcArea().getCode());
                if (point == null) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + src_point_code + "原库位不存在");
                }
                List<ItemKey> itemKeyList = itemKeyRepository.queryItemKey(item.getId(), pc1);
                if (itemKeyList.size() == 0) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + code + "不存在库存");
                }
                ItemKey ik = itemKeyList.get(0);
                List<Inventory> inventoryList = inventoryRepository.queryInventoryPointIk(point.getId(), ik.getId());
                if (inventoryList.size() == 0) {
                    throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + code + "不存在库存");
                }
                Point dstPoint = null;
                if (dst_point_code == null) {
                    dstPoint = countMove.getDstPoint();
                } else {
                    dstPoint = pointService.getPoint(dst_point_code, null, null, countMove.getDstArea().getCode());
                    if (point == null) {
                        throw new BadRequestException(HttpStatus.NOT_FOUND, i + 1 + "行" + dst_point_code + "目标库位不存在");
                    }
                }
                countMoveService.createCountDetail(countMove, inventoryList.get(0), ik, dstPoint);
            } else {
                break;
            }
        }
    }
}