package com.huimv.manage.eartag.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huimv.manage.eartag.dao.entity.EtPackageEntity;
import com.huimv.manage.eartag.dao.repo.PackageRepo;
import com.huimv.manage.eartag.service.IPackageService;
import com.huimv.manage.util.Const;
import com.huimv.manage.util.Result;
import com.huimv.manage.util.ResultCode;
import com.huimv.manage.webservice.Soap;
import com.huimv.manage.webservice.task.PackageTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @Project : huimv.shiwan
 * @Package : com.huimv.biosafety.uface.controller
 * @Description : TODO
 * @Version : 1.0
 * @Author : ZhuoNing
 * @Create : 2020-12-25
 **/
@Service
@Slf4j
public class PackageServiceImpl implements IPackageService {
    @Value("${webservice.url}")
    private String webServiceUrl;
    @Autowired
    private PackageRepo packageRepo;
    @Autowired
    private PackageTask packageTask;
    @Autowired
    private Soap soap;

    @Override
    public Result listPackage(int pageSize) {
        List<EtPackageEntity> packageEntityList = packageRepo.listPackage(pageSize);
        return new Result(ResultCode.SUCCESS,packageEntityList);
    }

    @Override
    public Result listPackage(Integer applyId, Integer packageId, Date startDate, Date endDate, Integer returnState, Integer pageSize, Integer pageNo) {
        Specification<EtPackageEntity> spec = (Specification<EtPackageEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            //
            List<Predicate> predList = new ArrayList<>();
            if (null != applyId) {
                predList.add(criteriaBuilder.equal(root.get("applyId").as(Integer.class), applyId));
            }
            if (null != startDate) {
                predList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("startDate").as(Date.class), startDate));
            }
            if (null != endDate) {
                predList.add(criteriaBuilder.lessThanOrEqualTo(root.get("endDate").as(Date.class), endDate));
            }
            if (null != returnState) {
                predList.add(criteriaBuilder.equal(root.get("returnState").as(Integer.class), returnState));
            }
            //
            Predicate[] pred = new Predicate[predList.size()];
            Predicate and = criteriaBuilder.and(predList.toArray(pred));
            criteriaQuery.where(and);
            //
            List<Order> orders = new ArrayList<>();
            orders.add(criteriaBuilder.desc(root.get("id")));
            return criteriaQuery.orderBy(orders).getRestriction();
        };
        //分页
        Pageable pageable = PageRequest.of( pageNo - 1, pageSize);
        return new Result(ResultCode.SUCCESS, packageRepo.findAll(spec, pageable));
    }

    /**
     * @Method      : getNewPackage
     * @Description : 
     * @Params      : [applyId]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 16:08
     */
    @Override
    public Result getNewPackage(int applyId) throws UnsupportedEncodingException {
        // Step1.下载新批次数据
        // Step2.新批次数据入库

        //调用接口获取远程数据
        String answerXML = soap.callSoap(packageTask.getNewPackageRequestXML(applyId),webServiceUrl);
//        log.info("应答文件="+answerXML);

        //解析应答数据
        JSONArray downPackageJa = packageTask.parseNewPackageAnswerXML(answerXML);
//        System.out.println("downPackageJa.zie="+downPackageJa.size());

        // 过滤已经存在批次数据
        JSONArray newPackageJa = filterPackage(downPackageJa);
        if(newPackageJa.size() == 0){
            return new Result(Const.CODE_PACKAGE_EXIST, Const.PACKAGE_EXIST,false);
        }
        //新批次数据入库
        for(int a=0;a<newPackageJa.size();a++){
            JSONObject packageJo = newPackageJa.getJSONObject(a);
            EtPackageEntity newPackageEntity = new EtPackageEntity();
            newPackageEntity.setPackageId(packageJo.getIntValue("packageId"));
            newPackageEntity.setPackageNumber(packageJo.getString("packageNumber"));
            newPackageEntity.setApplyId(packageJo.getIntValue("applyID"));
            newPackageEntity.setPackageData(packageJo.getString("packageData"));
            newPackageEntity.setDownloadDate(new Timestamp(new Date().getTime()));
            newPackageEntity.setProduceState(0);
            packageRepo.saveAndFlush(newPackageEntity);
        }
        return new Result(Const.CODE_OK,Const.SAVE_NEW_PACKAGE,true);
    }

    /**
     * @Method      : setReturnDownloadState
     * @Description : 
     * @Params      : [packageIds, ids]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 19:15
     */
    @Override
    public Result setReturnDownloadState(String packageIds,String ids) throws UnsupportedEncodingException {
        String[] packageIdArray = packageIds.split(",");
        String[] idArray = ids.split(",");

        // 构造请求XML
        String requestXML = packageTask.getReturnPackageHasDownloadXML(packageIdArray);
        String answerXML = "";
        // 提交请求
      answerXML = soap.callSoap(requestXML,webServiceUrl);
        // 解析报文
        String setReturnState = packageTask.parseAnswerXML(answerXML);
        if(setReturnState.trim().equalsIgnoreCase("false")){
            return new Result(Const.CODE_UPDATE_PACKAGE_STATE_DOWN_FAIL,Const.UPDATE_PACKAGE_DOWN_STATE_FAIL,false);
        }
        // 将返回结果入库
        for(int a=0;a<idArray.length;a++){
            Optional optional = packageRepo.findById(Integer.parseInt(idArray[a]));
            if(optional.isPresent()){
                EtPackageEntity packageEntity = (EtPackageEntity) optional.get();
                packageEntity.setSetDownState(1);
                packageEntity.setSetDownStateDate(new Timestamp(new Date().getTime()));
                packageRepo.saveAndFlush(packageEntity);
            }
        }
        return new Result(ResultCode.SUCCESS);
    }

    //过滤已经存在的批次数据
    private JSONArray filterPackage(JSONArray downPackageJa) {
        JSONArray newApplyJa = new JSONArray();
        // 过滤已经入库的批次数据
        for(int a=0;a<downPackageJa.size();a++){
            JSONObject packageJo = downPackageJa.getJSONObject(a);
            int packageId = packageJo.getIntValue("packageId");
            String packageNumber = packageJo.getString("packageNumber");
            EtPackageEntity packageEntity = new EtPackageEntity();
            packageEntity.setPackageId(packageId);
            packageEntity.setPackageNumber(packageNumber);
            ExampleMatcher matcher = ExampleMatcher.matching()
                    .withMatcher("package_id" ,ExampleMatcher.GenericPropertyMatchers.contains())
                    .withMatcher("package_number",ExampleMatcher.GenericPropertyMatchers.contains());
            Example example = Example.of(packageEntity,matcher);
            if(!packageRepo.exists(example)){
                newApplyJa.add(packageJo);
            }
        }
        return newApplyJa;
    }

    /**
     * @Method      : setProduceState
     * @Description : 设置生产状态
     * @Params      : [ids, state]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 23:57
     */
    @Override
    public Result setProduceState(String ids, int state) {
        String[] idArray = ids.split(",");
        for(int a=0;a<idArray.length;a++){
            Optional optional = packageRepo.findById(Integer.parseInt(idArray[a]));
            EtPackageEntity packageEntity = (EtPackageEntity) optional.get();
            packageEntity.setProduceState(state);
            packageEntity.setProduceStateDate(new Timestamp(new Date().getTime()));
            packageRepo.saveAndFlush(packageEntity);
        }
        return new Result(ResultCode.SUCCESS);
    }
}
