package com.seeyon.apps.esign.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.filemanager.manager.AttachmentManager;
import com.seeyon.ctp.common.filemanager.manager.FileManager;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.services.FileUploadExporter;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import www.seeyon.com.utils.StringUtil;
import www.seeyon.com.utils.UUIDUtil;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class FileUtil {

    private static final long MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
    private static final String TEMP_DIR = System.getProperty("java.io.tmpdir") + File.separator + "seeyontempfile";
    private static final String DEFAULT_FILENAME_PREFIX = "没有文件名_";
    private static final String CATEGORY_CODE = "66";
    private FileManager fileManager;

    public void setFileManager(FileManager fileManager) {
        this.fileManager = fileManager;
    }

    public FileManager getFileManager() {
        if (fileManager == null) {
            fileManager = (FileManager) AppContext.getBean("fileManager");
        }
        return fileManager;
    }

    private AttachmentManager attachmentManager;

    public void setAttachmentManager(AttachmentManager attachmentManager) {
        this.attachmentManager = attachmentManager;
    }

    public AttachmentManager getAttachmentManager() {
        if (attachmentManager == null) {
            attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager");
        }
        return attachmentManager;
    }

    public void isFilePath(String filePath) {
        File directory = new File(filePath);
        if (!directory.exists()) {
            directory.mkdirs();
        }

    }


    /**
     * 上传附件
     *
     * @param fileNames
     * @throws Exception
     * @throws NumberFormatException
     */
    public List<Attachment> fileUpload(List<String> fileNames, String summaryId, Long memberId, Long accountId) throws NumberFormatException, Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        FileUploadExporter fileUpload = new FileUploadExporter();
        List<Attachment> attachments = new ArrayList<Attachment>();
        File f = null;
        long l = UUIDUtil.getUUIDLong();
        for (int i = 0; i < fileNames.size(); i++) {
            String fileName = fileNames.get(i);
            if (StringUtils.isNotEmpty(fileName)) {
                f = new File(fileName);
                if (!f.exists()) {
                    return null;
                }
                if (f.length() > 102400000) {
                    return null;
                }
            }
            String[] strs = new String[]{f.getAbsolutePath()};
            String s = fileUpload.processUpload(strs);
            Map<String, String> map = new HashMap();
            String attachName = f.getName();
            String[] suffixNames = attachName.split("\\.");
            map.put("type", "0");
            map.put("fileUrl", s);
            map.put("mimeType", "application/" + suffixNames[suffixNames.length - 1].toLowerCase());
            map.put("size", f.length() + "");
            map.put("subReference", l + "");
            map.put("category", "66");
            map.put("createdate", sdf.format(new Date()));
            map.put("filename", f.getName());
            map.put("reference", summaryId);
            Attachment attachment = new Attachment(map);
            attachments.add(attachment);
        }
        String str = getAttachmentManager().create(attachments, memberId, accountId);
        return attachments;
    }


    public List<String> fieldFileDownload(Long refId, String path) throws BusinessException {
//        判断路径是否存在
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        List<Long> fileUrls = getAttachmentManager().getBySubReference(refId);
        System.out.println(fileUrls.size());
        List<String> filepaths = new ArrayList<>();
        for (Long fileUrl : fileUrls) {
            Attachment attachment = getAttachmentManager().getAttachmentByFileURL(fileUrl);
            InputStream inputStream = getFileManager().getFileInputStream(attachment.getFileUrl());
            String filepath = path + attachment.getFilename();
            try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filepath))) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            filepaths.add(filepath);
        }
        return filepaths;
    }


    public JSONArray getFileContent(String filePath) throws IOException {
        JSONArray jsonArray = new JSONArray();
        String houzhui = filePath.substring(filePath.lastIndexOf(".") + 1);
        // 创建文件输入流
        FileInputStream file = new FileInputStream(new File(filePath));
        // 创建工作簿对象
        Workbook workbook;
        System.out.println("当前文件为"+houzhui+"后缀");
        if ("xlsx".equals(houzhui) || "XLSX".equals(houzhui)) {
            workbook = new XSSFWorkbook(file);
        } else {
            workbook = new HSSFWorkbook(file);
        }
        // 获取第一个工作表
        Sheet sheet = workbook.getSheetAt(0);
        // 迭代行
        Iterator<Row> rowIterator = sheet.iterator();
//            根据行跳过设置
        row : while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            if (row.getRowNum() < 2) {
                continue;
            }
            int num = 0;
            int bj = 0;
            JSONObject jsonObject = new JSONObject();
            JSONArray SPS = new JSONArray();
            JSONObject SP = new JSONObject();
            boolean isddh = false;

            // 迭代单元格
            Iterator<Cell> cellIterator = row.cellIterator();
             cell : while (cellIterator.hasNext()) {
//                    获取单元格对象
                Cell cell = cellIterator.next();
//                    单元格索引为1的数据（订单号）
                if (cell.getColumnIndex() == 1) {
                    String ddh = "";
                    switch (cell.getCellType()) {
                        case STRING:
                            ddh = cell.getStringCellValue();
                            break;
                        case NUMERIC:
                            ddh = cell.getNumericCellValue()+"";
                            break;
                        default:
                            ddh = "";
                    }
//                    如果当前订单号为空，则跳过当前行数据
//                        查询当前订单号是否已经存在
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject json = jsonArray.getJSONObject(i);
                        if (ddh.equals(json.getString("DDH"))) {
//                                订单号已经存在
                            bj = i;
                            isddh = true;
                            jsonObject = json;
                            SPS = jsonObject.getJSONArray("SPS");
                        } else {
                            num++;
                        }
                    }
                    if (num == jsonArray.size()) {
//                        switch (cell.getCellType()) {
//                            case STRING:
                                jsonObject.put("DDH",ddh);
//                                break;
//                            case NUMERIC:
//                                jsonObject.put("DDH", cell.getNumericCellValue());
//                                break;
//                            default:
//                                jsonObject.put("DDH", "");
//                        }
////                        jsonObject.put("DDH", cell.getStringCellValue());
                    }
                }
                switch (cell.getColumnIndex()) {
                    case 3:
                        if (!isddh) {
                            switch (cell.getCellType()) {
                                case STRING:
                                    jsonObject.put("GMFMC", cell.getStringCellValue());
                                    break;
                                case NUMERIC:
                                    jsonObject.put("GMFMC", cell.getNumericCellValue());
                                    break;
                                default:
                                    jsonObject.put("GMFMC", "");
                            }
                        }
                        break;
                    case 4:
                        if (!isddh) {
                            switch (cell.getCellType()) {
                                case STRING:
                                    jsonObject.put("GMFNSRSBH", cell.getStringCellValue());
                                    break;
                                case NUMERIC:
                                    jsonObject.put("GMFNSRSBH", cell.getNumericCellValue());
                                    break;
                                default:
                                    jsonObject.put("GMFNSRSBH", "");
                            }
                        }
                        break;
                    case 5:
                        if (!isddh) {
                            switch (cell.getCellType()) {
                                case STRING:
                                    jsonObject.put("GMFYX", cell.getStringCellValue());
                                    break;
                                case NUMERIC:
                                    jsonObject.put("GMFYX", cell.getNumericCellValue());
                                    break;
                                default:
                                    jsonObject.put("GMFYX", "");
                            }
                        }
                        break;
                    case 6:
                        if (!isddh) {
                            switch (cell.getCellType()) {
                                case STRING:
                                    jsonObject.put("GMFSJ", cell.getStringCellValue());
                                    break;
                                case NUMERIC:
                                    jsonObject.put("GMFSJ", cell.getNumericCellValue());
                                    break;
                                default:
                                    jsonObject.put("GMFSJ", "");
                            }
                        }
                        break;
                    case 17:
                    if (!isddh) {
                        switch (cell.getCellType()) {
                            case STRING:
                                jsonObject.put("BZ", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                jsonObject.put("BZ", cell.getNumericCellValue());
                                break;
                            default:
                                jsonObject.put("BZ", "");
                        }
                    }
                    break;
                    case 2:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("FXHXZ", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("FXHXZ", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("FXHXZ", "");
                        }
                        break;
                    case 7:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("XMMC", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("XMMC", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("XMMC", "");
                        }
                        break;
                    case 8:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("SPBM", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("SPBM", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("SPBM", "");
                        }
                        break;
                    case 9:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("GGXH", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("GGXH", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("GGXH", "");
                        }
                        break;
                    case 10:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("DW", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("DW", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("DW", "");
                        }
                        break;
                    case 11:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("NUM", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("NUM", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("NUM", "");
                        }
                        break;
                    case 12:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("SPDJ", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("SPDJ", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("SPDJ", "");
                        }
                        break;
                    case 13:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("JE", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("JE", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("JE", "");
                        }
                        break;
                    case 14:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("SL", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("SL", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("SL", "");
                        }
                        break;
                    case 15:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("ZKJE", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("ZKJE", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("ZKJE", "");
                        }
                        break;
                    case 16:
                        switch (cell.getCellType()) {
                            case STRING:
                                SP.put("YHZCBS", cell.getStringCellValue());
                                break;
                            case NUMERIC:
                                SP.put("YHZCBS", cell.getNumericCellValue());
                                break;
                            default:
                                SP.put("YHZCBS", "");
                        }
                        break;
                }
            }
            if(StringUtil.isEmpty(jsonObject.getString("DDH"))){
                continue row;
            }
            SPS.add(SP);
            jsonObject.put("SPS", SPS);
            if (num == jsonArray.size()) {
                jsonArray.add(jsonObject);
            } else {
                jsonArray.set(bj, jsonObject);
            }
        }
        // 关闭工作簿
        workbook.close();
        file.close();
        return jsonArray;
    }

    public JSONArray getFileContent(long fileId) throws IOException {
        System.out.println("获取参数附件ID"+fileId);
//        附件路径
        String path = SystemEnvironment.getApplicationFolder()+"/hxinvoiceFile/"+fileId+"/";
        System.out.println("文件下载路径"+path);
        List<Long> fileUrls = getAttachmentManager().getBySubReference(fileId);
        Attachment attachment = getAttachmentManager().getAttachmentByFileURL(fileUrls.get(0));
        String filePath = path+attachment.getFilename();
        JSONArray jsonArray = getFileContent(filePath);
        return jsonArray;
    }


    public static String uploadContractToOA(Object[] fileInfos, String formId, String loginName, String updateAccountName) throws Exception {

        OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
        V3xOrgMember member = orgManager.getMemberByLoginName(loginName);
        V3xOrgAccount account = orgManager.getAccountByName(updateAccountName);
        String refId = String.valueOf(Math.abs(UUID.randomUUID().getLeastSignificantBits()));
        List<Attachment> attachments = new ArrayList<>();
        File tempDir = new File(TEMP_DIR);
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }
        for (Object fileInfo : fileInfos) {
            Map<String, Object> fileInfoMap = (Map<String, Object>) fileInfo;
            String fileName = (String) fileInfoMap.get("fileName");
            String url = (String) fileInfoMap.get("downloadUrl");
            String savePath = TEMP_DIR + File.separator + fileName;
            HttpClient.httpDownloadFile(url, null,savePath,"ITF-8");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            FileUploadExporter fileUpload = new FileUploadExporter();
            File file = new File(savePath);
            if (file.exists() && file.length() <= MAX_FILE_SIZE) {
                String uploadedPath = fileUpload.processUpload(new String[]{file.getAbsolutePath()});
                Map<String, String> attachMeta = new HashMap<>();
                attachMeta.put("type", "0");
                attachMeta.put("fileUrl", uploadedPath);
                attachMeta.put("size", String.valueOf(file.length()));
                attachMeta.put("subReference", refId);
                attachMeta.put("category", CATEGORY_CODE);
                attachMeta.put("createdate", sdf.format(new Date()));
                attachMeta.put("filename", fileName);
                attachMeta.put("reference", formId);
                attachMeta.put("mimeType", "application/" + "pdf");
                attachments.add(new Attachment(attachMeta));
                file.delete();
            }
        }
        if (attachments.isEmpty()) return null;
        AttachmentManager attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager");
        attachmentManager.create(attachments, member.getId(), account.getId());
        return refId;
    }

    private static boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }
}
