package com.yem.tws.aip;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.yem.tws.common1.CommonUtils;
import kd.bos.bill.IBillWebApiPlugin;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.api.ApiResult;
import kd.bos.id.ID;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.logorm.LogORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import sun.misc.BASE64Decoder;


public class UploadAttachments implements IBillWebApiPlugin {

    private final static Log logger = LogFactory.getLog(UploadAttachments.class);

    @Override
    public ApiResult doCustomService(Map<String, Object> params) {
        List<Object> resultlist = Collections.synchronizedList(new ArrayList<>());
        boolean BollISSucces = false;
        String ErrMassage = "";
        String FID = "";
        String billno = "";
        JSONObject jsonData = null;
        try {
            jsonData = JSONObject.parseObject(JSONObject.toJSONString(params));
            billno = jsonData.getString("billno");
            Map<String, Object> Data = new HashMap<String, Object>();
            Data.put("accessToken",jsonData.getString("accessToken"));
            Data.put("url",jsonData.getString("url"));
            Data.put("billno",jsonData.getString("billno"));
            Data.put("entityNumber",jsonData.getString("entityNumber"));
            Data.put("APPNUMBER",jsonData.getString("APPNUMBER"));
            Data.put("FileName",jsonData.getString("FileName"));

            File File = base64ToFile(jsonData.getString("Base64"));
            if (File != null) {
//                Map<String, Object> allBizBillData =   remoteSaveAttasToCosmic(url,accessToken,File,billno,entityNumber, APPNUMBER);
                List<File> fileList1 = new ArrayList<>();
                fileList1.add(File);
                Map<String, List<File>> files = new HashMap<String, List<File>>();
                // 将各文件放入苍穹单据上指定的附件面板中
                files.put("attachmentpanel", fileList1);
                // 封装数据, 并文件发送至苍穹系统中
                Map<String, Object> allBizBillData = this.generateBizData(files, Data);
                if(allBizBillData!=null){
                    JSONObject body = new JSONObject();
                    body.put("billData", allBizBillData.get("billData"));
                    body.put("allAttachmentsData", allBizBillData.get("allAttachmentsData"));
                    body.put("params", allBizBillData.get("params"));
                    doExecute(body,resultlist);
                    synchronized (resultlist) {
                        for (Object result : resultlist) {
                            @SuppressWarnings("unchecked")
                            Map<String, Object> map = (Map<String, Object>) result;
                            if (null != map) {
                                if (map.get("result") == Boolean.TRUE) {
                                    return ApiResult.success(resultlist);
                                } else {
                                    return ApiResult.fail((String) map.get("description"));
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public void doExecute(JSONObject jsonData, List<Object> resultlist) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        StringBuilder message = new StringBuilder();
        boolean synresult = true;
        String Fid = "";
        // 单据数据信息
        JSONObject bizObject = jsonData.getJSONObject("billData");
        String billno = bizObject.getString("billno");
        logger.info("单据数据信息: " + bizObject);

        // 附件信息
        JSONObject attachmentInfo = jsonData.getJSONObject("allAttachmentsData");
        logger.info("参数信息信息: " + attachmentInfo);

        // 参数信息
        JSONObject paramMap = jsonData.getJSONObject("params");
        String appId = paramMap.getString("appId");
        String entityNumber = paramMap.getString("entityName");
        logger.info("参数信息信息: " + paramMap);
        logger.info(">>> 上传附件 <<<");
        if (billno.isEmpty()) {
            message.append("唯一标识单号为空！").append("\n");
            synresult = false;
        }
        if (appId.isEmpty()) {
            message.append("应用标识为空！").append("\n");
            synresult = false;
        }
        if (entityNumber.isEmpty()) {
            message.append("单据标识为空！").append("\n");
            synresult = false;
        }
        if (attachmentInfo.isEmpty()) {
            message.append("附件信息为空！").append("\n");
            synresult = false;
        }
        if (synresult) {
            QFilter qFilter = new QFilter("billno", QCP.equals, billno);
            DynamicObject[] bllDycol = BusinessDataServiceHelper.load(entityNumber, "id,billno", new QFilter[]{qFilter});
            if (bllDycol.length > 1) {
                message.append("单据不唯一请检查！").append("\n");
                synresult = false;
            } else if (bllDycol.length == 0) {
                message.append("附件对应单据为空！").append("\n");
                synresult = false;
            }
            DynamicObject bllDy = bllDycol[0];
            Object pkId = bllDy.getPkValue();
            DynamicObjectCollection collection = AttachmentServiceHelper.saveTempAttachments(entityNumber, pkId, appId, attachmentInfo);
            if (null == collection || collection.size() == 0) {
                message.append("单据").append(entityNumber).append(billno).append("附件上传失败").append("\n");
                synresult = false;
            } else {
                message.append("单据").append(entityNumber).append(billno).append("附件上传成功").append("\n");
                message.append("附件成功").append("\n");
                for (int j = 0; j < collection.size(); j++){
                    DynamicObject yem_entityfieldcol = collection.get(j);
                    Fid = yem_entityfieldcol.getString("id");
                }
            }

        }
        resultMap.put("description", message.toString());
        resultMap.put("result", synresult);
        resultMap.put("Fid", Fid);
        resultlist.add(resultMap);

        //写入日志信息
        // 根据实体名构建元数据并创建DynamicObject
        MainEntityType entityType = EntityMetadataCache.getDataEntityType("yem_ca_apilog");
        DynamicObject dynamicObject = new DynamicObject(entityType);
        dynamicObject.getDataEntityType().getPrimaryKey().setValueFast(dynamicObject, ID.genLongId());
        dynamicObject.set("username", CommonUtils.getCurrentUser().getString("name"));
        dynamicObject.set("opname", "单一窗口同步附件");
        dynamicObject.set("opdesc", "将报关单相关附件同步至ERP系统");
        dynamicObject.set("opdate", new Date());

        if (resultMap.get("result") == Boolean.TRUE) {
            dynamicObject.set("yem_description", "同步成功");

            dynamicObject.set("yem_issuccess", "success");
        } else {
            dynamicObject.set("yem_description", "同步失败请查看详细信息");

            dynamicObject.set("yem_issuccess", "fail");
        }
        dynamicObject.set("yem_description_tag", resultMap.get("billno") + ":" + resultMap.get("description"));

        dynamicObject.set("yem_datajson", billno);
        dynamicObject.set("yem_datajson_tag", jsonData.toJSONString());

        dynamicObject.set("yem_interfacetype", "UploadAttachments");

        // 批量插入，需要保证objects中为同一个单据类型的DynamicObject
        List<DynamicObject> objects = new ArrayList<>();
        objects.add(dynamicObject);

        // 初始化LogORM实例
        LogORM logORM = LogORM.create();
        // 批量插入
        logORM.insert(objects);

    }

    /**
     *
     * @param base64 base64文件字符串
     * @return
     * @throws Exception
     */
    public static File base64ToFile(String base64) throws Exception {
        //创建文件目录
        String prefix = ".pdf";
        File file = File.createTempFile(UUID.randomUUID().toString(), prefix);
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(base64);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }

    /**
     * 封装单据数据  & 所有附件数据
     *
     * @param allFiles    所有待上传到苍穹的附件
     * @param Data        所需参数
     * @return
     * @throws Exception
     */
    private Map<String, Object> generateBizData(Map<String, List<File>> allFiles, Map<String, Object> Data) throws Exception {
        Map<String, Object> allBizBillData = new HashMap<String, Object>();
        // 单据信息数据
        Map<String, Object> billData = new HashMap<String, Object>();
        billData.put("billno",Data.get("billno").toString()); //唯一标识 编码
        allBizBillData.put("billData", billData);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("appId", Data.get("APPNUMBER").toString());
        params.put("entityName", Data.get("entityNumber").toString());
        allBizBillData.put("params", params);
        // 生成单据上所有的附件数据
        Map<String, Object> allAttachmentsData = new HashMap<String, Object>();
        // 单个附件面板中所有附件的信息
        List<Map<String, Object>> attachments = null;
        // 单个附件的信息
        Map<String, Object> attachmentInfo = null;
        StringBuffer uid = new StringBuffer();
        uid.append("rc-upload-").append(new Date().getTime()).append("-");
        int index = (int) (1 + Math.random() * 10);
        for (String tempAttaKey : allFiles.keySet()) {
            List<File> files = allFiles.get(tempAttaKey);
            attachments = new ArrayList<Map<String, Object>>();
            for (File tempFile : files) {
                String tempAttaUrl = this.postFileToCosmic(tempFile,Data.get("accessToken").toString(),Data.get("url").toString());
                attachmentInfo = new HashMap<String, Object>();
                attachmentInfo.put("entityNum",Data.get("billno").toString());//单据编码
                attachmentInfo.put("name", Data.get("FileName").toString());//附件名称
                attachmentInfo.put("url", tempAttaUrl);//附件地址
                attachmentInfo.put("size", tempFile.length());//附件大小
                attachmentInfo.put("status", "success");
                attachmentInfo.put("uid", uid.toString() + index++);
                attachments.add(attachmentInfo);
            }
            allAttachmentsData.put(tempAttaKey, attachments);
        }
        allBizBillData.put("allAttachmentsData", allAttachmentsData);
        return allBizBillData;
    }

    /**
     * 将文件发送到苍穹中
     *
     * @param file
     * @param accessToken
     * @return
     * @throws Exception
     */
    private String postFileToCosmic(File file, String accessToken,String uploadurl) throws Exception {
        // 第三方系统上传附件到苍穹的请求接口
        StringBuffer url = new StringBuffer();
        url.append(uploadurl).append("attachment/uploadFile.do");
        // 上传可能需要传的参数
        Map<String, Object> param = new HashMap<String, Object>();
        // 上传附件,返回该附件在苍穹缓存中的临时存储路径
        return FileUploadService.getService().postFile(url.toString(), param, file, accessToken);
    }

    public String bizSave(String cosmicHost, String accessToken, Map<String, Object> allAttachmentsData) throws URISyntaxException {
        // 自定义开放平台接口路
        StringBuffer url = new StringBuffer();
        url.append(cosmicHost).append("kapi/app/yem_ca/UploadAttachments");
        System.out.println(">>> " + url.toString());
        // 封装数据
        JSONObject body = new JSONObject();
        body.put("billData", allAttachmentsData.get("billData"));
        body.put("allAttachmentsData", allAttachmentsData.get("allAttachmentsData"));
        body.put("params", allAttachmentsData.get("params"));
        String responseStr = null;
        try {
            responseStr = HttpService.getService().doGetByHttpClient(url.toString(), accessToken, body);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseStr;
    }
}
