package com.pingcap.kb.integration.service;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pingcap.kb.integration.config.JiraConfiguration;
import com.pingcap.kb.integration.dao.JiraIssueDao;
import com.pingcap.kb.integration.entity.JiraIssueStatus;
import com.pingcap.kb.integration.jira.JiraClient;
import com.pingcap.kb.integration.jira.JiraIssue;
import com.pingcap.kb.integration.jira.JiraIssueIterator;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class JiraService {

  private final ObjectMapper mapper = new ObjectMapper();
  private final JiraIssueDao jiraIssueDao;
  private final JiraConfiguration jiraConfiguration;
  private final JiraClient jiraClient;

  {
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  }

  public JiraService(JiraIssueDao dao, JiraConfiguration jiraConfiguration, JiraClient jiraClient) {
    this.jiraIssueDao = dao;
    this.jiraConfiguration = jiraConfiguration;
    this.jiraClient = jiraClient;
  }

  public Iterator<JiraIssue> findIssues() {
    var jql = buildJql(jiraConfiguration.getPollJql(), buildJqlParams());
    return new JiraIssueIterator(jiraClient, jql).iterator();
  }

  public Iterator<JiraIssue> findLegacyIssues () {
    var jql = jiraConfiguration.getLegacyJql();
    return new JiraIssueIterator(jiraClient, jql).iterator();
  }

  public String buildJql(String jql, Map<String, String> params) {
    var res = new String[]{jql};
    params.forEach((k, v) -> {
      res[0] = res[0].replace("${" + k + "}", v);
    });
    return res[0];
  }

  public Map<String, String> buildJqlParams() {
    Map<String, String> res = new HashMap<>();
    Date maxUpdated = jiraIssueDao.findMaxUpdated();
    if (maxUpdated == null) {
      res.put("lastUpdatedAt", "\"2021-12-28 00:00\"");
    } else {
      SimpleDateFormat sdf = new SimpleDateFormat("\"yyyy-MM-dd HH:mm\"");
      res.put("lastUpdatedAt", sdf.format(maxUpdated));
    }
    return res;
  }

  public JiraIssueStatus getIssueStatus(String num) {
    String key = jiraConfiguration.getProject() + "-" + num;
    return jiraIssueDao.findByKey(key)
        .orElseGet(() -> {
          var issue = jiraClient.get(num).orElseThrow();
          return jiraIssueDao.create(key, true, issue.getFields().getUpdated(), issue.getFields().getCreated());
        });
  }

}
