package fucoin.gui;

import fucoin.supervisor.SuperVisorImpl;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
    private SuperVisorImpl superVisor;
    private JFrame frame;

    private FilteredLogModel log = new FilteredLogModel();
    private JList<LogMessage> txtLog = new JList<>(log);
    private JScrollPane logPane = new JScrollPane(txtLog);
    private JCheckBox showDebug;

    public SuperVisorGuiControlImpl(SuperVisorImpl sv) {
        superVisor = sv;
        init();
    }

    private void init() {
        //Show AWT window for runtime information
        frame = new JFrame("Server");
        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new GridLayout(2, 1));

        //Init Amount Table and SuperVisorImpl

        JTable amountListView = new JTable(superVisor.getAmountTableModel());
        contentPanel.add(new JScrollPane(amountListView));

        JPanel logPanel = new JPanel(new BorderLayout());

        txtLog.setCellRenderer(new LogCellRenderer());

        showDebug = new JCheckBox("Show debug messages in transaction log");
        showDebug.setSelected(true);
        showDebug.addItemListener(e -> {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                log.clearFilter();
            } else {
                log.setTransactionFilter();
            }
        });

        logPanel.add(showDebug, BorderLayout.NORTH);
        logPanel.add(logPane, BorderLayout.CENTER);
        contentPanel.add(logPanel);

        frame.add(contentPanel, BorderLayout.CENTER);

        //Exit Button and shutdown supervisor
        JButton exitBtn = new JButton("Stop Supervisor");
        exitBtn.addActionListener(e -> {
            superVisor.exit();
            frame.setVisible(false);
            frame.dispose();
        });
        frame.add(exitBtn, BorderLayout.PAGE_END);
        frame.setSize(800, 600);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                superVisor.exit();
            }
        });
    }

    @Override
    public void onLeave() {
        frame.dispose();
    }

    private void log(LogMessage logMessage) {
        SwingUtilities.invokeLater(() -> {
            log.addElement(logMessage);

            // auto scroll to the bottom
            txtLog.ensureIndexIsVisible(log.getSize() - 1);
        });
    }

    @Override
    public void addLogMsg(String msg) {
        log(new LogMessage(msg));
    }

    @Override
    public void addTransactionLogMessageSuccess(String message) {
        log(new LogMessage(message, LogMessage.Context.TRANSACTION_SUCCESS));
    }

    @Override
    public void addTransactionLogMessageFail(String message) {
        log(new LogMessage(message, LogMessage.Context.TRANSACTION_FAIL));
    }
}