package ru.yandex.direct.web.entity.keyword.presentation;

import ru.yandex.direct.core.entity.keyword.service.validation.phrase.advqphrase.AdvqPhraseDefectIds;
import ru.yandex.direct.core.entity.keyword.service.validation.phrase.advqphrase.AdvqPhraseDefectTranslations;
import ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectTranslations;
import ru.yandex.direct.core.entity.keyword.service.validation.phrase.minusphrase.MinusPhraseDefectIds;
import ru.yandex.direct.core.entity.keyword.service.validation.phrase.minusphrase.MinusPhraseDefectTranslations;
import ru.yandex.direct.i18n.types.Identity;
import ru.yandex.direct.validation.presentation.DefaultDefectPresentationRegistry;
import ru.yandex.direct.web.validation.WebDefectTranslations;
import ru.yandex.direct.web.validation.kernel.TranslatableWebDefect;

import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.AD_GROUP_NOT_FOUND;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.AUTOTARGETING_PREFIX_IS_NOT_ALLOWED;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.DUPLICATED_WITH_UPDATED;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.KEYWORD_ALREADY_SUSPENDED;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.KEYWORD_DUPLICATED_WITH_EXISTING;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.KEYWORD_DUPLICATED_WITH_NEW;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.KEYWORD_NOT_SUSPENDED;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.NOT_ACCEPTABLE_AD_GROUP_TYPE;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Gen.NO_RIGHTS_IN_ARCHIVED_ADGROUP;
import static ru.yandex.direct.core.entity.keyword.service.validation.KeywordDefectIds.Keyword.MAX_KEYWORDS_PER_AD_GROUP_EXCEEDED;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.BOTH_QUOTES_AND_MINUS_WORDS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.BRACKETS_IN_MINUS_WORDS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INCORRECT_USE_OF_PARENTHESIS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_APOSTROPHE;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_BRACKETS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_EXCLAMATION_MARK;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_MINUS_MARK;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_PLUS_MARK;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_POINT;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.INVALID_QUOTES;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.MINUS_WORD_INSIDE_BRACKETS_OR_QUOTES;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.NO_PLUS_WORDS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.ONLY_STOP_WORDS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.Gen.PLUS_MARK_IN_BRACKETS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.ILLEGAL_CHARACTERS;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.MINUS_WORD_DELETE_PLUS_WORD;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.NOT_SINGLE_MINUS_WORD;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.TOO_LONG_KEYWORD;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.TOO_LONG_MINUS_WORD;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.TOO_LONG_WORD;
import static ru.yandex.direct.core.entity.keyword.service.validation.phrase.keyphrase.PhraseDefectIds.String.TOO_MANY_WORDS;
import static ru.yandex.direct.web.validation.kernel.WebDefectPresentationProviders.defaultWebDefect;
import static ru.yandex.direct.web.validation.kernel.WebDefectPresentationProviders.paramWebDefect;
import static ru.yandex.direct.web.validation.kernel.WebDefectPresentationProviders.webDefect;

public class KeywordDefectPresentations {

    private KeywordDefectPresentations() {
    }

    /**
     * Общие ошибки модели Keyword кроме ошибок текстов фраз
     */
    public static DefaultDefectPresentationRegistry<TranslatableWebDefect> keywordDefectPresentationRegistry() {
        return DefaultDefectPresentationRegistry.builder()
                .register(MAX_KEYWORDS_PER_AD_GROUP_EXCEEDED, defaultWebDefect())
                .register(NOT_ACCEPTABLE_AD_GROUP_TYPE, defaultWebDefect())
                .register(NO_RIGHTS_IN_ARCHIVED_ADGROUP, defaultWebDefect())
                .register(KEYWORD_DUPLICATED_WITH_NEW, defaultWebDefect())
                .register(DUPLICATED_WITH_UPDATED, defaultWebDefect())
                .register(KEYWORD_DUPLICATED_WITH_EXISTING, defaultWebDefect())
                .register(AD_GROUP_NOT_FOUND, defaultWebDefect())
                .register(KEYWORD_ALREADY_SUSPENDED, defaultWebDefect())
                .register(KEYWORD_NOT_SUSPENDED, defaultWebDefect())
                .register(AUTOTARGETING_PREFIX_IS_NOT_ALLOWED, defaultWebDefect())
                .build();
    }

    /**
     * Ошибки текстов фраз
     */
    public static DefaultDefectPresentationRegistry<TranslatableWebDefect> phraseDefectPresentationRegistry() {
        PhraseDefectTranslations translations = PhraseDefectTranslations.INSTANCE;

        return DefaultDefectPresentationRegistry.builder()
                .register(ILLEGAL_CHARACTERS,
                        paramWebDefect(di -> translations.invalidChars(
                                di.getDefect().params().getAllInvalidSubstrings(),
                                (String) di.getValue())))
                .register(INVALID_QUOTES,
                        paramWebDefect(di -> translations.invalidQuotes((String) di.getValue())))
                .register(INVALID_BRACKETS,
                        paramWebDefect(di -> translations.invalidBrackets((String) di.getValue())))
                .register(INVALID_EXCLAMATION_MARK,
                        paramWebDefect(di -> translations.invalidExclamationMark((String) di.getValue())))
                .register(INVALID_PLUS_MARK,
                        paramWebDefect(di -> translations.invalidPlus((String) di.getValue())))
                .register(INVALID_MINUS_MARK,
                        paramWebDefect(di -> translations.invalidMinus((String) di.getValue())))
                .register(INVALID_POINT,
                        paramWebDefect(di -> translations.invalidPoint((String) di.getValue())))
                .register(INVALID_APOSTROPHE,
                        paramWebDefect(di -> translations.invalidApostrophe((String) di.getValue())))
                .register(BOTH_QUOTES_AND_MINUS_WORDS,
                        paramWebDefect(di -> translations.bothQuotesAndMinusWords((String) di.getValue())))
                .register(MINUS_WORD_INSIDE_BRACKETS_OR_QUOTES,
                        paramWebDefect(di -> translations.minusWordsInsideBracketsOrQuotes((String) di.getValue())))
                .register(PLUS_MARK_IN_BRACKETS,
                        paramWebDefect(di -> translations.plusMarkInsideBrackets((String) di.getValue())))
                .register(BRACKETS_IN_MINUS_WORDS,
                        paramWebDefect(di -> translations.bracketsInMinusWords((String) di.getValue())))
                .register(NOT_SINGLE_MINUS_WORD,
                        paramWebDefect(di -> translations.notSingleMinusWord((String) di.getValue())))
                .register(NO_PLUS_WORDS,
                        paramWebDefect(di -> translations.noPlusWords((String) di.getValue())))
                .register(MINUS_WORD_DELETE_PLUS_WORD,
                        paramWebDefect(di -> translations.minusWordDeletePlusWord((String) di.getValue())))
                .register(TOO_LONG_KEYWORD,
                        paramWebDefect(di -> translations.tooLongKeyword(
                                di.getDefect().params().getMaxLength(), (String) di.getValue())))
                .register(TOO_LONG_WORD,
                        paramWebDefect(di -> translations.tooLongWord(
                                di.getDefect().params().getMaxLength(), (String) di.getValue())))
                .register(TOO_LONG_MINUS_WORD,
                        paramWebDefect(di -> translations.tooLongWord(
                                di.getDefect().params().getMaxLength(), (String) di.getValue())))
                .register(TOO_MANY_WORDS,
                        paramWebDefect(di -> translations.tooManyWords(
                                di.getDefect().params().getMaxWords(), (String) di.getValue())))
                .register(ONLY_STOP_WORDS,
                        paramWebDefect(di -> translations.onlyStopWords((String) di.getValue())))
                .register(INCORRECT_USE_OF_PARENTHESIS,
                        paramWebDefect(di -> translations.invalidParenthesis()))
                .build();
    }

    /**
     * Ошибки фраз для ручки "hasSearchVolume".
     */
    public static DefaultDefectPresentationRegistry<TranslatableWebDefect> advqPhraseDefectPresentationRegistry() {
        AdvqPhraseDefectTranslations translations = AdvqPhraseDefectTranslations.INSTANCE;

        return DefaultDefectPresentationRegistry.builder()
                .register(AdvqPhraseDefectIds.Gen.CANNOT_CONTAIN_LONE_DOT,
                        webDefect(translations.invalidCharsKeywordLoneDotDetailed()))
                .register(AdvqPhraseDefectIds.Gen.UNPAIRED_QUOTES,
                        webDefect(translations.invalidCharsUnpairedQuotesDetailed()))
                .register(AdvqPhraseDefectIds.Gen.CONTAINS_ONLY_STOP_WORDS,
                        webDefect(translations.stopWordsDetailed()))
                .register(AdvqPhraseDefectIds.Gen.CANNOT_CONTAIN_ONLY_MINUS_WORDS,
                        webDefect(translations.minusWordsOnlyDetailed()))
                .register(AdvqPhraseDefectIds.String.TOO_MANY_WORDS,
                        paramWebDefect(di -> translations.maxWordsDetailed(di.getDefect().params().getMaxWords())))
                .register(AdvqPhraseDefectIds.String.TOO_LONG_KEYWORD,
                        paramWebDefect(di -> translations.keywordMaxLengthDetailed(
                                di.getDefect().params().getMaxLength())))
                .register(AdvqPhraseDefectIds.Gen.UNPAIRED_SQUARE_BRACKETS,
                        webDefect(translations.invalidCharsUnpairedSquareBracketsDetailed()))
                .register(AdvqPhraseDefectIds.Gen.EMPTY_OR_NESTED_SQUARE_BRACKETS,
                        webDefect(translations.invalidCharsEmptyOrNestedSquareBrackets()))
                .register(AdvqPhraseDefectIds.Gen.MODIFIERS_INSIDE_SQUARE_BRACKETS,
                        webDefect(translations.invalidCharsModifiersInsideSquareBrackets()))
                .register(AdvqPhraseDefectIds.Gen.INCORRECT_USE_OF_EXCLAMATION_MARK,
                        webDefect(translations.invalidCharsIncorrectUseOfExclamationMarks()))
                .register(AdvqPhraseDefectIds.Gen.INCORRECT_USE_OF_MINUS_SIGN,
                        webDefect(translations.invalidCharsIncorrectUseOfMinusSign()))
                .register(AdvqPhraseDefectIds.Gen.INCORRECT_USE_OF_PLUS_SIGN,
                        webDefect(translations.invalidCharsIncorrectUseOfPlusSign()))
                .register(AdvqPhraseDefectIds.Gen.NO_MINUS_PHRASES_ONLY_WORDS,
                        webDefect(translations.minusWordsNoMinusPhrasesDetailed()))
                .register(AdvqPhraseDefectIds.Gen.MINUS_WORDS_NO_PHRASE_WITH_DOT,
                        webDefect(translations.minusWordsPhraseWithDot()))
                .register(AdvqPhraseDefectIds.Gen.INCORRECT_COMBINATION_OF_SPECIAL_SYMBOLS,
                        webDefect(translations.minusWordsIncorrectCombinationOfSpecialSymbols()))
                .register(AdvqPhraseDefectIds.Gen.MINUS_WORD_CANNOT_START_FROM_DOT_OR_APOSTROPHE,
                        webDefect(translations.minusWordsCantStartWithDotOrApostroph()))
                .register(AdvqPhraseDefectIds.Gen.MINUS_WORD_NOT_IN_QUOTED_PHRASE,
                        webDefect(translations.minusWordsNotInQuotedPhrase()))
                .register(AdvqPhraseDefectIds.Gen.ONLY_SINGLE_DOT_BETWEEN_NUMBERS,
                        webDefect(translations.minusWordsSingleDotOnly()))
                .register(AdvqPhraseDefectIds.String.MINUS_WORDS_CANNOT_SUBTRACT_PLUS_WORDS,
                        paramWebDefect(di -> translations.minusWordsCantSubtractPlusWords(
                                di.getDefect().params().getAllInvalidSubstrings())))
                .build();
    }

    /**
     * Ошибки минус-фраз
     */
    public static DefaultDefectPresentationRegistry<TranslatableWebDefect> minusPhraseDefectPresentationRegistry() {
        MinusPhraseDefectTranslations translations = MinusPhraseDefectTranslations.INSTANCE;
        WebDefectTranslations webTranslations = WebDefectTranslations.INSTANCE;

        return DefaultDefectPresentationRegistry.builder()
                .register(MinusPhraseDefectIds.Gen.MINUS_KEYWORD_IS_INCLUDED_IN_KEYWORD,
                        webDefect(webTranslations.minusKeywordIsIncludedInKeyword()))
                .register(MinusPhraseDefectIds.MinusPhrase.ILLEGAL_MINUS_KEYWORD_CHARS,
                        webDefect(translations.notAllowedSymbolsInMinusKeywordDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_COMBINATION_SPECIAL_SYMBOLS,
                        webDefect(translations.wrongSpecialSymbolsUsageInMinusKeywordDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_DOT,
                        webDefect(translations.invalidDotDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.SEPARATE_DOT,
                        webDefect(translations.separateDotDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_WORD_FIRST_CHARACTER,
                        webDefect(translations.invalidWordFirstCharacterDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_EXCLAMATION_MARK,
                        webDefect(translations.wrongExclamationMarkInMinusKeyword()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_MINUS_MARK,
                        webDefect(translations.wrongMinusMarkUsageInMinusKeywordDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_OPERATORS_INSIDE_SQUARE_BRACKETS,
                        webDefect(translations.notAllowedOperatorsInsideBracketsDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.INVALID_PLUS_MARK,
                        webDefect(translations.wrongPlusMarkUsageInMinusKeywordDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.WRONG_QUOTES,
                        webDefect(translations.wrongWrappedQuotesInMinusKeywordDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.IMBALANCED_SQUARE_BRACKETS,
                        webDefect(translations.imbalancedSquareBracketsDetailed()))
                .register(MinusPhraseDefectIds.MinusPhrase.NESTED_OR_EMPTY_SQUARE_BRACKETS,
                        webDefect(translations.nestedOrEmptySquareBracketsDetailed()))
                .register(MinusPhraseDefectIds.IndividualKeywordLength.MAX_COUNT_WORDS_IN_KEYWORD,
                        paramWebDefect(di -> translations.maxWordsCountInKeywordDetailed(
                                new Identity(di.getDefect().params().getMaxWords()))))
                .register(MinusPhraseDefectIds.StringLength.MAX_LENGTH_MINUS_KEYWORDS,
                        paramWebDefect(di -> translations.maxLengthMinusKeywordsDetailed(
                                new Identity(di.getDefect().params().getMaxLength()))))
                .register(MinusPhraseDefectIds.IndividualKeywordLength.MAX_LENGTH_MINUS_WORD,
                        paramWebDefect(di -> translations.maxWordsCountInKeywordDetailed(
                                new Identity(di.getDefect().params().getMaxLength()))))
                .register(MinusPhraseDefectIds.Gen.MINUS_WORDS_PACK_NOT_FOUND,
                        paramWebDefect(di -> translations.minusWordsPackNotFound(
                                new Identity((Long) di.getValue()))))
                .build();
    }
}
