package io.delphi.qa.auto.awsmfrw.managers;

import com.atlassian.httpclient.api.ResponseTransformationException;
import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.domain.Comment;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.input.FieldInput;
import com.atlassian.jira.rest.client.api.domain.input.IssueInput;
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
import io.delphi.qa.auto.awsmfrw.common_baby.IsaCommonMethods;
import io.delphi.qa.auto.awsmfrw.common_baby.IsaConstants;
import io.delphi.qa.auto.awsmfrw.common_baby.IsaLogging;
import io.delphi.qa.auto.awsmfrw.common_baby.delphi.aws.EnAwsSecrets;
import io.delphi.qa.auto.awsmfrw.common_baby.delphi.aws.ICanFetchAwsSecret;
import io.delphi.qa.auto.awsmfrw.common_baby.exceptions.FeatureNotImplementedException;
import io.delphi.qa.auto.awsmfrw.models.jira.cfg.JiraConfig;
import io.delphi.qa.auto.awsmfrw.models.jira.cfg.JiraLink;
import io.delphi.qa.auto.awsmfrw.models.jira.cfg.JiraProject;
import io.delphi.qa.auto.awsmfrw.models.jira.cfg.JiraUser;
import io.qameta.allure.Step;

import java.net.URI;
import java.util.Arrays;
import java.util.Map;

public class HlJira implements IsaCommonMethods, IsaConstants, ICanFetchAwsSecret {

  public final JiraConfig OBJ_JIRA_CFG_ATLASSIAN;
  private final JiraUser OBJ_JIRA_USER;
  private final JiraProject OBJ_JIRA_PROJECT;
  private JiraRestClient jiraRestClient;

  protected final Map<String, String> secretsKey = fetchAwsSecret(EnAwsSecrets.DELPHI_AUTOTESTS_CONFIG);

  public HlJira() {
    //    private final IssueRestClient issueClt;
    OBJ_JIRA_USER =
        new JiraUser()
            .withName(secretsKey.get("jira_user"))
            .withEmail(secretsKey.get("jira_email"))
            .withAccessToken(secretsKey.get("jira_api_token"));
    OBJ_JIRA_PROJECT = new JiraProject().withId("DSMA");
    OBJ_JIRA_CFG_ATLASSIAN =
        new JiraConfig()
            .withJiraLink(new JiraLink().withSpec(HTTPS).withHost("theorchard.atlassian.net"))
            .withJiraUser(OBJ_JIRA_USER)
            .withJiraProject(OBJ_JIRA_PROJECT);
    jiraRestClient =
        new AsynchronousJiraRestClientFactory()
            .createWithBasicHttpAuthentication(
                URI.create(buildJiraIssueLink(OBJ_JIRA_CFG_ATLASSIAN.getJiraLink())),
                OBJ_JIRA_CFG_ATLASSIAN.getJiraUser().getEmail(),
                OBJ_JIRA_CFG_ATLASSIAN.getJiraUser().getAccessToken());
  }

  //  public static String getIssueUrl(String issueKey) {
  //    return issueKey != null
  //        ? JIRA_CONFIG.getJiraUri() + "browse/" + issueKey
  //        : "There is no issue key.";
  //  }

  @Step("API::REST: add Jira issue comment")
  public void addIssueComment(Issue issue, String msg) {
    jiraRestClient
        .getIssueClient()
        .addComment(issue.getCommentsUri(), Comment.valueOf(msg))
        .claim();
  }

  @Step("Update jira issue field")
  public void updateIssueFields(Issue issue, FieldInput... newFieldInputs) {
    IsaLogging.log(this.getClass(), "Update field:\n" + Arrays.toString(newFieldInputs));
    jiraRestClient
        .getIssueClient()
        .updateIssue(issue.getKey(), IssueInput.createWithFields(newFieldInputs))
        .claim();
  }

  @Step("Fetch Jira issue")
  public Issue getJiraIssue(String issueKey) {
    try {
      IsaLogging.log(this.getClass(), "Fetch jira issue");
      return jiraRestClient.getIssueClient().getIssue(issueKey).claim();
    } catch (ResponseTransformationException e) {
      IsaLogging.log(this.getClass(), String.format("Issue %s is not existed!", issueKey));
    }
    throw new FeatureNotImplementedException("This is a new issues OR wrong issue id.");
  }

  //  public void updateIssue(Issue jiraIssue, String testName, DateTime dt) {
  //
  //    Iterable<Comment> comments = jiraIssue.getComments();
  //    List<Comment> commentList = StreamSupport.stream(comments.spliterator(), false).filter(o ->
  // o.getBody().startsWith(testName)).collect(Collectors.toList());
  //    if (commentList.size() > 0){
  //      Promise<Issue> issue = jiraRestClient.getIssueClient().getIssue(jiraIssue.getKey());
  //    } else{
  //
  //    }
  //
  //  }

  //  public void closeIssue(String issueKey) {
  //    String issueStatus = getJiraIssue(issueKey).getStatus().getName().toLowerCase();
  //    if (issueStatus.equals(JiraIssueStatus.OPEN.toString())
  //        || issueStatus.equals(JiraIssueStatus.IN_PROGRESS.toString())
  //        || issueStatus.equals(JiraIssueStatus.IN_REVIEW.toString())
  //        || issueStatus.equals(JiraIssueStatus.REOPENED.toString())) {
  //      throw getNotImplementedException(issueKey);
  //    }
  //    // let's check either this issue is already preprocessed
  //    putIssueToClose(issueKey);
  //  }

  //  public BasicIssue createJiraIssue(IssueInput issue) {
  //    return jiraRestClient
  //        .getIssueClient().createIssue(issue).claim();
  //  }

  //  public void reopenIssue(String issueKey) {
  //    putIssueToReopened(issueKey);
  //  }

  //  private String getErrorMsg(String issueKey) {
  //    return String.format(
  //        "ERROR: %s is not pre-processed yet. Please, visit %s and update it manually!",
  //        issueKey, getIssueUrl(issueKey));
  //  }

  //  private NotImplementedException getNotImplementedException(String issueKey) {
  //    return new NotImplementedException(getErrorMsg(issueKey));
  //  }
  //
  //  private Transition getTransitionByName(Iterable<Transition> transitions, String status) {
  //    Transition transition =
  //        StreamSupport.stream(transitions.spliterator(), false)
  //            .filter(s -> s.getName().equals(status))
  //            .collect(Collectors.toList())
  //            .get(0);
  //    return transition;
  //  }
  //
  //  private String getWarningByStatus(Object issueKey) {
  //    return String.format(
  //        "WARNING: %s issue is already has status - %s!",
  //        issueKey, issue.getStatus().getDescription());
  //  }
  //
  //  public void makeIssueNotVoted(String issueKey) {
  //    issue = getJiraIssue(issueKey);
  //    // now let's vote for it
  //    if (Objects.requireNonNull(issue.getVotes()).hasVoted()) {
  //      jiraRestClient
  //        .getIssueClient().unvote(issue.getVotesUri()).claim();
  //    } else {
  //      log().warn(String.format("Issue %s is already not voted by current user!", issueKey));
  //    }
  //  }
  //
  //  public void makeIssueUnwatched(String issueKey) {
  //    issue = getJiraIssue(issueKey);
  //    // now let's watch it
  //    if (Objects.requireNonNull(issue.getWatchers()).isWatching()) {
  //      jiraRestClient
  //        .getIssueClient().unwatch(issue.getWatchers().getSelf()).claim();
  //    } else {
  //      log().warn(String.format("Issue %s is already Unwatched by current user!", issueKey));
  //    }
  //  }
  //
  //  public void makeIssueVoted(String issueKey) {
  //    issue = getJiraIssue(issueKey);
  //    // now let's vote for it
  //    if (!Objects.requireNonNull(issue.getVotes()).hasVoted()) {
  //      jiraRestClient
  //        .getIssueClient().vote(issue.getVotesUri()).claim();
  //    } else {
  //      log().warn(String.format("Issue %s is already voted by current user!", issueKey));
  //    }
  //  }
  //
  //  public void makeIssueWatched(String issueKey) {
  //    issue = getJiraIssue(issueKey);
  //    // now let's watch it
  //    if (Objects.requireNonNull(issue.getWatchers()).isWatching()) {
  //      jiraRestClient
  //        .getIssueClient().watch(issue.getWatchers().getSelf()).claim();
  //    } else {
  //      log().warn(String.format("Issue %s is already watched by current user!", issueKey));
  //    }
  //  }
  //
  //  @SuppressWarnings("UnstableApiUsage")
  //  private void printIssueListByJql(String jqlQuery, HashSet<String> searchFields) {
  //    SearchRestClient searchRestClient = jiraRestClient.getSearchClient();
  //    int startIndex = 1;
  //    int maxPerQuery = 100;
  //    ArrayList<Issue> issuesList = new ArrayList<>();
  //    while (true) {
  //      Promise<SearchResult> searchResult =
  //          searchRestClient.searchJql(jqlQuery, maxPerQuery, startIndex, searchFields);
  //      SearchResult results = searchResult.claim();
  //      StreamSupport.stream(results.getIssues().spliterator(), false).forEach(issuesList::add);
  //      if (startIndex >= results.getTotal()) {
  //        break;
  //      }
  //      startIndex += maxPerQuery;
  //    }
  //    issuesList.forEach(
  //        s ->
  //            log().debug(
  //                String.format(
  //                    "Issue:{STR_STOP_REQUEST=%s, Type=%s, Priority=%s, Summary=%s}",
  //                    s.getKey(),
  //                    s.getIssueType().getName(),
  //                    Objects.requireNonNull(s.getPriority()).getName(),
  //                    s.getSummary())));
  //  }
  //
  //  private void processTransactionTo(ImmutableList<FieldInput> fieldInputs, String actionName) {
  //    TransitionInput transitionInput;
  //    final Iterable<Transition> transitions =
  //        jiraRestClient
  //        .getIssueClient().getTransitions(issue.getTransitionsUri()).claim();
  //    final Transition currentTransition = getTransitionByName(transitions, actionName);
  //    if (fieldInputs == null) {
  //      transitionInput =
  //          new TransitionInput(currentTransition.getId(),
  // Comment.valueOf(STR_COMMENT_FROM_CODE));
  //    } else {
  //      transitionInput =
  //          new TransitionInput(
  //              currentTransition.getId(), fieldInputs, Comment.valueOf(STR_COMMENT_FROM_CODE));
  //    }
  //    jiraRestClient
  //        .getIssueClient().transition(issue.getTransitionsUri(), transitionInput).claim();
  //  }

  //  private void putIssueToClose(String issueKey) {
  //    String issueStatus = getJiraIssue(issueKey).getStatus().getName().toLowerCase();
  //    if (issueStatus.equals(JiraIssueStatus.CLOSED.toString())) {
  //      log().warn(getWarningByStatus(issueKey));
  //    } else {
  //      if (issueStatus.equals(JiraIssueStatus.OPEN.toString())
  //          || issueStatus.equals(JiraIssueStatus.REOPENED.toString())) {
  //        // let's preprocess issue
  //        processTransactionTo(null, JiraFlowActions.START_DEV.getActionName());
  //      }
  //      ImmutableList<FieldInput> fieldInputs =
  //          ImmutableList.of(
  //              new FieldInput("resolution", ComplexIssueInputFieldValue.with("value", "5")));
  //      // now let's close issue
  //      processTransactionTo(fieldInputs, JiraFlowActions.CLOSE.getActionName());
  //    }
  //  }

  //    private void putIssueToReopened(String issueKey) {
  //      if (getJiraIssue(issueKey)
  //          .getStatus()
  //          .getName()
  //          .toUpperCase()
  //          .equals(JiraIssueStatus.REOPENED.toString())) {
  //        log().warn(getWarningByStatus(issueKey));
  //      } else {
  //        // now let's reopen issue
  //        processTransactionTo(null, JiraFlowActions.REOPEN.getActionName());
  //      }
  //    }
}
