package com.bcxin.file;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.bcxin.file.model.FileLog;
import com.bcxin.file.model.FtpConfig;
import com.bcxin.file.model.ListOption;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Auther linqinglin
 * @date 2022/9/22 17:17
 */
public class gui {

    JPanel jPanel;
    public static void main(String[] args) {
        JFrame frame=new JFrame("文件下载上传-V3.4");
        frame.setMaximizedBounds(new Rectangle(500,300));
        frame.setMinimumSize(new Dimension(500,300));
        frame.setMaximumSize(new Dimension(500,300));
        frame.setLayout(null);

        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.setBounds(0,0,500,300);
        tabbedPane.addTab("文件下载",initOutPane());
        tabbedPane.addTab("上传FTP",initInPane());

        frame.setContentPane(tabbedPane);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static String errorPath;
    private static JPanel initOutPane() {
        JPanel outPanel = new JPanel();
        outPanel.setLayout(null);
        JTextField readPathTxt = new JTextField();
        readPathTxt.setBounds(20, 30, 280, 30);
        readPathTxt.setFocusable(false);
        JTextField zipPathTxt = new JTextField();
        zipPathTxt.setBounds(20, 70, 280, 30);
        zipPathTxt.setFocusable(false);

        JButton readDirBtn = new JButton("选择读取目录");
        JButton saveDirBtn = new JButton("选择保存目录");
        JButton downloadBtn = new JButton("开始下载");

        readDirBtn.setBounds(320, 30, 120, 30);
        saveDirBtn.setBounds(320, 70, 120, 30);
        downloadBtn.setBounds(180, 150, 120, 30);
        outPanel.add(readDirBtn);
        outPanel.add(saveDirBtn);
        outPanel.add(downloadBtn);
        outPanel.add(readPathTxt);
        outPanel.add(zipPathTxt);
        CustomSystemErrorPrintStream errorPrintStream = CustomSystemErrorPrintStream.instance;
        System.setErr(errorPrintStream);

        downloadBtn.setEnabled(false);

        JProgressBar progressBar = new JProgressBar(0, 100);
        progressBar.setBounds(20, 110, 280, 30);
        progressBar.setStringPainted(true);
        outPanel.add(progressBar);

        JCheckBox jCheckBox = new JCheckBox("外网判重", true);
        jCheckBox.setBounds(320, 110, 80, 30);
//        jCheckBox.add();
        outPanel.add(jCheckBox);

        File initPath = new File("C:\\Users\\Administrator\\Desktop");

        readDirBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                JFileChooser fileChooser = new JFileChooser(initPath);
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int flag = fileChooser.showDialog(null, "选择目录");
                if (flag == JFileChooser.APPROVE_OPTION) {
                    readPathTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());

                    if (StrUtil.isNotEmpty(readPathTxt.getText()) && StrUtil.isNotEmpty(zipPathTxt.getText())) {
                        downloadBtn.setEnabled(true);
                        downloadBtn.setText("开始下载");
                    }
                }
            }
        });


        saveDirBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                JFileChooser fileChooser = new JFileChooser(initPath);
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int flag = fileChooser.showDialog(null, "选择目录");
                if (flag == JFileChooser.APPROVE_OPTION) {
                    zipPathTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());

                    if (StrUtil.isNotEmpty(readPathTxt.getText()) && StrUtil.isNotEmpty(zipPathTxt.getText())) {
                        downloadBtn.setEnabled(true);
                        downloadBtn.setText("开始下载");
                    }

                }
            }
        });

        downloadBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                if (!downloadBtn.isEnabled()) {
                    return;
                }
                if (StrUtil.isEmpty(readPathTxt.getText())) {
                    JOptionPane.showMessageDialog(null, "请选择读取目录");
                    return;
                }
                if (StrUtil.isEmpty(zipPathTxt.getText())) {
                    JOptionPane.showMessageDialog(null, "请选择保存目录");
                    return;
                }
                downloadBtn.setText("正在下载..");
                downloadBtn.setEnabled(false);
                downloadBtn.setVisible(false);
                progressBar.setVisible(false);

                String txtPath = readPathTxt.getText();
                String zipPath = zipPathTxt.getText();

                File errorTxtFile = new File(zipPath + "/error.log");
                errorTxtFile.deleteOnExit();

                File[] fileList = new File(txtPath).listFiles();
                if (fileList == null || fileList.length == 0) {
                    downloadBtn.setText("目录下无txt文件");
                    JOptionPane.showMessageDialog(null, "目录下无txt文件");
                    return;
                }

                List<String> allFilePathes = FileUtils.getAllFilePaths(fileList);
                if (allFilePathes == null || allFilePathes.size() < 1) {
                    downloadBtn.setText("没有可下载地址");
                    JOptionPane.showMessageDialog(null, "没有可下载地址");
                    return;
                }

                errorPath = zipPath + "/error.log";
                String processPath = zipPath + "/process.log";
                errorPrintStream.setErrorPath(errorPath);
                for (String filePath : allFilePathes) {
                    outputString(String.format("[开始]读取文件(%s)", filePath), processPath);
                    try {
                        AtomicLong totalCount = new AtomicLong();
                        FileUtils.readFile(filePath, errorPath, pathList -> {
                            List<FileLog> saveLogs = new ArrayList<>();
                            if (pathList != null && pathList.size() > 0) {
                                try {
                                    //根据数据数量情况，切分不同的大小
                                    int limit = 100;
                                    //计算拆分次数
                                    int count = new Double(Math.ceil(pathList.size() * 1.0 / limit)).intValue();
                                    //存放拆分数据
                                    List<String> subList = null;
                                    FileLog fileLog = null;
                                    List<FileLog> logList = null;
                                    //循环拆分次数 生成相应数据文件
                                    for (int i = 0; i < count; i++) {
                                        logList = new ArrayList<>();
                                        subList = pathList.stream().skip(i * limit).limit(limit).collect(Collectors.toList());
                                        for (String s : subList) {
                                            fileLog = new FileLog();
                                            fileLog.setFileUrl(s);
                                            fileLog.setMd5(MD5Util.encryptToMD5(s));
                                            logList.add(fileLog);
                                        }
                                        saveLogs.addAll(logList);
                                    }
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                    throw ex;
                                }
                            }
                            if (saveLogs.size() < 1) {
                                downloadBtn.setText("无可下载文件");
                                return;
                            }

                            totalCount.addAndGet(pathList.size());

                            FileSwingWorker fileSwingWorker = new FileSwingWorker(downloadBtn, saveLogs, zipPath, jCheckBox.isSelected());
                            fileSwingWorker.execute();
                        });
                        outputString(String.format("[完成]读取文件(%s)总数:%s", filePath, totalCount.get()), processPath);
                    } catch (IOException ex) {
                        outputString(String.format("[异常]读取文件(%s)异常:%s", filePath, ex.toString()), processPath);
                    }
                }

                JOptionPane.showMessageDialog(null, "下载完成");
                downloadBtn.setEnabled(true);
                downloadBtn.setVisible(true);
                downloadBtn.setText("开始下载");
            }
        });

        return outPanel;
    }

    private static JPanel initInPane(){
        JPanel inPanel = new JPanel();
        inPanel.setLayout(null);
        JTextField txtFile = new JTextField();
        txtFile.setBounds(20, 30, 280, 30);
        txtFile.setFocusable(false);

        JButton b1 = new JButton("选择文件目录");
        JButton b3 = new JButton("开始上传");

        JComboBox<ListOption> jComboBox = new JComboBox<ListOption>();
        jComboBox.addItem(new ListOption("bj内网ftp", FtpConfig.getBjConfig()));
        jComboBox.addItem(new ListOption("测试内网ftp", FtpConfig.getTestConfig()));
        jComboBox.addItem(new ListOption("本地ftp", FtpConfig.getLocalConfig()));

        b1.setBounds(320, 30, 120, 30);
        jComboBox.setBounds(20, 70, 420, 30);
        b3.setBounds(180, 150, 120, 30);
        inPanel.add(b1);
        inPanel.add(b3);
        inPanel.add(txtFile);

        b3.setEnabled(false);

        JProgressBar progressBar = new JProgressBar(0, 100);
        progressBar.setBounds(20, 110, 420, 30);
        progressBar.setStringPainted(true);

        inPanel.add(jComboBox);
        inPanel.add(progressBar);

        File initPath = new File("C:\\Users\\Administrator\\Desktop");

        b1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                JFileChooser fileChooser = new JFileChooser(initPath);
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int flag = fileChooser.showDialog(null,"选择目录");
                if(flag == JFileChooser.APPROVE_OPTION){
                    if(!fileChooser.getSelectedFile().getAbsolutePath().replaceAll("\\\\","/").contains("/uploads")){
                        JOptionPane.showMessageDialog(null,"目录不含uploads，请确认！");
                        return;
                    }

                    txtFile.setText(fileChooser.getSelectedFile().getAbsolutePath());

                    if(StrUtil.isNotEmpty(txtFile.getText())){
                        b3.setEnabled(true);
                    }
                }
            }
        });

        b3.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                if(!b3.isEnabled()){
                    return;
                }
                if(StrUtil.isEmpty(txtFile.getText())){
                    JOptionPane.showMessageDialog(null,"请选择文件目录");
                    return;
                }

                ListOption listOption = (ListOption) jComboBox.getSelectedItem();

                b3.setText("FTP连接中");
                b3.setEnabled(false);
                FtpSwingWorker ftpSwingWorker = new FtpSwingWorker(b3,listOption.getFtpConfig(),txtFile.getText());
                ftpSwingWorker.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if ("progress".equals(evt.getPropertyName())) {
                            progressBar.setValue((Integer) evt.getNewValue());
                        }
                    }
                });
                ftpSwingWorker.execute();
            }
        });

        return inPanel;
    }

    private static void outputString(String content, String path) {
        try {
            FileUtil.appendLines(Collections.singleton(content), path, "UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static DataBaseUtil _dataBaseUtil;
    private static DataBaseUtil getDataBaseUtil(boolean checkPepeat,JButton jButton) {
        if (_dataBaseUtil == null) {
            if (checkPepeat) {
                try {
                    _dataBaseUtil = new DataBaseUtil();
                } catch (Exception e) {
                    jButton.setEnabled(true);
                    jButton.setText("开始下载");
                    JOptionPane.showMessageDialog(null, "数据库连接异常！！");
                    return null;
                }
            }
        }

        return _dataBaseUtil;
    }
}
