/**
 *  Copyright © 2021-2025, Luis Andrés Lange <https://javacomm.net>
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Exhibit B - "Incompatible With Secondary Licenses" Notice
 *
 *  This Source Code Form is "Incompatible With Secondary Licenses",
 *  as defined by the Mozilla Public License, v. 2.0.
 *
 *  In short:
 *  - This file may be used, modified, and distributed under MPL 2.0 only.
 *  - It may NOT be relicensed under GPL, LGPL, AGPL, or any other Secondary License.
 *
 *  Rationale:
 *  - Ensures that the code remains MPL-2.0.
 *  - Avoids legal conflicts with GPL-licensed libraries (e.g., VideoLAN).
 *  - Maximizes usability for commercial and security-critical applications.
 *
 */
package net.javacomm.client.administer;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Enumeration;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nexuswob.gui.InputDocument;
import org.nexuswob.util.Util;
import net.javacomm.client.environment.GUI;
import net.javacomm.client.gui.MultilingualServiceButton;
import net.javacomm.multilingual.Babelfish;
import net.javacomm.multilingual.MultilingualButton;
import net.javacomm.multilingual.MultilingualLabel;
import net.javacomm.multilingual.MultilingualString;
import net.javacomm.multilingual.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.share.Constants;
import net.javacomm.window.manager.Control;



@SuppressWarnings("serial")
public class JChatfilter extends JPanel implements Babelfish {

  private final static Logger log = LogManager.getLogger(JChatfilter.class);

  private GridBagLayout gridbag = new GridBagLayout();
  private GridBagConstraints con = new GridBagConstraints();

  private MultilingualLabel labelEinleitung = new MultilingualLabel(KEY.LABEL_EIN_CHATFILTER_SCHLAEGT);
  private MultilingualLabel labelFilter = new MultilingualLabel(KEY.STRING_RAUMFILTER);
  private DefaultListModel<String> model = new DefaultListModel<>();
  private JList<String> listFilter = new JList<>(model);
  private JScrollPane scrollpane = new JScrollPane();
  private JSeparator separator = new JSeparator();
  private MultilingualButton buttonSchliessen = new MultilingualButton(KEY.BUTTON_SCHLIESSEN);
  private GridLayout grid = new GridLayout(1, 2, 12, 12);
  private JPanel buttonpane = new JPanel(grid);

  private JPanel buttonVerwalten = new JPanel();
  private GridLayout gridVerwalten = new GridLayout(2, 1, 0, 12);
  private MultilingualButton buttonAdd = new MultilingualButton(KEY.BUTTON_FILTER_HINZUFUEGEN);
  private MultilingualButton buttonRemove = new MultilingualButton(KEY.BUTTON_FILTER_ENTFERNEN);
  private ActionListener addActionListener;
  private ActionListener removeActionListener;

  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private String neuerFilter;
  private List<String> removeValues;
  private MultilingualString raumfilterVorhanden = new MultilingualString(KEY.STRING_RAUMFILTER_VORHANDEN);
  private MultilingualString raumfilter = new MultilingualString(KEY.STRING_ROOM_FILTER);
  private MultilingualString neuerfilter = new MultilingualString(KEY.STRING_NEUER_RAUMFILTER);
  private MultilingualServiceButton serviceButton = new MultilingualServiceButton(
      KEY.BUTTON_SPEICHERN, KEY.BUTTON_ABBRECHEN
  );
  JDialog dialog;

  private final int margin_top = 12;
  private final int margin_left = 12;
  private final int margin_right = 12;

  public JChatfilter() {
    setLayout(gridbag);

    con.gridx = 0;
    con.gridy = 0;
    con.gridwidth = 2;
    con.gridheight = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.weightx = 0.0;
    con.weighty = 0.0;
    con.insets = new Insets(margin_top, margin_left, 0, margin_right);
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(labelEinleitung, con);
    add(labelEinleitung);

    con.gridx = 0;
    con.gridy = 1;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.NONE;
    con.weightx = 0.0;
    con.weighty = 0.0;
    con.insets = new Insets(margin_top, margin_left, 0, margin_right);
    con.anchor = GridBagConstraints.CENTER;
    gridbag.setConstraints(labelFilter, con);
    add(labelFilter);
    labelFilter.setFont(GUI.semiFont15);

    con.gridx = 0;
    con.gridy = 2;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.BOTH;
    con.weightx = 1.0;
    con.weighty = 1.0;
    con.insets = new Insets(0, margin_left, 0, 0);
    con.anchor = GridBagConstraints.CENTER;
    gridbag.setConstraints(scrollpane, con);
    add(scrollpane);
    scrollpane.setViewportView(listFilter);
    scrollpane.getHorizontalScrollBar().setUnitIncrement(12);
    scrollpane.getVerticalScrollBar().setUnitIncrement(12);
    listFilter.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    con.gridx = 1;
    con.gridy = 2;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.NONE;
    con.weightx = 0.0;
    con.weighty = 0.0;
    con.insets = new Insets(0, 12, 0, 12);
    con.anchor = GridBagConstraints.CENTER;
    gridbag.setConstraints(buttonVerwalten, con);
    add(buttonVerwalten);
    buttonVerwalten.setLayout(gridVerwalten);
    buttonVerwalten.add(buttonAdd);
    buttonVerwalten.add(buttonRemove);
    addActionListener = new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {

        // mehrsprachig
        final String ABBRECHEN = serviceButton.getButton_2_Text();

        Object[] options = new Object[] {"OK", ABBRECHEN};
        JOptionPane pane = new JOptionPane(
            neuerfilter.toString(), JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, options
        );
        pane.setWantsInput(true);
        InputDocument document = new InputDocument(Constants.LEN_ROOMFILTER);

        final JTextField[] inputField = new JTextField[1];

        List<Component> result = Util.getAllComponents(pane);
        result.forEach(component -> {
          if (component instanceof JTextField textfield) {
            inputField[0] = textfield;
            textfield.setDocument(document);
            textfield.getInputMap(JComponent.WHEN_FOCUSED)
                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
            textfield.getActionMap().put("ENTER", new AbstractAction() {
              @Override
              public void actionPerformed(ActionEvent event) {
                dialog.dispose();
              }
            });

          }
        });

        dialog = pane.createDialog(JChatfilter.this, raumfilter.toString().toString());
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        dialog.setAlwaysOnTop(true);
        dialog.setModal(true);
        dialog.pack();
        dialog.setVisible(true);
        if (inputField[0] == null) return;
        String item = inputField[0].getText();
        if (item == null || item.isEmpty()) return;

        Object input = pane.getValue();
        if (input == null) return;
        if (input.equals(ABBRECHEN)) return;

        if (model.contains(item)) {
          JOptionPane.showMessageDialog(
              JChatfilter.this, raumfilterVorhanden.toString().replace("XXX", item), raumfilter.toString(),
              JOptionPane.INFORMATION_MESSAGE
          );
        }

        // Rückmeldung Filter schon vorhanden
        neuerFilter = new String(item);
        changes.firePropertyChange(JChatfilter.class.getName(), Control.NULL, Control.ADD);

      }
    };
    buttonAdd.addActionListener(addActionListener);

    removeActionListener = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        removeValues = listFilter.getSelectedValuesList();
        changes.firePropertyChange(JChatfilter.class.getName(), Control.NULL, Control.REMOVE);
      }
    };
    buttonRemove.addActionListener(removeActionListener);

    con.gridx = 0;
    con.gridy = 3;
    con.gridwidth = 2;
    con.gridheight = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.weightx = 0.0;
    con.weighty = 0.0;
    con.insets = new Insets(24, margin_left, 0, margin_right);
    con.anchor = GridBagConstraints.CENTER;
    gridbag.setConstraints(separator, con);
    add(separator);

    buttonpane.add(buttonSchliessen);
    con.gridx = 1;
    con.gridy = 4;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.NONE;
    con.weightx = 0.0;
    con.weighty = 0.0;
    con.insets = new Insets(12, margin_left, 12, margin_right);
    con.anchor = GridBagConstraints.EAST;
    gridbag.setConstraints(buttonpane, con);
    add(buttonpane);

    buttonSchliessen.addActionListener(event -> {
      changes.firePropertyChange(JChatfilter.class.getName(), Control.NULL, Control.CLOSE);
    });

  }



  public void addRaumfilterListener(PropertyChangeListener l) {
    changes.addPropertyChangeListener(l);
  }



  /**
   * Deregisters the filters selected by the user.
   *
   * @return the list of deregistered filters
   */
  List<String> deregisterFilter() {
    return removeValues;
  }



  /**
   * Gibt die aktuelle Filterliste zurück.
   * 
   * @return alle Filternamen
   */
  public Enumeration<String> getFilterliste() {
    return model.elements();
  }



  /**
   * Registers this room filter.
   * 
   * @return the registered filter
   */
  String registerFilter() {
    return neuerFilter;
  }



  public void removeAllListener() {
    for (PropertyChangeListener listener : changes.getPropertyChangeListeners()) {
      removeRaumfilterListener(listener);
    }
    buttonAdd.removeActionListener(addActionListener);
    buttonRemove.removeActionListener(removeActionListener);
  }



  public void removeRaumfilterListener(PropertyChangeListener l) {
    changes.removePropertyChangeListener(l);
  }



  void setFilterliste(List<String> value) {
    model.clear();
    model.addAll(value);
  }



  @Override
  public void setLanguage(ISO639 code) {
    labelEinleitung.setLanguage(code);
    buttonSchliessen.setLanguage(code);
    buttonAdd.setLanguage(code);
    buttonRemove.setLanguage(code);
    raumfilterVorhanden.setLanguage(code);
    raumfilter.setLanguage(code);
    neuerfilter.setLanguage(code);
    labelFilter.setLanguage(code);
    serviceButton.setLanguage(code);
  }

}
