// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.webcore.packaging;

import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBList;
import com.intellij.util.CatchingConsumer;
import com.intellij.util.ui.JBUI;

import javax.swing.*;
import java.util.List;

public final class ManageRepoDialog extends DialogWrapper {
  private JPanel myMainPanel;
  private final JBList<String> myList;
  private boolean myEnabled;
  private static final Logger LOG = Logger.getInstance(ManageRepoDialog.class);

  public ManageRepoDialog(Project project, final PackageManagementService controller) {
    super(project, false);
    init();
    setTitle(IdeBundle.message("manage.repositories.dialog.title"));
    myList = new JBList<>();
    myList.setPaintBusy(true);
    final DefaultListModel<String> repoModel = new DefaultListModel<>();
    controller.fetchAllRepositories(new CatchingConsumer<>() {
      @Override
      public void consume(List<@NlsSafe String> repoUrls) {
        ApplicationManager.getApplication().invokeLater(() -> {
          if (isDisposed()) return;
          myList.setPaintBusy(false);
          for (@NlsSafe String repoUrl : repoUrls) {
            repoModel.addElement(repoUrl);
          }
        }, ModalityState.any());
      }

      @Override
      public void consume(Exception e) {
        ApplicationManager.getApplication().invokeLater(() -> {
          if (isDisposed()) return;
          myList.setPaintBusy(false);
          LOG.warn(e);
        });
      }
    });
    myList.setModel(repoModel);
    myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    myList.addListSelectionListener(event -> {
      final String selected = myList.getSelectedValue();
      myEnabled = controller.canModifyRepository(selected);
    });

    final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myList).disableUpDownActions();
    decorator.setAddActionName(IdeBundle.message("action.add.repository"));
    decorator.setRemoveActionName(IdeBundle.message("action.remove.repository.from.list"));
    decorator.setEditActionName(IdeBundle.message("action.edit.repository.url"));

    decorator.setAddAction(button -> {
      String url = Messages.showInputDialog(IdeBundle.message("please.input.repository.url"), IdeBundle.message("repository.url.title"), null);
      if (!StringUtil.isEmptyOrSpaces(url) && !repoModel.contains(url)) {
        repoModel.addElement(url);
        controller.addRepository(url);
      }
    });
    decorator.setEditAction(button -> {
      final String oldValue = myList.getSelectedValue();

      String url = Messages.showInputDialog(
        IdeBundle.message("please.edit.repository.url"),
        IdeBundle.message("repository.url.title"),
        null,
        oldValue,
        new InputValidator() {
          @Override
          public boolean checkInput(String inputString) {
            return !repoModel.contains(inputString);
          }

          @Override
          public boolean canClose(String inputString) {
            return true;
          }
        }
      );
      if (!StringUtil.isEmptyOrSpaces(url) && !oldValue.equals(url)) {
        repoModel.addElement(url);
        repoModel.removeElement(oldValue);
        controller.removeRepository(oldValue);
        controller.addRepository(url);
      }
    });
    decorator.setRemoveAction(button -> {
      String selected = myList.getSelectedValue();
      controller.removeRepository(selected);
      repoModel.removeElement(selected);
      button.setEnabled(false);
    });
    decorator.setRemoveActionUpdater(e -> myEnabled);
    decorator.setEditActionUpdater(e -> myEnabled);

    final JPanel panel = decorator.createPanel();
    panel.setPreferredSize(JBUI.size(800, 600));
    myMainPanel.add(panel);

  }

  @Override
  protected JComponent createCenterPanel() {
    return myMainPanel;
  }
}
