package com.qst.dms.ui;

import com.qst.dms.db.DBUtil;
import com.qst.dms.entity.MatchedLogRec;
import com.qst.dms.entity.MatchedTransport;
import com.qst.dms.entity.Transport;
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.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.util.Duration;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;


public class TableFXML {

    private MainFrame mainFrame;
    private InfoInputFXML infoInputFrame;
    // 创建一个日志业务类
    LogRecService logService = new LogRecService();
    // 创建一个物流业务类
    TransportService tranService = new TransportService();
    // 日志数据匹配集合
    ArrayList<MatchedLogRec> matchedLogs = null;
    // 物流数据匹配集合
    ArrayList<MatchedTransport> matchedTrans = null;

    @FXML
    private TableView<logLine> logTable;

    @FXML
    private TableColumn<logLine, String> logUsername;

    @FXML
    private TableColumn<logLine, String> loginTime;

    @FXML
    private TableColumn<logLine, String> logoutTime;

    @FXML
    private TableColumn<logLine, String> logAddress;

    @FXML
    private TableColumn<transportLine, String> transAddress;

    @FXML
    private TableColumn<transportLine, String> transHandler;

    @FXML
    private TableColumn<transportLine, String> transID;

    @FXML
    private TableColumn<transportLine, String> transReceiver;

    @FXML
    private TableColumn<transportLine, String> transState;

    @FXML
    private TableColumn<transportLine, String>transTime;

    @FXML
    private TableColumn<transportLine, String> transType;

    @FXML
    private TableView<transportLine> transportTable;

    @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 tablePane;

    @FXML
    private Label logSQLLabel;

    @FXML
    private Label transportSQLLabel;

    private Image OKImage;
    private Image errorImage;

    private ImageView logImageView;
    private ImageView transportImageView;

    private Thread errorThread;
    private volatile boolean stopRequested = false;
    private Thread flusherThread;

    public void getDelegation(MainFrame _mainFrame,InfoInputFXML _infoInputFrame)
    {
        mainFrame = _mainFrame;
        infoInputFrame =_infoInputFrame;
    }

    public void setTable()
    {
        try
        {
            matchedLogs = logService.readMatchedLogFromDB();
            matchedTrans = tranService.readMatchedTransportFromDB();
        }
        catch(SQLException e)
        {
            if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED)
            {
                errorThread = new Thread(this::SQLError);
                errorThread.start();
            }
            return;
        }
        logTable.getItems().clear();
        transportTable.getItems().clear();
        for(MatchedLogRec matchedLogRec:matchedLogs)
            logTable.getItems().add(new logLine(matchedLogRec.getUser(),matchedLogRec.getLogInTime().toString(),matchedLogRec.getLogoutTime().toString(),matchedLogRec.getAddress()));
        for(MatchedTransport matchedTransport :matchedTrans)
        {
            Transport[] transports = new Transport[]{ matchedTransport.getSend(), matchedTransport.getTrans(),matchedTransport.getReceive()};
            for(Transport transport:transports)
                transportTable.getItems().add(new transportLine(transport.getId()+"",transport.getAddress(),transport.getHandler(),transport.getReciver(),"已禁用",transport.getTime().toString(),transport.getType()));
        }
    }

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


    @FXML
    void matchedAcquisitionLogData(ActionEvent event) {
        infoInputFrame.matchedAcquisitionLogData(null);
    }

    @FXML
    void matchedAcquisitionTransportData(ActionEvent event) {
        infoInputFrame.matchedAcquisitionTransportData(null);
    }

    @FXML
    void sandData(ActionEvent event) {
        infoInputFrame.sandData(null);
    }

    @FXML
    void saveData(ActionEvent event) {
        infoInputFrame.saveData(null);
    }

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

    @FXML
    void toTableFrame(ActionEvent event) {
        ;
    }

    private Button[] topButtons;
    private String[] photos;

    public void initialize()
    {
        topButtons = new Button[]{collectDataButton, matchLogButton, matchTransportButton, saveDataButton, sandDataButton, showDataButton};
        photos = new String[]{"dataCollection.png","logPair.png","transportPair.png","save.png","upload.png","table.png"};
        setPhotos();
        logUsername.setCellValueFactory(new PropertyValueFactory<logLine,String>("logUsername"));
        loginTime.setCellValueFactory(new PropertyValueFactory<logLine,String>("loginTime"));
        logoutTime.setCellValueFactory(new PropertyValueFactory<logLine,String>("logoutTime"));
        logAddress.setCellValueFactory(new PropertyValueFactory<logLine,String>("logAddress"));
        transID.setCellValueFactory(new PropertyValueFactory<>("transID"));
        transAddress.setCellValueFactory(new PropertyValueFactory<>("transAddress"));
        transHandler.setCellValueFactory(new PropertyValueFactory<>("transHandler"));
        transReceiver.setCellValueFactory(new PropertyValueFactory<>("transReceiver"));
        transState.setCellValueFactory(new PropertyValueFactory<>("transState"));
        transTime.setCellValueFactory(new PropertyValueFactory<>("transTime"));
        transType.setCellValueFactory(new PropertyValueFactory<>("transType"));
        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);
        logSQLLabel.setGraphic(logImageView);
        transportSQLLabel.setGraphic(transportImageView);
        flusherThread = new Thread(()->{flusher();});
        flusherThread.start();
    }

    void updateFlusherTime()
    {
        Thread thread = new Thread(()->{
            stopRequested=true;
            while(flusherThread.isAlive())
            {
                flusherThread.interrupt();
                try
                {
                    Thread.sleep(50);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            stopRequested=false;
            flusherThread = new Thread(()->{
                flusher();
            });
            flusherThread.start();
        });
        thread.start();
    }
    public void flusher()
    {
        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(this::SQLError);
                    errorThread.start();
                }
                //e.printStackTrace();
            }
            setTable();
        }
    }

    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),tablePane );
        fadeOut.setFromValue(1); // 初始不透明度为1（完全可见）
        fadeOut.setToValue(0);   // 目标不透明度为0（完全透明）
        fadeOut.setOnFinished((event)->{
            if (action != null)
                action.run();});
        fadeOut.play();
    }

    void fadeIn(Runnable action)
    {
        // 创建FadeTransition对象
        FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5),tablePane );
        fadeIn.setFromValue(0); // 初始不透明度为1（完全可见）
        fadeIn.setToValue(1);   // 目标不透明度为0（完全透明）
        fadeIn.setOnFinished((event)->{
            if (action != null)
            action.run();});
        fadeIn.play();
    }

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