package com.th.demo.service.impl.ware;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.auth0.jwt.internal.org.bouncycastle.jce.exception.ExtCertificateEncodingException;
import com.th.demo.mapping.maint.*;
import com.th.demo.mapping.ware.InRecordMapper;
import com.th.demo.mapping.ware.StoreMapper;
import com.th.demo.model.maint.*;
import com.th.demo.model.system.ResponseCodeMsg;
import com.th.demo.model.system.SysUser;
import com.th.demo.model.system.Type;
import com.th.demo.model.ware.InRecord;
import com.th.demo.model.ware.OutRecord;
import com.th.demo.model.ware.Store;
import com.th.demo.service.ware.InService;
import com.th.demo.service.ware.StoreService;
import com.th.demo.tools.JSONTools;
import com.th.demo.tools.Tools;
import org.apache.velocity.context.InternalContextAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service("InService")
public class InServiceImpl implements InService {

    @Autowired
    public InRecordMapper inRecordMapper;
    @Autowired
    public StoreMapper storeMapper;
    @Autowired
    public WareMapper wareMapper;
    @Autowired
    public StackMapper stackMapper;
    @Autowired
    public CustomerMapper customerMapper;
    @Autowired
    public MaterialMapper materialMapper;
    @Autowired
    public ProdPriceMapper prodPriceMapper;
    @Autowired
    public PriceMapper priceMapper;
    String result = Type.FAIL;
    int num = 0;

    @Transactional
    @Override
    public String in(String json, String userId, String belongId) {


        int currentLayer = 0;
        Store store = JSON.parseObject(json, new TypeReference<Store>() {
        });
        int effStoreCnt = storeMapper.selEffStore(store.getPlateNo());
        if(effStoreCnt > 0){
            return JSONTools.toString(1,"库存中已存在板号"+store.getPlateNo()+",请勿重复入库");
        }
        Stack stack = store.getStack();//stackMapper.selectByPrimaryKey(store.getStack().getId());



        if (stack.getIsLayer().equals("1")) {
            currentLayer = Integer.parseInt(storeMapper.selectLayerByStackId(stack.getId(), belongId));
        } else if (stack.getIsLayer().equals("2")){
            currentLayer = store.getLayer()-1;
        }  else{
            currentLayer = -1;
        }

        store.setLayer(currentLayer + 1);
        store.setAddId(userId);
        store.setAddTime(new Date());
        store.setCancelFlag("0");
        store.setOutFlag("0");
        store.setLockFlag("0");
        store.setBelongId(belongId);
        /*ProdPrice prodPrice = new ProdPrice();

        prodPrice = prodPriceMapper.selectByProdNm(store.getMaterial().getName());
        if(prodPrice == null){
            return JSONTools.toString(1,store.getMaterial().getName()+"价格未维护");
        }
        store.setInvoicePrice(prodPrice.getInvoicePrice());*/

        InRecord inRecord = getInRecord(store, "1", userId);
        num = inRecordMapper.insert(inRecord);


        store.setInId(inRecord.getId());
        num = storeMapper.insert(store);

        result = Tools.moreThanZeroResultJSON(num);
        return result;
    }


    @Override
    public String inImport(String json, String userId, String belongId) throws Exception {
        long startTime = System.currentTimeMillis();

        List<JSONObject> listJO = JSON.parseObject(json, new TypeReference<List<JSONObject>>() {
        });

        List<Store> listStore = objToStore(listJO, userId, belongId);
        List storeArray = new ArrayList();
        //检查库存中是否已经有导入的板号或者excel本身板号有重复
        for(int i = 0 ; i < listStore.size();i++){
            if(storeArray.contains(listStore.get(i).getPlateNo())){
                return JSONTools.toString(1,"导入数据板号"+listStore.get(i).getPlateNo()+"重复,请勿重复入库");
            }else{
                storeArray.add(listStore.get(i).getPlateNo());
            }
            int effStoreCnt = storeMapper.selEffStore(listStore.get(i).getPlateNo());
            if(effStoreCnt > 0){
                return JSONTools.toString(1,"库存中已存在板号"+listStore.get(i).getPlateNo()+",请勿重复入库");
            }
        }


        resortAndInsert(listStore, userId, belongId);
        result = Tools.moreThanZeroResultJSON(1);
        long endTime = System.currentTimeMillis();
        float seconds = (endTime - startTime) / 1000F;
        System.out.println(Float.toString(seconds) + " seconds.");

        return result;
    }

    @Override
    public String back(String json, String userId, String belongId) {
        List<Store> listStore = JSON.parseObject(json, new TypeReference<List<Store>>() {
        });
        Stack stack = stackMapper.selectByPrimaryKey(listStore.get(0).getStack().getId());

        if (stack.getIsLayer().equals("0")) {
            result = JSONTools.toString("");
        } else {
            Collections.sort(listStore);
            int currentLayer = Integer.parseInt(storeMapper.selectLayerByStackId(listStore.get(0).getStack().getId(), belongId));
            int min = listStore.get(0).getLayer();
            int max = listStore.get(listStore.size() - 1).getLayer();
            if (currentLayer != max) {
                result = JSONTools.toString(ResponseCodeMsg.CODE_EX, "必须包含最上层取消出库！");
            } else if (!WareTools.checkOrder(listStore)) {
                result = JSONTools.toString(ResponseCodeMsg.CODE_EX, "请选中连续数据取消出库！");
            } else {
                for (int i = 0; i < listStore.size(); i++) {
                    int effStoreCnt = storeMapper.selEffStore(listStore.get(i).getPlateNo());
                    if(effStoreCnt == 0){
                        return JSONTools.toString(1,"库存中不存在板号"+listStore.get(i).getPlateNo()+",无法取消出库");
                    }
                    InRecord inRecord = getInRecord(listStore.get(i), "0", userId);
                    num += inRecordMapper.insert(inRecord);

                    //listStore.get(i).setOutId(outRecord.getId());
                    listStore.get(i).setCancelFlag("1");
                    num += storeMapper.updateByPrimaryKey(listStore.get(i));
                }
                result = Tools.moreThanZeroResultJSON(num);
            }
        }
        return result;
    }

    private List<Store> resortAndInsert(List<Store> listStore, String userId, String belongId) throws Exception {
        for (int i = 0; i < listStore.size(); i++) {
            Store temp = listStore.get(i);
            List<Store> listSameStack = new ArrayList<>();

            for (int j = 0; j < listStore.size(); j++) {
                if (listStore.get(j).getWare().equals(temp.getWare()) && listStore.get(j).getStack().equals(temp.getStack())) {
                    listSameStack.add(listStore.get(j));
                    listStore.remove(j);
                    j--;
                }
            }

            Collections.sort(listSameStack);
            Stack stack = stackMapper.selectByPrimaryKey(listSameStack.get(0).getStack().getId());
            num = insert(listSameStack, stack, userId, belongId);
            i--;


            for (int j = 0; j < listStore.size(); j++) {
                if (i != j && listStore.get(j).getWare().equals(temp.getWare()) && listStore.get(j).getStack().equals(temp.getStack())) {
                    if (temp.getLayer() > listStore.get(j).getLayer()) {
                        temp = listStore.get(j);
                    }
                }
            }

            int currentLayer = Integer.parseInt(storeMapper.selectLayerByStackId(temp.getStack().getId(), belongId));
            if (currentLayer + 1 != temp.getLayer()) {
                int c = temp.getLayer() - currentLayer - 1;
                for (int a = 0; a < listStore.size(); a++) {
                    if (listStore.get(a).getWare().equals(temp.getWare()) && listStore.get(a).getStack().equals(temp.getStack())) {
                        listStore.get(i).setLayer(listStore.get(i).getLayer() + c);
                    }
                }
            }


        }
        return listStore;
    }

    private int insert(List<Store> listSameStack, Stack stack, String userId, String belongId) throws Exception{
        int currentLayer = 0;
        /*if (stack.getIsLayer().equals("1")) {
            currentLayer = Integer.parseInt(storeMapper.selectLayerByStackId(stack.getId(), belongId));
        } else {
            currentLayer = -1;
        }*/
        Price Price = new Price();
        for (int m = 0; m < listSameStack.size(); m++) {
            currentLayer = Integer.parseInt(storeMapper.selectLayerByStackId(stack.getId(), belongId));
            if (stack.getIsLayer().equals("1")) {
                listSameStack.get(m).setLayer(currentLayer + 1);
            } else {
                listSameStack.get(m).setLayer(0);
            }
            listSameStack.get(m).setAddId(userId);
            listSameStack.get(m).setAddTime(new Date());
            listSameStack.get(m).setCancelFlag("0");
            listSameStack.get(m).setBelongId(belongId);
            Price = priceMapper.selectByMaterialChangeTime(listSameStack.get(m).getFkComponyId().toString(),belongId);
            if(Price == null){
                Customer fk_compony = customerMapper.selectByPrimaryKey(listSameStack.get(m).getFkComponyId());
                throw new Exception(fk_compony.getName()+"公司的价格未维护");
            }
            listSameStack.get(m).setInvoicePrice(Price.getOrdPrice());
            InRecord inRecord = getInRecord(listSameStack.get(m), "1", userId);
            num += inRecordMapper.insert(inRecord);

            listSameStack.get(m).setInId(inRecord.getId());
            num += storeMapper.insert(listSameStack.get(m));

        }

        return  num;
    }


    private List<Store> objToStore(List<JSONObject> listJO, String userId, String belongId) throws Exception {
        String err = Type.SUCCESS;
        List<Store> listStore = new ArrayList<>();
        String wareName = listJO.get(0).get("仓库名称").toString();
        String stackName = listJO.get(0).get("垛位号").toString();
        String materialName = listJO.get(0).get("货物品名").toString();
        String standard = listJO.get(0).get("材质").toString();
        String customerName = listJO.get(0).get("客户名称").toString();
        String fk_compony_name = listJO.get(0).get("客户名称").toString();
        Ware ware = wareMapper.selectByWareName(wareName, userId, belongId);
        if (ware == null) {
            err += "未找到名为\"" + wareName + "\"的库房；";
            throw new Exception(err);
        }
        Stack stack = stackMapper.selectByWareNameStackName(wareName, stackName, userId, belongId);
        if (stack == null) {
            err += "未找到名为\"" + stackName + "\"的垛位号；";
            throw new Exception(err);
        }
        Material material = materialMapper.selectByNameStandard(materialName, standard, belongId);
        if (material == null) {
            err += "未找到名为\"" + materialName + "，" + standard + "\"的物料类型；";
            throw new Exception(err);
        }
        Customer customer = customerMapper.selectByName(customerName, belongId);
        if (customer == null) {
            err += "未找到名为\"" + customerName + "\"的客户名称；";
            throw new Exception(err);
        }
        Customer fk_compony = customerMapper.selectByName(fk_compony_name, belongId);
        if (fk_compony == null) {
            err += "未找到名为\"" + customerName + "\"的货权单位；";
            throw new Exception(err);
        }
        for (int i = 0; i < listJO.size(); i++) {
            Store store = new Store();
            if (listJO.get(i).get("仓库名称").toString().equals(wareName)) {
                store.setWare(ware);
            } else {
                wareName = listJO.get(i).get("仓库名称").toString();
                ware = wareMapper.selectByWareName(wareName, userId, belongId);
                if (ware == null) {
                    err += "未找到名为\"" + wareName + "\"的仓库名称；";
                    throw new Exception(err);
                }
                store.setWare(ware);
            }
            if (listJO.get(i).get("垛位号").toString().equals(stackName)) {
                store.setStack(stack);
            } else {
                stackName = listJO.get(i).get("垛位号").toString();
                stack = stackMapper.selectByWareNameStackName(wareName, stackName, userId, belongId);
                if (stack == null) {
                    err += "未找到名为\"" + stackName + "\"的垛位号；";
                    throw new Exception(err);
                }
                store.setStack(stack);
            }
            if (listJO.get(i).get("货物品名").toString().equals(materialName) && listJO.get(i).get("材质").toString().equals(standard)) {
                store.setMaterial(material);
            } else {
                materialName = listJO.get(i).get("货物品名").toString();
                standard = listJO.get(i).get("材质").toString();
                material = materialMapper.selectByNameStandard(materialName, standard, belongId);
                if (material == null) {
                    err += "未找到名为\"" + materialName + "，" + standard + "\"的货物品名；";
                    throw new Exception(err);
                }
                store.setMaterial(material);
            }
            if (listJO.get(i).get("订单客户").toString().equals(customerName)) {
                store.setCustomer(customer);
            } else {
                customerName = listJO.get(i).get("订单客户").toString();
                customer = customerMapper.selectByName(customerName, belongId);
                if (customer == null) {
                    err += "未找到名为\"" + customerName + "\"的订单客户名称；";
                    throw new Exception(err);
                }
                store.setCustomer(customer);
            }
            if (listJO.get(i).get("客户名称").toString().equals(fk_compony_name)) {
                store.setFkComponyId(fk_compony.getId());
            } else {
                fk_compony_name = listJO.get(i).get("客户名称").toString();
                fk_compony = customerMapper.selectByName(fk_compony_name, belongId);
                if (customer == null) {
                    err += "未找到名为\"" + customerName + "\"的客户名称；";
                    throw new Exception(err);
                }
                store.setFkComponyId(fk_compony.getId());
            }
            store.setLayer(Integer.parseInt(listJO.get(i).get("层号").toString()));
            store.setPlateNo(listJO.get(i).get("顺序号").toString());
            store.setModel(listJO.get(i).get("规格").toString());
            store.setCount(Double.parseDouble(listJO.get(i).get("数量").toString()));
            store.setWeight(Double.parseDouble(listJO.get(i).get("重量").toString()));
            if (listJO.get(i).get("目的地") == null || listJO.get(i).get("目的地").toString().equals("")) {
                store.setReceiveAddress(customer.getAddress());
            } else {
                store.setReceiveAddress(listJO.get(i).get("目的地").toString());
            }
            if(listJO.get(i).get("备注") != null){
                store.setRemark(listJO.get(i).get("备注").toString());
            }

            store.setAddId(userId);
            store.setAddTime(new Date());
            store.setCancelFlag("0");
            store.setOutFlag("0");
            store.setBelongId(belongId);
            if(listJO.get(i).get("产地") != null){
                store.setProductionPlace(listJO.get(i).get("产地").toString());
            }

            if(listJO.get(i).get("订单号") != null){
                store.setOrdNo(listJO.get(i).get("订单号").toString());
            }
            if(listJO.get(i).get("合约号") != null){
                store.setContractNo(listJO.get(i).get("合约号").toString());
            }
            if(listJO.get(i).get("车号") != null){
                store.setCarNo(listJO.get(i).get("车号").toString());
            }
            if(listJO.get(i).get("吊装工") != null){
                store.setTallyPeople(listJO.get(i).get("吊装工").toString());
            }
            listStore.add(store);
        }
        if (err.equals(Type.SUCCESS)) {
            return listStore;
        } else {
            throw new Exception(err);
        }
    }
//
//    private String check(List<JSONObject> listJO, String userId, String belongId) {
//        result = Type.SUCCESS;
//        for (int i = 0; i < listJO.size(); i++) {
//            Ware ware = wareMapper.selectByWareName(listJO.get(i).get("库房").toString(), userId, belongId);
//            if (ware == null) {
//                result = "未找到对应的库房信息";
//                break;
//            }
//            Stack stack = stackMapper.selectByWareNameStackName(listJO.get(i).get("库房").toString(), listJO.get(i).get("垛位").toString(), userId, belongId);
//            if (stack == null) {
//                result = "未找到对应的垛位信息";
//                break;
//            }
//        }
//        return result;
//    }


    private InRecord getInRecord(Store store, String recordType, String userId) {
        InRecord inRecord = new InRecord();
        Ware ware =  wareMapper.selectByPrimaryKey(store.getWare().getId());
        inRecord.setWareName(ware.getName());
        inRecord.setStackName(store.getStack().getName());
        inRecord.setLayer(store.getLayer());
        inRecord.setMaterialName(store.getMaterial().getName());
        inRecord.setStandard(store.getMaterial().getStandard());
        inRecord.setModel(store.getModel());
        inRecord.setCustomerName(store.getCustomer().getName());
        inRecord.setFkComponyName(store.getFkComponyId());

        if (recordType.equals("0")) {
            inRecord.setCount(-1 * store.getCount());
            inRecord.setWeight(-1 * store.getWeight());
        } else {
            inRecord.setCount(store.getCount());
            inRecord.setWeight(store.getWeight());
        }
        inRecord.setRemark(store.getRemark());
        inRecord.setBelongId(store.getBelongId());
        inRecord.setPlateNo(store.getPlateNo());
        inRecord.setAddUser(new SysUser(userId));
        inRecord.setAddTime(new Date());
        inRecord.setRecordType(recordType);
        inRecord.setCancelFlag("0");
        inRecord.setReceiveAddress(store.getReceiveAddress());

        inRecord.setWgtDcnMtcCd(store.getWgtDcnMtcCd());
        inRecord.setEdgeTy(store.getEdgeTy());
        inRecord.setProductionPlace(store.getProductionPlace());
        inRecord.setOrdNo(store.getOrdNo());
        inRecord.setCarNo(store.getCarNo());
        inRecord.setTallyPeople(store.getTallyPeople());
        inRecord.setContractNo(store.getContractNo());

        return inRecord;
    }


}
