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

import com.intellij.internal.statistic.eventLog.events.EventPair;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.ui.StateRestoringCheckBox;

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

import static com.intellij.find.findUsages.JavaFindUsagesCollector.*;

public class FindClassUsagesDialog extends JavaFindUsagesDialog<JavaClassFindUsagesOptions> {
  private StateRestoringCheckBox myCbUsages;
  private StateRestoringCheckBox myCbConstructorUsages;
  private StateRestoringCheckBox myCbMethodsUsages;
  private StateRestoringCheckBox myCbFieldsUsages;
  private StateRestoringCheckBox myCbImplementingClasses;
  private StateRestoringCheckBox myCbDerivedInterfaces;
  private StateRestoringCheckBox myCbDerivedClasses;

  public FindClassUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, 
                               boolean mustOpenInNewTab, boolean isSingleFile, FindUsagesHandler handler){
    super(element, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
  }

  @Override
  public JComponent getPreferredFocusedControl() {
    return myCbUsages;
  }

  @Override
  public void calcFindUsagesOptions(JavaClassFindUsagesOptions options) {
    super.calcFindUsagesOptions(options);

    if (isToChange(myCbUsages)) {
      options.isUsages = isSelected(myCbUsages);
    }
    if (isToChange(myCbConstructorUsages)) {
      options.isConstructorUsages = isSelected(myCbConstructorUsages);
    }
    if (isToChange(myCbMethodsUsages)) {
      options.isMethodsUsages = isSelected(myCbMethodsUsages);
    }
    if (isToChange(myCbFieldsUsages)) {
      options.isFieldsUsages = isSelected(myCbFieldsUsages);
    }
    if (isToChange(myCbDerivedClasses)) {
      options.isDerivedClasses = isSelected(myCbDerivedClasses);
    }
    if (isToChange(myCbImplementingClasses)) {
      options.isImplementingClasses = isSelected(myCbImplementingClasses);
    }
    if (isToChange(myCbDerivedInterfaces)) {
      options.isDerivedInterfaces = isSelected(myCbDerivedInterfaces);
    }
    options.isSkipImportStatements = false;
    options.isCheckDeepInheritance = true;
    options.isIncludeInherited = false;

    FIND_CLASS_STARTED.log(myPsiElement.getProject(), createFeatureUsageData(options));
  }

  @Override
  protected List<EventPair<?>> createFeatureUsageData(JavaClassFindUsagesOptions options) {
    List<EventPair<?>> data = super.createFeatureUsageData(options);
    data.add(CONSTRUCTOR_USAGES.with(options.isConstructorUsages));
    data.add(METHOD_USAGES.with(options.isMethodsUsages));
    data.add(FIELD_USAGES.with(options.isFieldsUsages));
    data.add(DERIVED_USAGES.with(options.isDerivedClasses));
    data.add(IMPLEMENTING_CLASSES.with(options.isImplementingClasses));
    data.add(DERIVED_INTERFACES.with(options.isDerivedInterfaces));
    return data;
  }

  @Override
  protected JPanel createFindWhatPanel() {
    JPanel findWhatPanel = new JPanel();
    findWhatPanel.setLayout(new BoxLayout(findWhatPanel, BoxLayout.Y_AXIS));

    myCbUsages = addCheckboxToPanel(JavaBundle.message("find.what.usages.checkbox"), getFindUsagesOptions().isUsages, findWhatPanel, true);

    PsiClass psiClass = (PsiClass)getPsiElement();
    if (!psiClass.isInterface()) {
      myCbConstructorUsages = addCheckboxToPanel(JavaBundle.message("find.what.constructor.usages.checkbox"), getFindUsagesOptions().isConstructorUsages, findWhatPanel, true);
    }
    myCbMethodsUsages = addCheckboxToPanel(JavaBundle.message("find.what.methods.usages.checkbox"), getFindUsagesOptions().isMethodsUsages, findWhatPanel, true);

    if (!psiClass.isAnnotationType()) {
      myCbFieldsUsages = addCheckboxToPanel(JavaBundle.message("find.what.fields.usages.checkbox"), getFindUsagesOptions().isFieldsUsages, findWhatPanel, true);
      if (psiClass.isInterface()){
        myCbImplementingClasses = addCheckboxToPanel(JavaBundle.message("find.what.implementing.classes.checkbox"), getFindUsagesOptions().isImplementingClasses, findWhatPanel, true);
        myCbDerivedInterfaces = addCheckboxToPanel(JavaBundle.message("find.what.derived.interfaces.checkbox"), getFindUsagesOptions().isDerivedInterfaces, findWhatPanel, true);
      }
      else if (!psiClass.hasModifierProperty(PsiModifier.FINAL)){
        myCbDerivedClasses = addCheckboxToPanel(JavaBundle.message("find.what.derived.classes.checkbox"), getFindUsagesOptions().isDerivedClasses, findWhatPanel, true);
      }
    }
    return findWhatPanel;
  }

  @Override
  protected void update() {
    if(myCbToSearchForTextOccurrences != null){
      updateStateOnUsagesStateChange(myCbToSearchForTextOccurrences);
    }

    boolean hasSelected = isSelected(myCbUsages) ||
                          isSelected(myCbConstructorUsages) ||
                          isSelected(myCbMethodsUsages) ||
                          isSelected(myCbFieldsUsages) ||
                          isSelected(myCbDerivedClasses) ||
                          isSelected(myCbImplementingClasses) ||
                          isSelected(myCbDerivedInterfaces);
    setOKActionEnabled(hasSelected);
  }

  protected void updateStateOnUsagesStateChange(StateRestoringCheckBox dependantCb) {
    if (isSelected(myCbUsages)){
      dependantCb.makeSelectable();
    }
    else{
      dependantCb.makeUnselectable(false);
    }
  }
}