package com.airlock.iam.plugin.configeditor.ui.panel;

import com.airlock.iam.configeditor.shared.application.ConfigEditorProperties;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.configeditor.data.ConfigEditorState;
import com.airlock.iam.plugin.configeditor.data.EnvironmentSelection;
import com.airlock.iam.plugin.configeditor.data.EnvironmentSpecificPropertyBean;
import com.airlock.iam.plugin.configeditor.data.ErrorBean;
import com.airlock.iam.plugin.configeditor.util.GuiResources;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.Component;
import com.vaadin.ui.TabSheet;
import java.util.Set;

public final class PanelsTabSheet {
   private final TabSheet tabSheet = new TabSheet();
   private final SearchPanel searchPanel = new SearchPanel();
   private final PanelsTabSheet.GlobalErrorDataSource errorDataSource;
   private final ErrorPanel errorPanel;
   private final EnvironmentSelection environmentSelection;
   private final EnvironmentValuesPanel environmentValuesPanel;
   private final ConfigurationVariablesPanel variablesPanel;
   private final DocsPanel docsPanel;

   public PanelsTabSheet(
      ConfigEditorState state,
      SelectionListener<ErrorBean> errorSelected,
      SelectionListener<EnvironmentSpecificPropertyBean> environmentSpecificPropertySelected
   ) {
      this.errorDataSource = new PanelsTabSheet.GlobalErrorDataSource(state);
      this.errorPanel = new ErrorPanel(this.errorDataSource, errorSelected);
      this.environmentSelection = state.getEnvironmentSelection();
      this.environmentValuesPanel = new EnvironmentValuesPanel(state::getEnvironmentSpecificProperties, environmentSpecificPropertySelected);
      this.variablesPanel = new ConfigurationVariablesPanel(state::getAllPluginConfigurations, () -> state.getEnvironmentSelection().isEnabled());
      this.docsPanel = new DocsPanel(state::getDocsText);
      this.buildTabSheet();
   }

   private void buildTabSheet() {
      this.tabSheet.setSizeFull();
      this.tabSheet.addStyleName("framed");
      this.tabSheet.setId("tabsheet");
      this.tabSheet.addSelectedTabChangeListener(event -> this.updateSelectedTab());
      this.tabSheet.addTab(this.searchPanel.getContent(), "Search", GuiResources.ICON_SEARCH).setId("searchTabSelector");
      this.tabSheet.addTab(this.errorPanel.getContent(), "Errors", GuiResources.ICON_VALIDATION_DISABLED).setId("errorsTabSelector");
      if (ConfigEditorProperties.configEditorProperties().isShowVariables()) {
         this.tabSheet.addTab(this.variablesPanel.getContent(), "Variables", GuiResources.ICON_SHOW_VARIABLE).setId("variablesTabSelector");
      }

      this.tabSheet.addTab(this.docsPanel.getContent(), "Docs", GuiResources.ICON_INFO).setId("docsTabSelector");
   }

   private void updateSelectedTab() {
      this.getSelectedPanelContainer().update();
   }

   public Component getContent() {
      return this.tabSheet;
   }

   public void selectDocsPanel() {
      this.selectPanel(this.docsPanel);
   }

   public void selectErrorPanel() {
      this.selectPanel(this.errorPanel);
   }

   private void selectPanel(PanelContainer panel) {
      this.tabSheet.setSelectedTab(panel.getContent());
   }

   public void updateSearchPanel() {
      this.updatePanel(this.searchPanel);
   }

   public void updateVariablesPanel() {
      this.updatePanel(this.variablesPanel);
   }

   public void updateErrorPanel() {
      this.tabSheet.getTab(this.errorPanel.getContent()).setIcon(this.errorPanelIcon());
      this.updatePanel(this.errorPanel);
   }

   private ThemeResource errorPanelIcon() {
      if (!this.errorDataSource.isValidationEnabled()) {
         return GuiResources.ICON_VALIDATION_DISABLED;
      } else {
         return this.errorDataSource.getErrors().isEmpty() ? GuiResources.ICON_VALIDATION_OK : GuiResources.ICON_VALIDATION_ERROR;
      }
   }

   public void updateConfigurationEnvironment() {
      if (this.environmentSelection.getSelectedEnvironment().isCommonEnvironment()) {
         this.tabSheet.removeComponent(this.environmentValuesPanel.getContent());
      } else {
         this.tabSheet
            .addTab(this.environmentValuesPanel.getContent(), "Env Properties", GuiResources.ICON_ENVIRONMENT_PROPERTIES, 2)
            .setId("envPropertiesTabSelector");
      }

      this.updateSearchPanel();
      this.updateEnvironmentValuesPanel();
   }

   public void updateEnvironmentValuesPanel() {
      this.updatePanel(this.environmentValuesPanel);
   }

   public void updateDocsPanel() {
      this.updatePanel(this.docsPanel);
   }

   private void updatePanel(PanelContainer panel) {
      if (this.getSelectedPanelContainer() == panel) {
         panel.update();
      }
   }

   private PanelContainer getSelectedPanelContainer() {
      Component selectedTab = this.tabSheet.getSelectedTab();
      if (selectedTab == this.searchPanel.getContent()) {
         return this.searchPanel;
      } else if (selectedTab == this.errorPanel.getContent()) {
         return this.errorPanel;
      } else if (selectedTab == this.environmentValuesPanel.getContent()) {
         return this.environmentValuesPanel;
      } else if (selectedTab == this.docsPanel.getContent()) {
         return this.docsPanel;
      } else if (selectedTab == this.variablesPanel.getContent()) {
         return this.variablesPanel;
      } else {
         throw new IllegalStateException("Invalid selected tab: " + selectedTab);
      }
   }

   private static class GlobalErrorDataSource implements ErrorDataSource {
      private final ConfigEditorState state;

      public GlobalErrorDataSource(ConfigEditorState state) {
         this.state = state;
      }

      @Override
      public boolean isValidationEnabled() {
         return this.state.isValidationEnabled();
      }

      @Override
      public Set<ConfigurationException> getErrors() {
         return this.state.getGlobalErrors();
      }
   }
}
