package com.prolog.cs.biz.inbound.service.impl;

import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.prolog.cs.biz.inbound.Application;
import com.prolog.cs.biz.inbound.dao.SupervisionCodeMapper;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.remote.BaseWmsWarehouseCaller;
import com.prolog.cs.biz.inbound.remote.ChainRemoteCaller;
import com.prolog.cs.biz.inbound.service.rcv.RcvHeadersService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.framework.authority.util.HystrixVarUtil;
import com.prolog.framework.bz.common.search.SearchApi;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.utils.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 * 基础测试类
 *
 * @author tianhl
 * @Date 2017/5/21 16:10
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
//@Transactional //打开的话测试之后数据可自动回滚
public class SupervisionCodeXmlHandlerTest {

    private static Logger log = LoggerFactory.getLogger(SupervisionCodeXmlHandlerTest.class);

    @Autowired
    WebApplicationContext webApplicationContext;

    protected MockMvc mockMvc;

    @Autowired
    private RcvHeadersService rcvHeadersService;

    @Value("classpath:rcvDTO.json")
    private Resource rcvDTO;

    @Autowired
    private SupervisionCodeMapper mapper;

    @Autowired
    private SupervisionCodeXmlHandler supervisionCodeXmlHandler;

    @Autowired
    private BaseWmsWarehouseCaller baseWmsWarehouseCaller;

    @Autowired
    private ChainRemoteCaller chainRemoteCaller;

    @Autowired
    private SearchApi searchApi;

    @Before
    public void setupMockMvc(){
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        HystrixVarUtil.setUserKey("kzywmstest");
    }

    @Test
    public void spellXmlAndUpdate(){
        try {
            String[] split = "638772751850672128,638796125419212800".split(",");
            List<SupervisionCode> voList = this.mapper.findByIds(SupervisionCode.class, split, null);
            Map<String, Map<String, String>> elecCodeMap = new HashMap();
            System.out.println(supervisionCodeXmlHandler.spellXml(1, voList,elecCodeMap));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void exportXmlAll(){
        String warehouseId="658952120325658545";
        String cargoOwnerId="E2UXG3AVQOO";
        Integer supervisionType=0;
        String srcCode="";
//        srcCode="SKPWS400020065";
//        srcCode="STPWS400001066";
        Map<String, Map<String, String>> elecCodeMap = new HashMap();
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        HystrixVarUtil.setUserKey("kzywms-admin");
        for (int j = 0; j < 4; j++) {
            List<SupervisionCode> voList =null;

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {

                supervisionType=j;
//                supervisionType=1;
//                supervisionType=1;
                Criteria crt = Criteria.forClass(SupervisionCode.class);
                Restriction eq = StringUtils.isBlank(warehouseId) ? null : Restrictions.eq("warehouseId", warehouseId);
                Restriction eq2 = StringUtils.isBlank(cargoOwnerId) ? null : Restrictions.eq("cargoOwnerId", cargoOwnerId);
                Restriction eq3 = Restrictions.eq("supervisionType", supervisionType);
                Restriction eq4 = ObjectUtils.isNull(srcCode) ? null : Restrictions.eq("srcCode", srcCode);
                String[] str =new String[]{"SKPWS400020260", "SKPWS400027097"};
                Restriction eq5 = Restrictions.in("srcCode", str);
                //Restriction eq6 = Restrictions.eq("status", 20);
                //Restriction eq6 = Restrictions.eq("status", 10);
                Restriction eq7 = Restrictions.between("gmtCreate",
                        //sdf1.parse("2022-03-30 16:11:11"), sdf1.parse("2022-04-17 23:59:59"));
                        //sdf1.parse("2022-04-18 00:00:00"), sdf1.parse("2022-05-01 23:59:59"));
                        sdf1.parse("2022-05-01 23:59:59"), sdf1.parse("2022-05-21 23:59:59"));
                //Restriction eq7 = Restrictions.le("status", 20);
                //Restriction eq8 = Restrictions.eq("srcCode", "SKPWS400024979");
                //Restriction eq8 = Restrictions.eq("srcCode", "PDDWS400006420");
                //Restriction eq8 = Restrictions.eq("srcCode", "PDDWS400006420");


                Restriction eq8 = Restrictions.isNotNull("srcCode");
                crt.setRestriction(Restrictions.and(eq, eq2, eq3, eq4,
                        //eq5,
                        //eq6,
                        eq7,
                        eq8));
                voList = this.mapper.findByCriteria(crt);
                if(voList==null || voList.size()==0){
                    continue;
                }
                String inOrOut = (supervisionType == 0 || supervisionType == 1) ? "IN" : "OUT";

                List<String> srcCodeList= voList.stream().map(SupervisionCode::getSrcCode).distinct().collect(Collectors.toList());
                int count = srcCodeList.size() > 2000? (srcCodeList.size() % 2000): 1;
                for (int m = 0; m < count; m++) {
                    // 输出流
                    BufferedInputStream bufferedInputStream = null;
                    ZipOutputStream zipOutputStream = null;
                    FileOutputStream outputStream=null;
                    try {

                        List<SupervisionCode> updateSrcCodeSubList=new ArrayList<>();
                        int size= (m==count-1? srcCodeList.size() : (m+1)*2000);
                        for (int i = m*2000; i < size; i++) {
                            String tempSrcCode=srcCodeList.get(i);
                            List<SupervisionCode> srcCodeSubList =voList.stream().filter(p -> tempSrcCode.equals(p.getSrcCode())).collect(Collectors.toList());
                            updateSrcCodeSubList.addAll(srcCodeSubList);
                        }
                        Set supplierSet = updateSrcCodeSubList.stream().filter(t -> !elecCodeMap.containsKey(t.getSupplierId())).map(SupervisionCode::getSupplierId).collect(Collectors.toSet());;
                        //请求客户信息
                        Set customerSet = updateSrcCodeSubList.stream().filter(t -> !elecCodeMap.containsKey(t.getShipperId())).map(SupervisionCode::getShipperId).collect(Collectors.toSet());;
                        try {
                            if(supplierSet!=null && supplierSet.size()>0){
                                Map<String, Object> queryMap = new HashMap<>();
                                queryMap.put("type", "supplier");
                                queryMap.put("ids", new ArrayList<>(supplierSet));
                                List<Map> searchForMap = searchApi.searchForMap("queryChainElecCode", queryMap);
                                for (int i = 0; i < searchForMap.size(); i++) {
                                    Map map = searchForMap.get(i);
                                    Map sonMap=new HashMap();
                                    sonMap.put("code",map.get("code").toString());
                                    sonMap.put("elecCode",map.get("elecCode")==null?null:map.get("elecCode").toString());
                                    elecCodeMap.put(map.get("id").toString(), sonMap);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("随机获取质检操作员接口异常", e);
                            //throw new BizException("调用查询服务queryChainElecCode异常");
                        }
                        try {
                            if(customerSet!=null && customerSet.size()>0){
                                Map<String, Object> queryMap1 = new HashMap<>();
                                queryMap1.put("type", "customer");
                                queryMap1.put("ids", new ArrayList<>(customerSet));
                                List<Map> searchForMap1 = searchApi.searchForMap("queryChainElecCode", queryMap1);
                                for (int i = 0; i < searchForMap1.size(); i++) {
                                    Map map = searchForMap1.get(i);
                                    Map sonMap=new HashMap();
                                    sonMap.put("code",map.get("code").toString());
                                    sonMap.put("elecCode",map.get("elecCode")==null?null:map.get("elecCode").toString());
                                    elecCodeMap.put(map.get("id").toString(), sonMap);
                                }
                            }
                            System.out.println(1);
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("随机获取质检操作员接口异常", e);
                            //throw new BizException("调用查询服务queryChainElecCode异常");
                        }
                        String preFileName = inOrOut + "_" + "昭通" + "_" + sdf.format(new Date());
                        outputStream = new FileOutputStream("D:\\wms\\xmlProd\\"+preFileName+".zip");
                        zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
                        log.info("supervisionType:"+supervisionType+",文件："+preFileName+",订单数:"+size);
                        for (int i = m*2000; i < size; i++) {
                            String tempSrcCode=srcCodeList.get(i);
                            ZipEntry zipEntry = new ZipEntry(preFileName  + "_"+ tempSrcCode+ ".xml");
                            zipOutputStream.putNextEntry(zipEntry);
                            List<SupervisionCode> srcCodeSubList =voList.stream().filter(p -> tempSrcCode.equals(p.getSrcCode())).collect(Collectors.toList());
                            String beanToXml = supervisionCodeXmlHandler.spellXml(supervisionType, srcCodeSubList, elecCodeMap);
                            zipOutputStream.write(beanToXml.getBytes("UTF-8"));
                        }
                        zipOutputStream.flush();
                        outputStream.flush();
                    } catch (Exception e2) {
                        e2.printStackTrace();
                        log.error("1341",e2);
                    }finally {
                        // 关闭流
                        try {
                            if (null != bufferedInputStream) {
                                bufferedInputStream.close();
                            }
                            if (null != zipOutputStream) {
                                zipOutputStream.close();
                            }
                            if (null != outputStream) {
                                outputStream.close();
                            }
                        } catch (Exception e1) {
                            e1.printStackTrace();
                            log.error("IOException occureds...", e1);
                        }

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("exportXml",e);
                throw new RuntimeException(e);
            }
        }
    }
}
