/*
 * Created by JFormDesigner on Tue Oct 08 20:59:17 EDT 2024
 */

package tech.nevets.tvpn.ui;

import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;

import net.miginfocom.swing.*;
import tech.nevets.tvpn.Logger;
import tech.nevets.tvpn.Utils;
import tech.nevets.tvpn.wg.WireGuardHandler;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

/**
 * @author steven
 */
public class HomePanel extends JPanel {
    private static final Logger LOGGER = new Logger(HomePanel.class);

    public HomePanel() {
        initComponents();
        createTunnelsUI(WireGuardHandler.getTunnelConfigs());
        updateActiveTunnels();
    }

    public void createTunnelsUI(List<String> tunnels) {
        // Clear the list model first in case we're refreshing
        listModel.clear();

        // Add each tunnel string to the list model, which updates the JList
        for (String s : tunnels) {
            listModel.addElement("◦ " + s.substring(0, s.length() - 11));
        }
    }

    private void updateActiveTunnels() {
        String tunnelName;
        if (WireGuardHandler.isActiveTunnel()) {
            tunnelName = WireGuardHandler.getActiveTunnels().getFirst();
        } else {
            tunnelName = "";
        }
        for (int i = 0; i < listModel.size(); i++) {
            String s = listModel.get(i).replace("◦", "").replace("•", "").trim();
            String newStr;
            if (s.equals(tunnelName)) {
                newStr = "• " + s;
            } else {
                newStr = "◦ " + s;
            }
            listModel.set(i, newStr);
        }
        tunnelList.updateUI();
    }

    private String getSelectedTunnel() {
        return tunnelList.getSelectedValue().replace("•", "").replace("◦", "").trim();
    }

    private void loadTunnel(String tunnelName) {
        List<String> tunnels = WireGuardHandler.getActiveTunnels();
        if (tunnels.size() > 1) { //TODO implement this logic
            System.out.println("Too many tunnels active, logic not implemented yet.");
            return;
        }
        if (WireGuardHandler.isActiveTunnel()) {
            String tunnel = tunnels.getFirst();
            WireGuardHandler.stopTunnel(tunnel);
        }
        WireGuardHandler.startTunnel(tunnelName);
        updateActiveTunnels();
    }

    public void updateUserInfo(String username, String email) {
        userLabel.setText(username);
        emailLabel.setText(email);
    }

    private void loadBtn(ActionEvent e) {
        loadTunnel(getSelectedTunnel());
    }

    private void showConfigBtn(ActionEvent e) {
        List<String> activeTunnels = WireGuardHandler.getActiveTunnels();
        if (activeTunnels.size() > 1) { //TODO implement this logic
            System.out.println("Too many tunnels active, logic not implemented yet.");
            return;
        }
        String originalTunnel = activeTunnels.getFirst();
        if (originalTunnel.equals(getSelectedTunnel())) {
            try {
                String tunnelConfig = Files.readString(Path.of(Utils.APP_DIR + "/" + getSelectedTunnel() + ".conf"));
                configArea.setText(tunnelConfig);
            } catch (IOException ex) {
                LOGGER.error(ex.getMessage());
            }
            return;
        }
        loadTunnel(getSelectedTunnel());
        WireGuardHandler.getActiveConfig(getSelectedTunnel());
        try {
            String tunnelConfig = Files.readString(Path.of(Utils.APP_DIR + "/" + getSelectedTunnel() + ".conf"));
            configArea.setText(tunnelConfig);
        } catch (IOException ex) {
            LOGGER.error(ex.getMessage());
        }
        loadTunnel(originalTunnel);
    }

    private void stopTunnelBtn(ActionEvent e) {
        List<String> tunnels = WireGuardHandler.getActiveTunnels();
        for (String tunnel : tunnels) {
            WireGuardHandler.stopTunnel(tunnel);
        }
        updateActiveTunnels();
    }

    private void importBtn(ActionEvent e) {
        JFileChooser fileChooser = new JFileChooser(System.getenv("HOME"));
        fileChooser.setFileFilter(new FileNameExtensionFilter("WireGuard Config", "conf"));
        fileChooser.showOpenDialog(null);
        File f = fileChooser.getSelectedFile();
        if (f == null) return;
        try {
            WireGuardHandler.loadTunnel(Path.of(f.getAbsolutePath()));
        } catch (IOException ex) {
            LOGGER.error(ex.getMessage());
        }
        listModel.addElement("◦ " + f.getName().replace(".conf", ""));
    }

    private void exceptionBtn(ActionEvent e) {
        try {
            Utils.throwException();
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
        }
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents  @formatter:off
        tunnelsLabel = new JLabel();
        userLabel = new JLabel();
        tunnelScrollPane = new JScrollPane();
        listModel = new DefaultListModel<>();
        tunnelList = new JList<>(listModel);
        emailLabel = new JLabel();
        configScrollPane = new JScrollPane();
        configArea = new JTextArea();
        showConfigBtn = new JButton();
        importBtn = new JButton();
        startTunnelBtn = new JButton();
        exceptionBtn = new JButton();
        stopTunnelBtn = new JButton();

        //======== this ========
        setLayout(new MigLayout(
            "hidemode 3",
            // columns
            "[fill]" +
            "[fill]" +
            "[grow,fill]" +
            "[fill]",
            // rows
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]" +
            "[]"));

        //---- tunnelsLabel ----
        tunnelsLabel.setText("Tunnels");
        add(tunnelsLabel, "cell 0 0 2 1");

        //---- userLabel ----
        userLabel.setText("Guest");
        add(userLabel, "cell 3 0");

        //======== tunnelScrollPane ========
        {
            tunnelScrollPane.setViewportView(tunnelList);
        }
        add(tunnelScrollPane, "cell 0 1 2 8,growy");

        //---- emailLabel ----
        emailLabel.setText("guest@tvpn.lan");
        add(emailLabel, "cell 3 1");

        //======== configScrollPane ========
        {
            configScrollPane.setViewportView(configArea);
        }
        add(configScrollPane, "cell 2 3 2 6,growy");

        //---- showConfigBtn ----
        showConfigBtn.setText("Show Config");
        showConfigBtn.addActionListener(e -> showConfigBtn(e));
        add(showConfigBtn, "cell 0 9 2 1");

        //---- importBtn ----
        importBtn.setText("Import Tunnel");
        importBtn.addActionListener(e -> importBtn(e));
        add(importBtn, "cell 3 9");

        //---- startTunnelBtn ----
        startTunnelBtn.setText("Start Tunnel");
        startTunnelBtn.addActionListener(e -> loadBtn(e));
        add(startTunnelBtn, "cell 0 10 2 1");

        //---- exceptionBtn ----
        exceptionBtn.setText("Exceptional");
        exceptionBtn.addActionListener(e -> exceptionBtn(e));
        add(exceptionBtn, "cell 3 10");

        //---- stopTunnelBtn ----
        stopTunnelBtn.setText("Stop Tunnel");
        stopTunnelBtn.addActionListener(e -> stopTunnelBtn(e));
        add(stopTunnelBtn, "cell 0 11 2 1");
        // JFormDesigner - End of component initialization  //GEN-END:initComponents  @formatter:on
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables  @formatter:off
    private JLabel tunnelsLabel;
    private JLabel userLabel;
    private JScrollPane tunnelScrollPane;
    private JList<String> tunnelList;
    private JLabel emailLabel;
    private JScrollPane configScrollPane;
    private JTextArea configArea;
    private JButton showConfigBtn;
    private JButton importBtn;
    private JButton startTunnelBtn;
    private JButton exceptionBtn;
    private JButton stopTunnelBtn;
    // JFormDesigner - End of variables declaration  //GEN-END:variables  @formatter:on

    private DefaultListModel<String> listModel;
}
