package com.jetbrains.edu.coursecreator.actions.placeholder;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.command.undo.BasicUndoableAction;
import com.intellij.openapi.command.undo.UnexpectedUndoException;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.DocumentUtil;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;

public abstract class CCChangePlaceholderVisibility extends CCAnswerPlaceholderAction {

  protected CCChangePlaceholderVisibility(@Nullable String text, @Nullable String description) {
    super(text, description);
  }

  @Override
  protected void performAnswerPlaceholderAction(@NotNull CCState state) {
    AnswerPlaceholder placeholder = state.getAnswerPlaceholder();
    if (placeholder == null) {
      return;
    }
    EduUtils.runUndoableAction(state.getProject(), getName(), new BasicUndoableAction(state.getEditor().getDocument()) {
      @Override
      public void undo() throws UnexpectedUndoException {
        setVisible(placeholder, isVisible(), state);
      }

      @Override
      public void redo() throws UnexpectedUndoException {
        setVisible(placeholder, !isVisible(), state);
      }
    });
  }

  private void setVisible(AnswerPlaceholder placeholder, boolean visible, CCState state) {
    placeholder.getActiveSubtaskInfo().setNeedInsertText(visible);
    int length = isVisible() ? placeholder.getTaskText().length() : 0;
    placeholder.setLength(length);
    saveIndent(placeholder, state, !visible);
    StudyUtils.drawAllAnswerPlaceholders(state.getEditor(), state.getTaskFile());
  }

  private static void saveIndent(AnswerPlaceholder placeholder, CCState state, boolean visible) {
    Document document = state.getEditor().getDocument();
    int offset = placeholder.getOffset();
    int lineNumber = document.getLineNumber(offset);
    int nonSpaceCharOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, lineNumber);
    int newOffset = offset;
    int endOffset = offset + placeholder.getRealLength();
    if (!visible && nonSpaceCharOffset == offset) {
      newOffset = document.getLineStartOffset(lineNumber);
    }
    if (visible) {
      newOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, offset, endOffset);
    }
    placeholder.setOffset(newOffset);
    int delta = offset - newOffset;
    placeholder.setPossibleAnswer(document.getText(TextRange.create(newOffset, newOffset + delta + placeholder.getRealLength())));
  }

  protected abstract String getName();

  protected abstract boolean isVisible();

  @Override
  public void update(AnActionEvent e) {
    Presentation presentation = e.getPresentation();
    presentation.setEnabledAndVisible(false);
    CCState state = getState(e);
    if (state == null) {
      return;
    }
    AnswerPlaceholder placeholder = state.getAnswerPlaceholder();
    if (placeholder == null) {
      return;
    }
    Task task = state.getTaskFile().getTask();
    if (!task.hasSubtasks()) {
      return;
    }
    Integer minSubtaskIndex = Collections.min(placeholder.getSubtaskInfos().keySet());
    if (placeholder.isActive() && minSubtaskIndex != 0 && minSubtaskIndex == task.getActiveSubtaskIndex() && isAvailable(placeholder)) {
      presentation.setEnabledAndVisible(true);
    }
  }

  protected abstract boolean isAvailable(AnswerPlaceholder placeholder);
}

@@ -383,16 +383,66 @@
 tRange;%0A
+import com.intellij.openapi.util.text.StringUtil;%0A
 import c
@@ -468,24 +468,24 @@
 cumentUtil;%0A
-
 import com.j
@@ -1787,24 +1787,70 @@
 t(visible);%0A
+    saveIndent(placeholder, state, !visible);%0A
     int leng
@@ -1947,54 +1947,8 @@
 h);%0A
-    saveIndent(placeholder, state, !visible);%0A
     
@@ -2758,24 +2758,24 @@
  newOffset;%0A
-
     placehol
@@ -2889,24 +2889,308 @@
 ength())));%0A
+    String oldTaskText = placeholder.getTaskText();%0A    if (delta %3E= 0) %7B%0A      placeholder.setTaskText(StringUtil.repeat(%22 %22, delta) + oldTaskText);%0A    %7D%0A    else %7B%0A      String newTaskText = oldTaskText.substring(Math.abs(delta));%0A      placeholder.setTaskText(newTaskText);%0A    %7D%0A
   %7D%0A%0A  prote

save indent for task text