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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huimv.manage.eartag.dao.entity.EtEarmarkEntity;
import com.huimv.manage.eartag.dao.repo.EarmarkRepo;
import com.huimv.manage.eartag.service.IEarmarkService;
import com.huimv.manage.util.*;
import com.huimv.manage.webservice.Soap;
import com.huimv.manage.webservice.task.EarmarkTask;
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 javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;

/**
 * @Project : huimv.shiwan
 * @Package : com.huimv.biosafety.uface.controller
 * @Description : TODO
 * @Version : 1.0
 * @Author : ZhuoNing
 * @Create : 2020-12-25
 **/
@Service
@Slf4j
public class EarmarkServiceImpl implements IEarmarkService {
    @Value("${webservice.url}")
    private String webServiceUrl;
    @Autowired
    private EarmarkRepo earmarkRepo;
    @Autowired
    private EarmarkTask earmarkTask;
    @Autowired
    private Soap soap;
    @Autowired
    private CodeUtil codeUtil;
    @Autowired
    private ExcelUtil excelUtil;

    /**
     * @Method      : listEarmark
     * @Description : 展示列表
     * @Params      : [pageSize]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 21:14
     */
    @Override
    public Result listEarmark(int pageSize) {
        //
        List<EtEarmarkEntity> earmarkEntityList = earmarkRepo.listEarmark(pageSize);
        return new Result(ResultCode.SUCCESS,earmarkEntityList);
    }

    @Override
    public Result listEarmark(Integer applyId, Integer packageId, Integer earMarkId, Integer earMarkNumber, Integer returnState, Integer writeState, Integer printState, Date startDate, Date endDate, Integer pageSize, Integer pageNo) {
        Specification<EtEarmarkEntity> sf = (Specification<EtEarmarkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            //
            List<Predicate> predList = new ArrayList<>();
            if (null != applyId) {
                predList.add(criteriaBuilder.equal(root.get("applyId").as(Integer.class), applyId));
            }
            if (null != packageId) {
                predList.add(criteriaBuilder.equal(root.get("packageId").as(Integer.class), packageId));
            }
            if (null != earMarkId) {
                predList.add(criteriaBuilder.equal(root.get("earMarkId").as(Integer.class), earMarkId));
            }
            if (null != earMarkNumber) {
                predList.add(criteriaBuilder.equal(root.get("earMarkNumber").as(Integer.class), earMarkNumber));
            }
            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));
            }
            if (null != writeState) {
                predList.add(criteriaBuilder.equal(root.get("writeState").as(Integer.class), writeState));
            }
            if (null != printState) {
                predList.add(criteriaBuilder.equal(root.get("printState").as(Integer.class), printState));
            }
            //
            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, earmarkRepo.findAll(sf, pageable));
    }

    /**
     * @Method      : getEarmark
     * @Description : 下载耳标号
     * @Params      : [applyId]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 21:14
     */
    @Override
    public Result getEarmark(int applyId) throws IOException {
        // 构造请求
        String requestXML = earmarkTask.getRequestEarmarkXML(applyId);
//        System.out.println("requestXML="+requestXML);

        // 调用接口返回结果
        String earMarkReponseXML = soap.callSoap(requestXML,webServiceUrl);
//        System.out.println("earMarkReponseXML="+earMarkReponseXML);

        // 解析结果
        JSONArray downloadEarmarkJa = earmarkTask.parseEarMarkReponseXML(earMarkReponseXML);
        // 耳标入库
        JSONArray newEarmarkJa = filterEarmark(downloadEarmarkJa);
        if(newEarmarkJa.size() == 0){
            return new Result(Const.CODE_NO_NEW_EARMARK,Const.NO_NEW_EARMARK,false);
        }
        for(int a=0;a<newEarmarkJa.size();a++){
            JSONObject earmarkJo = newEarmarkJa.getJSONObject(a);
            EtEarmarkEntity earmarkEntity = new EtEarmarkEntity();
            earmarkEntity.setEarmarkId(earmarkJo.getString("earmarkId"));
            earmarkEntity.setPackageId(earmarkJo.getString("packageId"));
            earmarkEntity.setEarmarkNumber(earmarkJo.getString("earmarkNumber"));
            earmarkEntity.setApplyId(earmarkJo.getString("applyId"));
            earmarkEntity.setEarmarkData(codeUtil.convertBase64BinaryToHex(earmarkJo.getString("earmarkData")));
            earmarkEntity.setSetPrintState(0);
            earmarkEntity.setSetWriteState(0);
            earmarkEntity.setSetDownState(0);
            earmarkEntity.setSetUploadState(0);
            earmarkRepo.saveAndFlush(earmarkEntity);
        }
        return new Result(Const.CODE_OK,"本次下载"+newEarmarkJa.size()+"个新耳标号数据.",false);
    }

    /**
     * @Method      : setUpdateDownState
     * @Description : 设置耳标已下载状态
     * @Params      : [earmarkIDs]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/29       
     * @Time        : 23:00
     */
    @Override
    public Result setUpdateDownState(String earmarkIDs) throws UnsupportedEncodingException {
        //构造请求字符串
        String requestXML = earmarkTask.getUpdateDownStateRequestXML(earmarkIDs);
        //远程调用返回结果
        String reponseXML = "";
        reponseXML = soap.callSoap(requestXML,webServiceUrl);
        // test
//        reponseXML = earmarkTask.TestParseUpdateDownStateXML();
        //解析
        String updateDownState = earmarkTask.parseUpdateDownStateXML(reponseXML);
        // 入库
        if(updateDownState.trim().equalsIgnoreCase("false")){
            return new Result(Const.CODE_UPDATE_EARMARK_DOWN_STATE_FAIL,Const.UPDATE_EARMARK_DOWN_STATE_FAIL,false);
        }else{
            String[] earmarkIDArray = earmarkIDs.split(",");
            for(int a=0;a<earmarkIDArray.length;a++){
                EtEarmarkEntity earmarkEntity = new EtEarmarkEntity();
                earmarkEntity.setEarmarkId(earmarkIDArray[a]);
                ExampleMatcher matcher = ExampleMatcher.matching()
                        .withMatcher("earmark_id" ,ExampleMatcher.GenericPropertyMatchers.contains());
                Example example = Example.of(earmarkEntity,matcher);
                Optional optional= earmarkRepo.findOne(example);
                if (optional.isPresent()){
                    EtEarmarkEntity earmarkEntity1  = (EtEarmarkEntity) optional.get();
                    earmarkEntity1.setSetDownState(1);
//                    earmarkEntity1.setSetDownDate(new Timestamp(new Date().getTime()));
                    earmarkEntity1.setSetDownDate(new Timestamp(System.currentTimeMillis()));
                    earmarkRepo.saveAndFlush(earmarkEntity1);
                }else{
                    return new Result(Const.CODE_NO_RECORD,Const.NO_RECORD,false);
                }
            }
            return new Result(ResultCode.SUCCESS);
        }
    }

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

    /**
     * @Method      : setWriteState
     * @Description : 设置写入时间
     * @Params      : [ids, state]
     * @Return      : com.huimv.manage.util.Result
     *
     * @Author      : ZhuoNing
     * @Date        : 2021/10/30
     * @Time        : 0:02
     */
    @Override
    public Result setWriteState(String ids, int state) {
        String[] idArray = ids.split(",");
        for(int a=0;a<idArray.length;a++){
            Optional optional = earmarkRepo.findById(Integer.parseInt(idArray[a]));
            EtEarmarkEntity earmarkEntity = (EtEarmarkEntity) optional.get();
            earmarkEntity.setSetWriteState(state);
            earmarkEntity.setSetWriteDate(new Timestamp(new Date().getTime()));
            earmarkRepo.saveAndFlush(earmarkEntity);
        }
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * @Method      : setPrintState
     * @Description : 设置打码状态
     * @Params      : [ids, state]
     * @Return      : com.huimv.manage.util.Result
     * 
     * @Author      : ZhuoNing
     * @Date        : 2021/10/30       
     * @Time        : 0:04
     */
    @Override
    public Result setPrintState(String ids, int state) {
        String[] idArray = ids.split(",");
        for(int a=0;a<idArray.length;a++){
            Optional optional = earmarkRepo.findById(Integer.parseInt(idArray[a]));
            EtEarmarkEntity earmarkEntity = (EtEarmarkEntity) optional.get();
            earmarkEntity.setSetPrintState(state);
//            earmarkEntity.setSetPrintDate(new Timestamp(new Date().getTime()));
            earmarkEntity.setSetPrintDate(new Timestamp(System.currentTimeMillis()));
            earmarkRepo.saveAndFlush(earmarkEntity);
        }
        return new Result(ResultCode.SUCCESS);
    }

    //过滤已经存在的耳标号
    private JSONArray filterEarmark(JSONArray downloadEarmarkJa) {
        JSONArray newEarmarkJa = new JSONArray();
        for(int a=0;a<downloadEarmarkJa.size();a++){
            JSONObject downloadEarmarkJo = downloadEarmarkJa.getJSONObject(a);
            String earmarkId = downloadEarmarkJo.getString("earmarkId");

            EtEarmarkEntity earmarkEntity = new EtEarmarkEntity();
            earmarkEntity.setEarmarkId(earmarkId);
            ExampleMatcher matcher = ExampleMatcher.matching()
                    .withMatcher("earmark_id" ,ExampleMatcher.GenericPropertyMatchers.contains());
            Example example = Example.of(earmarkEntity,matcher);
            if(!earmarkRepo.exists(example)){
                newEarmarkJa.add(downloadEarmarkJo);
            }
        }
        return newEarmarkJa;
    }

    /**
     * @Method      : exportEarmarkByApply
     * @Description : 通过任务号导出耳标号
     * @Params      : [applyId]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2021/11/9
     * @Time        : 14:11
     */
    @Override
    public void exportEarmarkByApply(Integer applyId,Integer printState,Integer quantity, HttpServletResponse response) throws IOException {
        Specification<EtEarmarkEntity> specific = (Specification<EtEarmarkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            //
            List<Predicate> predList = new ArrayList<>();
            if (null != applyId) {
                predList.add(criteriaBuilder.equal(root.get("applyId").as(Integer.class), applyId));
            }
            if (null != printState && printState != 0) {
                predList.add(criteriaBuilder.equal(root.get("printState").as(Integer.class), printState));
            }
            //
            Predicate[] pred = new Predicate[predList.size()];
            Predicate and = criteriaBuilder.and(predList.toArray(pred));
            criteriaQuery.where(and);
            //
            List<Order> orders = new ArrayList<>();
            orders.add(criteriaBuilder.asc(root.get("id")));
            return criteriaQuery.orderBy(orders).getRestriction();
        };
        //
        List<EtEarmarkEntity> dataList = earmarkRepo.findAll(specific);
        log.info("导出数据数量="+dataList.size());
        //
        excelUtil.exportEarmarkExcel(response,Const.EXPORT_EARMARK_EXCEL,String.valueOf(applyId),dataList,quantity);
        // test
//        excelUtil.exportEarmarkExcel(String.valueOf(applyId),dataList,quantity);
    }

    @Override
    public void exportEarmarkByEarmark(String ids, Integer printState,Integer quantity, HttpServletResponse response) throws IOException {
        Specification<EtEarmarkEntity> specific = (Specification<EtEarmarkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            //
            List<Predicate> predList = new ArrayList<>();
            if (null != ids && !ids.trim().equalsIgnoreCase("null")) {
                String[] idsArray =  ids.split(",");
                Integer[] idArrInt = new Integer[idsArray.length];
                for(int a=0;a<idsArray.length;a++){
                    idArrInt[a]=Integer.parseInt(idsArray[a]);
                }
//                predList.add(criteriaBuilder.equal(root.get("id").as(Integer.class), applyId));
                predList.add(root.get("id").as(Integer.class).in(idArrInt));
            }
            //
            Predicate[] pred = new Predicate[predList.size()];
            Predicate and = criteriaBuilder.and(predList.toArray(pred));
            criteriaQuery.where(and);
            //
            List<Order> orders = new ArrayList<>();
            orders.add(criteriaBuilder.asc(root.get("id")));
            return criteriaQuery.orderBy(orders).getRestriction();
        };
        //
        List<EtEarmarkEntity> dataList = earmarkRepo.findAll(specific);
        log.info("导出数据数量:"+dataList.size());
        String applyId = null;
        if(dataList.size() > 0){
            EtEarmarkEntity earmarkEntity = dataList.get(0);
            applyId = earmarkEntity.getApplyId();
        }
        //
        excelUtil.exportEarmarkExcel(response,Const.EXPORT_EARMARK_EXCEL,applyId,dataList,quantity);
        // test
//        excelUtil.exportEarmarkExcel(applyId,dataList,quantity);
    }

    //导出耳标数据到文本文件中
    @Override
    public void exportEarmarkByApplyToTxt(Integer applyId, Integer printState, Integer quantity, HttpServletResponse response) {



    }

    @Override
    public void exportTest1(Integer applyId, Integer printState, Integer quantity, HttpServletResponse response) {
        String fileName = "fileName" + ".txt";
        String content = "写入txt的内容";
        response.setContentType("text/plain");

        try {
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        ServletOutputStream outputStream = null;
        BufferedOutputStream buffer = null;

        try {
            outputStream = response.getOutputStream();
            buffer = new BufferedOutputStream(outputStream);
            buffer.write(content.getBytes("UTF-8"));
            buffer.flush();
            buffer.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportTest2(Integer applyId, Integer printState, Integer quantity, HttpServletResponse response) {

    }
}
