package com.qst.dms.ui;

import com.qst.dms.db.DBUtil;
import com.qst.dms.entity.*;
import com.qst.dms.gather.LogRecAnalyse;
import com.qst.dms.gather.TransportAnalyse;
import com.qst.dms.service.LogRecService;
import com.qst.dms.service.TransportService;
import javafx.animation.FadeTransition;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseEvent;
import javafx.util.Duration;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.sql.ResultSet;
import java.util.*;

public class InfoInputFXML {
    // 创建一个泛型ArrayList集合存储日志数据
    ArrayList<LogRec> logRecList = new ArrayList<>();
    // 创建一个泛型ArrayList集合存储物流数据
    ArrayList<Transport> transportList = new ArrayList<>();

    // 创建一个日志业务类
    LogRecService logService = new LogRecService();
    // 创建一个物流业务类
    TransportService tranService = new TransportService();

    // 日志数据匹配集合
    ArrayList<MatchedLogRec> matchedLogs = null;
    // 物流数据匹配集合
    ArrayList<MatchedTransport> matchedTrans = null;

    @FXML
    private TextField logID;

    @FXML
    private TextField logIP;

    @FXML
    private RadioButton logLogin;

    @FXML
    private RadioButton logLogout;

    @FXML
    private TextField logPosition;

    @FXML
    private TextField logUser;

    @FXML
    private TextField transportAddress;

    @FXML
    private TextField transportHandler;

    @FXML
    private TextField transportID;

    @FXML
    private TextField transportReceiver;

    @FXML
    private ChoiceBox<String> transportMode;

    @FXML
    private Label logLabelSuccess;

    @FXML
    private Label transportLabelSuccess;

    @FXML
    private Label logIDError;

    @FXML
    private Label logUserEmpty;

    @FXML
    private Label logAddressEmpty;

    @FXML
    private Label logIPEmpty;

    @FXML
    private Label logStateEmpty;

    @FXML
    private Label transportIDError;

    @FXML
    private Label transportAddressEmpty;

    @FXML
    private Label transportReceiverEmpty;

    @FXML
    private Label transportHandlerEmpty;

    @FXML
    private Label transportStateEmpty;

    @FXML
    private Button collectDataButton;

    @FXML
    private Button matchLogButton;

    @FXML
    private Button matchTransportButton;

    @FXML
    private Button sandDataButton;

    @FXML
    private Button saveDataButton;

    @FXML
    private Button showDataButton;

    @FXML
    private TabPane collectDataPane;

    @FXML
    private Label logInfoLabel;

    @FXML
    private Label transportInfoLabel;
    private Button[] topButtons;
    private String[] photos;
    private TextField[] textFields;
    private Label[] errorLabels;
    private boolean[] textFieldChanged;
    private int logMode;//0未选择 1登录 2登出
    private int transportModeVal;//0未选择 1发货中 2 运货中 3 已送达
    String defaultIP;
    public static String loginUser;
    private MainFrame mainFrame;
    private int logUpVal;
    private int transportUpVal;
    private boolean logIDValid=true,transportIDValid=true;
    private boolean sqlError;
    FadeTransition transportSuccess;
    FadeTransition logSuccess;
    private Thread errorThread;
    private Thread checkerThread;
    private volatile boolean stopRequested = false;
    private Image OKImage;
    private Image errorImage;
    private ImageView logImageView;
    private ImageView transportImageView;

    void SQLErrorAlert()
    {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("错误");
        alert.setHeaderText("连接到sql数据库失败");
        alert.setContentText("当前无法添加信息");
        alert.showAndWait();
    }
    @FXML
    void ConfirmLog(ActionEvent event) {
        if(sqlError)
            SQLErrorAlert();
        boolean canDo=true;
        if(logMode==0)
        {logStateEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        int id=0;
        try
        {
            String Sid = logID.getText();
            if(Sid.isEmpty())
                throw new Exception("ID不能为空");
            if(!logIDValid)
                throw new Exception("ID已被占用");
            id = Integer.parseInt(Sid);
        }
        catch(NumberFormatException e)
        {
            logIDError.setText("请输入纯数字");
            logIDError.setTextFill(Color.color(1,0,0,1));
            canDo=false;
        }
        catch(Exception e)
        {
            logIDError.setText(e.getMessage());
            logIDError.setTextFill(Color.color(1,0,0,1));
            canDo=false;
        }
        String address = logPosition.getText();
        if(address.isEmpty())
        {logAddressEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        String user = logUser.getText();
        if(user==null||user.isEmpty())
        {logUserEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        String ip = logIP.getText();
        if(ip.isEmpty())
        {logIPEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        Date nowDate = new Date();
        int logType = logMode==2?0:1;
        if(!canDo)
            return;
        int type=0;
        LogRec log = new LogRec(id, nowDate, address, type, user, ip, logType);
        logRecList.add(log);
        loginUser = user;
        logUpVal++;
        logMode=0;
        logLogin.setSelected(false);
        logLogout.setSelected(false);
        Thread thread = new Thread(()->{Platform.runLater(()->{
            setLogTextFields();});});
        thread.start();
        logSuccessAnimation();
    }

    @FXML
    void ConfirmTransport(ActionEvent event) {
        if(sqlError)
            SQLErrorAlert();
        boolean canDo = true;
        int id = 0;
        try
        {
            String Sid = transportID.getText();
            if(Sid.isEmpty())
                throw new Exception("ID不能为空");
            if(!transportIDValid)
                throw new Exception("ID已被占用");
            id = Integer.parseInt(Sid);
        }
        catch(NumberFormatException e)
        {
            transportIDError.setText("请输入纯数字");
            transportIDError.setTextFill(Color.color(1,0,0,1));
            canDo=false;
        }
        catch(Exception e)
        {
            transportIDError.setText(e.getMessage());
            transportIDError.setTextFill(Color.color(1,0,0,1));
            canDo=false;
        }
        String transportModeString = transportMode.getValue();
        if(transportModeString==null)
        {
            transportModeVal = 0;
            transportStateEmpty.setTextFill(Color.color(1,0,0,1));
            canDo=false;
        }
        else
            switch(transportModeString)
            {
                case "发货中" ->transportModeVal=1;
                case "运送中" ->transportModeVal=2;
                case "已送达" ->transportModeVal=3;
            }
        String address = transportAddress.getText();
        if(address.isEmpty())
        {transportAddressEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        String handler = transportHandler.getText();
        if(handler.isEmpty())
        {transportHandlerEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        String receiver = transportReceiver.getText();
        if(receiver.isEmpty())
        {transportReceiverEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;}
        if(!canDo)
            return;
        Date nowDate = new Date();
        Transport transport = new Transport(id,nowDate,address,2,handler,receiver,transportModeVal);
        transportList.add(transport);
        transportUpVal++;
        transportModeVal=0;
        transportMode.setValue(null);
        Thread thread = new Thread(()->{Platform.runLater(()->{
            setTransportTextFields();});});
        thread.start();
        transportSuccessAnimation();
    }

    void logIDTest()
    {
        logIDValid=true;
        int logIDValue;
        try
        {
            String s = logID.getText();
            if(s.isEmpty())
                throw new Exception();
            logIDValue = Integer.parseInt(s);
        }
        catch (Exception e)
        {logIDValid=false;return;}
        Thread thread = new Thread(()->
        {
            Platform.runLater(()->{
                DBUtil db = new DBUtil();
                try
                {
                    db.getConnection();
                    String sql = "SELECT id FROM gather_logrec WHERE id = "+ logIDValue;
                    ResultSet resultSet = db.executeQuery(sql,null);
                    if(resultSet.next())
                        logIDValid = false;
                    db.closeAll();
                } catch(Exception e)
                {
                    if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
                    {
                        db.closeAll();
                        errorThread = new Thread(() -> {
                            setSqlError();
                        });
                        errorThread.start();
                    }
                }
            });
        });
        thread.start();
    }
    void updateSQLCheckerTime()
    {
        Thread thread = new Thread(()->{
            stopRequested=true;
            while(checkerThread.isAlive())
            {
                checkerThread.interrupt();
                try
                {
                    Thread.sleep(50);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            stopRequested=false;
            checkerThread = new Thread(()->{
                SQLChecker();
            });
            checkerThread.start();
        });
        thread.start();
    }

    void SQLChecker()
    {
        while (!stopRequested)
        {
            try
            {
                Thread.sleep(UpdateTimeSetFXML.updateTime*1000);
            } catch (InterruptedException e)
            {
                break;
            }
            DBUtil db = new DBUtil();
            try
            {
                db.getConnection();
                String sql = "SELECT * FROM gather_transport";
                db.closeAll();
            } catch(Exception e)
            {
                db.closeAll();
                if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
                {
                    errorThread = new Thread(() -> {
                            setSqlError();
                    });
                    errorThread.start();
                }
                //e.printStackTrace();
            }
        }
    }

    void transportIDTest()
    {
        transportIDValid=true;
        int transportIDValue;
        try
        {
            String s = transportID.getText();
            if(s.isEmpty())
                throw new Exception();
            transportIDValue = Integer.parseInt(s);
        }
        catch (Exception e)
        {transportIDValid=false;return;}
        Thread thread = new Thread(()->
        {
           Platform.runLater(()->{
               DBUtil db = new DBUtil();
               try
               {
                   db.getConnection();
                   String sql = "SELECT id FROM gather_transport WHERE id = "+ transportIDValue;
                   ResultSet resultSet = db.executeQuery(sql,null);
                   if(resultSet.next())
                       transportIDValid=false;
                   db.closeAll();
               } catch(Exception e)
               {
                   db.closeAll();
                   if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
                   {
                       errorThread = new Thread(() -> {
                               setSqlError();
                       });
                       errorThread.start();
                   }
                   //e.printStackTrace();
               }
           });
        });
        thread.start();
    }

    void setSqlError()
    {
        sqlError = true;
        while (true)
        {
            for (int i = 3; i >= 0; i--)
            {
                int finalI = i;
                Platform.runLater(()-> {
                    logInfoLabel.setTextFill(Color.color(1, 0, 0, 1));
                    transportInfoLabel.setTextFill(Color.color(1, 0, 0, 1));
                    logImageView.setImage(errorImage);
                    transportImageView.setImage(errorImage);
                    logInfoLabel.setText("数据库连接异常，将在" + finalI + "秒后重试");
                    transportInfoLabel.setText("数据库连接异常，将在" + finalI + "秒后重试");
                });
                if (i != 0)
                    try
                    {
                        Thread.sleep(1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
            }
            DBUtil db = new DBUtil();
            try
            {
                db.getConnection();
                String sql = "SELECT id FROM gather_transport WHERE id = (SELECT MAX(id) FROM gather_transport)";
                ResultSet resultSet = db.executeQuery(sql,null);
                db.closeAll();
            } catch(Exception e)
            {
                db.closeAll();
                continue;
            }
            break;
        }
        setReady();
    }

    private void setReady()
    {
        Platform.runLater(()->{
            logImageView.setImage(OKImage);
            transportImageView.setImage(OKImage);
            logInfoLabel.setText("就绪");
            transportInfoLabel.setText("就绪");
            logInfoLabel.setTextFill(Color.color(0,0,0,1));
            transportInfoLabel.setTextFill(Color.color(0,0,0,1));
            });
        sqlError=false;
    }
    @FXML
    void LoginSet(ActionEvent event) {
        logLogout.setSelected(false);
        logMode = 1;
        logStateEmpty.setTextFill(Color.color(1,0,0,0));
    }

    @FXML
    void LogoutSet(ActionEvent event) {
        logLogin.setSelected(false);
        logMode = 2;
        logStateEmpty.setTextFill(Color.color(1,0,0,0));
    }

    @FXML
    void RedoALLLog(ActionEvent event) {
        logUser.clear();
        logPosition.clear();
        logIP.clear();
        logID.clear();
    }

    @FXML
    void RedoAllTransport(ActionEvent event) {
        transportID.clear();
        transportAddress.clear();
        transportHandler.clear();
        transportReceiver.clear();
    }

    @FXML
    public void matchedAcquisitionLogData(ActionEvent event) {
        if(logRecList.isEmpty())
        {
            matchedLogs = new ArrayList<>();
            return;
        }
        LogRecAnalyse logAn = new LogRecAnalyse(logRecList);
        logAn.doFilter();
        matchedLogs = logAn.matchData();
    }

    @FXML
    public void matchedAcquisitionTransportData(ActionEvent event){
        if(transportList.isEmpty())
        {
            matchedTrans = new ArrayList<>();
            return;
        }
        TransportAnalyse transAn = new TransportAnalyse(transportList);
        transAn.doFilter();
        matchedTrans = transAn.matchData();
    }

    @FXML
    public void sandData(ActionEvent event) {
        //开发中……
    }

    @FXML
    public void saveData(ActionEvent event) {
        boolean doLog=false,doTransport=false;
        if((matchedLogs==null||matchedLogs.isEmpty())&&!logRecList.isEmpty())
        {
            doLog=true;
            Alert alert = new Alert(AlertType.CONFIRMATION);
            alert.setTitle("Warning Dialog");
            alert.setHeaderText("配对的日志数据为空");
            alert.setContentText("你是否忘记匹配日志数据，要匹配日志数据吗？");
            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK){
                matchedAcquisitionLogData(null);
                if(matchedLogs.isEmpty())
                    doLog=false;
            }
            else doLog=false;
        }
        if(doLog)
        {
            logService.saveAndAppendMatchLog(matchedLogs);
            logService.saveMatchLogToDB(matchedLogs);//添加至DB
            logRecList.clear();
            matchedLogs.clear();
            logUpVal=0;
        }
        if((matchedTrans==null|| matchedTrans.isEmpty())&&!transportList.isEmpty())
        {
            doTransport=true;
            Alert alert = new Alert(AlertType.CONFIRMATION);
            alert.setTitle("Warning Dialog");
            alert.setHeaderText("配对的物流数据为空");
            alert.setContentText("你是否忘记匹配物流数据，要匹配物流数据吗？");
            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK){
                matchedAcquisitionTransportData(null);
                if(matchedTrans.isEmpty())
                    doTransport=false;
            }
            else doTransport=false;
        }
        if(doTransport)
        {
            tranService.saveAndAppendTransport(matchedTrans);
            tranService.saveMatchTransportToDB(matchedTrans);//添加至DB
            transportList.clear();
            matchedTrans.clear();
            transportUpVal=0;
        }
    }

    @FXML
    void toInfoInputFrame(ActionEvent event) {
        ;
    }

    @FXML
    void toTableFrame(ActionEvent event)
    {
        fadeOut(()->{mainFrame.toTableFrame();});
    }

    public void getDelegation(MainFrame _mainFrame)
    {
        mainFrame = _mainFrame;
    }

    void setLogTextFields()
    {
        sqlError = false;
        DBUtil db = new DBUtil();
        int min_id=0;
        try
        {
            db.getConnection();
            String sql = "SELECT id FROM gather_logrec WHERE id = (SELECT MAX(id) FROM gather_logrec)";
            ResultSet resultSet = db.executeQuery(sql,null);
            if(resultSet.next())
            {
                Integer id=(Integer) resultSet.getObject(1);
                min_id = id.intValue()+ logUpVal +1;
            }
            db.closeAll();
        } catch(Exception e)
        {
            db.closeAll();
            if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
            {
                errorThread = new Thread(() -> {
                        setSqlError();
                });
                errorThread.start();
            }
        }
        for(TextField textField:textFields)
            textField.setStyle("-fx-text-fill: #666");
        logUser.setText(loginUser);
        logID.setText(""+min_id);
        logIP.setText(defaultIP);
        Arrays.fill(textFieldChanged,false);
    }

    void setTransportTextFields()
    {
        sqlError = false;
        DBUtil db = new DBUtil();
        int min_id=0;
        try
        {
            db.getConnection();
            String sql = "SELECT id FROM gather_transport WHERE id = (SELECT MAX(id) FROM gather_transport)";
            ResultSet resultSet = db.executeQuery(sql,null);
            if(resultSet.next())
            {
                Integer id=(Integer) resultSet.getObject(1);
                min_id = id.intValue()+ transportUpVal +1;
            }
            db.closeAll();
        } catch(Exception e)
        {
            db.closeAll();
            if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
            {
                errorThread = new Thread(() -> {
                        setSqlError();
                });
                errorThread.start();
            }
        }
        for(TextField textField:textFields)
            textField.setStyle("-fx-text-fill: #666");
        transportID.setText(""+min_id);
        Arrays.fill(textFieldChanged,false);
    }

    @FXML
    void beChanged(KeyEvent event) {
        TextField textField =  (TextField)event.getSource();
        for(int i = 0;i<textFields.length;i++)
            if(textFields[i]==textField)
            {
                if(textFields[i]==logID)
                    logIDTest();
                if(textFields[i]==transportID)
                    transportIDTest();
                textFieldChanged[i]=true;
                errorLabels[i].setTextFill(Color.color(1,0,0,0));
                break;
            }
    }

    @FXML
    public void beClicked(MouseEvent event)
    {
        TextField textField =  (TextField)event.getSource();
        textField.setStyle("-fx-text-fill: black; ");
        textField.selectAll();
    }

    public void initialize()
    {
        sqlError = true;
        checkerThread = new Thread(()->{
            SQLChecker();
        });
        checkerThread.start();
        logUpVal = 0;
        transportUpVal = 0;
        textFieldChanged = new boolean[8];
        Arrays.fill(textFieldChanged,false);
        textFields = new TextField[]{logID,logUser,logPosition,logIP,transportID,transportAddress,transportHandler,transportReceiver};
        errorLabels = new Label[]{logIDError, logUserEmpty, logAddressEmpty, logIPEmpty,transportIDError,transportAddressEmpty,transportHandlerEmpty,transportReceiverEmpty,logStateEmpty,transportStateEmpty};
        topButtons = new Button[]{collectDataButton, matchLogButton, matchTransportButton, saveDataButton, sandDataButton,  showDataButton};
        photos = new String[]{"dataCollection.png","logPair.png","transportPair.png","save.png","upload.png","table.png"};
        logMode = 0;
        transportMode.getItems().addAll("发货中","运送中","已送达");
        setPhotos();
        for(Label label:errorLabels)
            label.setTextFill(Color.color(1,0,0,0));
        logLabelSuccess.setTextFill(Color.color(0,1,0,0));
        transportLabelSuccess.setTextFill(Color.color(0,1,0,0));
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface iface = interfaces.nextElement();
                // 过滤回环接口和虚拟接口
                if (iface.isLoopback() || iface.isVirtual() || !iface.isUp()) {
                    continue;
                }
                Enumeration<InetAddress> addresses = iface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    defaultIP = addresses.nextElement().getHostAddress();
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        OKImage = new Image("resources/ok.png");
        errorImage = new Image("resources/error.png");
        logImageView = new ImageView();
        transportImageView = new ImageView();
        for(ImageView imageView : new ImageView[]{logImageView,transportImageView})
        {
            imageView.setFitHeight(19);
            imageView.setFitWidth(19);
        }
        logImageView.setImage(OKImage);
        transportImageView.setImage(OKImage);
        logInfoLabel.setGraphic(logImageView);
        transportInfoLabel.setGraphic(transportImageView);
        transportMode.setOnAction((event)->{transportStateEmpty.setTextFill(Color.color(1,0,0,0));});
        Thread thread = new Thread(()->{Platform.runLater(()->{
            setLogTextFields();setTransportTextFields();});});
        thread.start();
    }

    void setPhotos()
    {
        for(int i=0;i<topButtons.length;i++)
        {
            Image image = new Image("resources/"+photos[i]);
            ImageView imageView = new ImageView(image);
            imageView.setFitWidth(18);
            imageView.setFitHeight(18);
            topButtons[i].setGraphic(imageView);
        }
    }
    void fadeOut(Runnable action)
    {
        // 创建FadeTransition对象
        FadeTransition fadeOut = new FadeTransition(Duration.seconds(0.5),collectDataPane );
        fadeOut.setFromValue(1); // 初始不透明度为1（完全可见）
        fadeOut.setToValue(0);
        fadeOut.setOnFinished((event)->{
            if (action != null)
                action.run();});
        fadeOut.play();
    }
    void fadeIn(Runnable action)
    {
        // 创建FadeTransition对象
        FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5),collectDataPane );
        fadeIn.setFromValue(0); // 初始不透明度为0（完全透明）
        fadeIn.setToValue(1);
        fadeIn.setOnFinished((event)->{
        if (action != null)
            action.run();});
        fadeIn.play();
    }

    void logSuccessAnimation()
    {
        logLabelSuccess.setTextFill(Color.color(0.26953125,0.66796875,0.26953125,1));
        if(logSuccess!=null)
            logSuccess.stop();
        logSuccess = new FadeTransition(Duration.seconds(1),logLabelSuccess);
        logSuccess.setFromValue(1); // 初始不透明度为1（完全可见）
        logSuccess.setToValue(0);
        logSuccess.setDelay(Duration.seconds(3));
        logSuccess.play();
    }

    void transportSuccessAnimation()
    {
        transportLabelSuccess.setTextFill(Color.color(0.26953125,0.66796875,0.26953125,1));
        if(transportSuccess!=null)
            transportSuccess.stop();
        transportSuccess = new FadeTransition(Duration.seconds(1),transportLabelSuccess);
        transportSuccess.setFromValue(1); // 初始不透明度为1（完全可见）
        transportSuccess.setToValue(0);
        transportSuccess.setDelay(Duration.seconds(3));
        transportSuccess.play();
    }

    public void updateFlushTime(ActionEvent event)
    {
        mainFrame.updateFlushTime();
    }
}
