package com.onresolve.scriptrunner.canned.jira.fields

import com.atlassian.jira.JiraDataTypes
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.customfields.CustomFieldValueProvider
import com.atlassian.jira.issue.customfields.SingleValueCustomFieldValueProvider
import com.atlassian.jira.issue.customfields.searchers.CustomFieldSearcherClauseHandler
import com.atlassian.jira.issue.customfields.searchers.SimpleCustomFieldSearcherClauseHandler
import com.atlassian.jira.issue.customfields.searchers.information.CustomFieldSearcherInformation
import com.atlassian.jira.issue.customfields.searchers.transformer.CustomFieldInputHelper
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.ImmutableCustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem
import com.atlassian.jira.issue.fields.rest.FieldJsonRepresentation
import com.atlassian.jira.issue.index.indexers.FieldIndexer
import com.atlassian.jira.issue.search.ClauseNames
import com.atlassian.jira.issue.search.LuceneFieldSorter
import com.atlassian.jira.issue.search.searchers.information.SearcherInformation
import com.atlassian.jira.issue.search.searchers.renderer.SearchRenderer
import com.atlassian.jira.issue.search.searchers.transformer.SearchInputTransformer
import com.atlassian.jira.issue.statistics.TextFieldSorter
import com.atlassian.jira.jql.operand.JqlOperandResolver
import com.atlassian.jira.jql.operator.OperatorClasses
import com.atlassian.jira.jql.query.ActualValueCustomFieldClauseQueryFactory
import com.atlassian.jira.jql.util.IndexValueConverter
import com.atlassian.jira.jql.util.SimpleIndexValueConverter
import com.atlassian.jira.jql.validator.ExactTextCustomFieldValidator
import com.atlassian.jira.util.ErrorCollection
import com.atlassian.jira.web.FieldVisibilityManager
import com.onresolve.scriptrunner.canned.jira.fields.editable.ConfigurablePickerSearcherRenderer
import com.onresolve.jira.scriptfields.MultistringIndexer
import com.onresolve.scriptrunner.canned.jira.fields.editable.PickerSearchInputTransformer
import com.onresolve.scriptrunner.canned.util.BuiltinScriptErrors
import groovy.util.logging.Log4j

import javax.annotation.Nullable
import java.util.concurrent.atomic.AtomicReference

@Log4j
class RestPickerCannedField extends AbstractEditableCannedField {

    private SearcherInformation<CustomField> searcherInformation
    private SearchInputTransformer searchInputTransformer
    private SearchRenderer searchRenderer
    final private FieldVisibilityManager fieldVisibilityManager = ComponentAccessor.getComponent(FieldVisibilityManager)
    final private JqlOperandResolver jqlOperandResolver = ComponentAccessor.getComponent(JqlOperandResolver)
    final private CustomFieldInputHelper customFieldInputHelper = ComponentAccessor.getComponent(CustomFieldInputHelper)
    private CustomFieldSearcherClauseHandler customFieldSearcherClauseHandler
    public static String FIELD_SEARCH_URL = "FIELD_SEARCH_URL"
    public static String FIELD_VALIDATE_URL = "FIELD_VALIDATE_URL"

    @Override
    void init(CustomField field) {
        FieldIndexer indexer = new MultistringIndexer(fieldVisibilityManager, field)
        final ClauseNames names = field.getClauseNames()

        this.searcherInformation = new CustomFieldSearcherInformation(field.getId(), field.getNameKey(), Collections.singletonList(indexer), new AtomicReference(field))
        this.searchInputTransformer = new PickerSearchInputTransformer(field, names, searcherInformation.getId(), customFieldInputHelper)

        final CustomFieldValueProvider customFieldValueProvider = new SingleValueCustomFieldValueProvider()
        this.searchRenderer = new ConfigurablePickerSearcherRenderer(names, getDescriptor(), field, customFieldValueProvider, fieldVisibilityManager)

        //  todo: possible group name validator

        final IndexValueConverter indexValueConverter = new SimpleIndexValueConverter(false)

        this.customFieldSearcherClauseHandler = new SimpleCustomFieldSearcherClauseHandler(
            new ExactTextCustomFieldValidator(),
            new ActualValueCustomFieldClauseQueryFactory(field.getId(), jqlOperandResolver, indexValueConverter, false),
            OperatorClasses.EQUALITY_OPERATORS_WITH_EMPTY,
            JiraDataTypes.TEXT
        )
    }

    @Override
    void validateFromParams(Map<String, Object> params, List<String> value, ErrorCollection errorCollectionToAddTo, FieldConfig config) {

    }

    @Override
    FieldJsonRepresentation getJsonFromIssue(CustomField field, Issue issue, boolean renderedVersionRequested,
                                             @Nullable FieldLayoutItem fieldLayoutItem) {
        return null
    }

    @Override
    CustomFieldSearcherClauseHandler getCustomFieldSearcherClauseHandler() {
        customFieldSearcherClauseHandler
    }

    @Override
    LuceneFieldSorter getSorter(CustomField customField) {
        new TextFieldSorter(customField.getId())
    }

    @Override
    SearcherInformation<CustomField> getSearchInformation() {
        searcherInformation
    }

    @Override
    SearchInputTransformer getSearchInputTransformer() {
        searchInputTransformer
    }

    @Override
    SearchRenderer getSearchRenderer() {
        searchRenderer
    }

    @Override
    List doGetParameters(Map params) {
        [
            [
                name       : FIELD_SEARCH_URL,
                label      : "Search URL",
                description: "for search - user search added as inputValue",
            ],
            [
                name       : FIELD_VALIDATE_URL,
                label      : "Validate URL",
                description: "for search - user search added as inputValue",
            ],
        ]
    }

    @Override
    BuiltinScriptErrors doValidation(Map<String, Object> params, boolean forPreview) {
        return null
    }

    @Override
    String getViewHtml(Issue issue, ImmutableCustomField field, FieldLayoutItem fieldLayoutItem, List<String> value) {
        value.join(", ")
    }

    @Override
    String getTextOnlyHtml(Issue issue, ImmutableCustomField field, FieldLayoutItem fieldLayoutItem, List<String> value) {
        getViewHtml(issue, field, fieldLayoutItem, value)
    }
}
