import type {
    ETranslationFlag,
    ITranslatableProperties,
    ITranslated,
    ITranslationProperties,
    Prettify,
    Remove,
} from "@devowl-wp/api";

import type { EExtendsMergeStrategy, ITemplateMetaData } from "../meta-data/meta-data.js";
import type { ITemplateMetaDataTranslatable } from "../meta-data/translatable.js";
import type { IRelease } from "../release.js";

interface IContentBlockerTemplateTranslatable extends ITemplateMetaDataTranslatable {
    description?: string;
    visualHeroButtonText?: string;
    ruleNotice?: string;

    // Translation Flags 🚩
    descriptionTranslationFlags: ETranslationFlag[];
    visualHeroButtonTextTranslationFlags: ETranslationFlag[];
    ruleNoticeTranslationFlags: ETranslationFlag[];
}

type ContentBlockerTemplateTranslatableKeys = keyof IContentBlockerTemplateTranslatable;

const TRANSLATABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST: ContentBlockerTemplateTranslatableKeys[] = [
    "name",
    "headline",
    "subHeadline",
    "description",
    "visualHeroButtonText",
    "ruleNotice",
];
Object.freeze(TRANSLATABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST);

interface IContentBlockerRule {
    expression: string;
    assignedToGroups?: string[];
    queryArgs?: IContentBlockerRuleQueryArg[];
    source?: string;
    needsRequiredSiblingRule: boolean;
}

interface IContentBlockerRuleQueryArg {
    queryArg: string;
    isOptional?: boolean;
    regExp: string;
}

interface IContentBlockerRuleGroup {
    id: string;
    mustGroupBeResolved: boolean;
    mustAllRulesBeResolved: boolean;
}

interface IContentBlockerTemplateTranslation
    extends IContentBlockerTemplateTranslatable,
        ITranslatableProperties,
        ITranslationProperties {}

/**
 * When extending attributes, think about WordPress client requirements: Is this field also need at WP-Client side?
 * If yes, add it to `/devowl-wp/backends/real-cookie-banner-backend/src/helper/templateExtends.ts` function `mapContentBlockerTemplate`.
 */
interface IContentBlockerTemplate
    extends IContentBlockerTemplateTranslatable,
        ITranslated<IContentBlockerTemplateTranslation>,
        ITemplateMetaData {
    id: string;
    serviceTemplateIdentifiers: string[];
    ruleGroups: IContentBlockerRuleGroup[]; // serialized, simple-json
    rules: IContentBlockerRule[]; // serialized, simple-json
    isVisual: boolean;
    visualHeroButtonText?: string;
    visualType?: EContentBlockerVisualType;
    visualContentType?: EContentBlockerVisualContentType;
    isVisualDarkMode?: boolean;
    visualBlur?: number;
    shouldForceToShowVisual: boolean;
    release?: IRelease;
    releaseId?: string;
    extendedMergeStrategies?: ExtendedContentBlockerMergeStrategies;
    exampleEmbedCodes?: string[];
    testStatus: EContentBlockerTestStatus;
    testPipelineId?: number;
}

interface IContentBlockerTemplateLatest {
    id: string;
    latestId: string;
    latestReleasedId?: string;
    identifier: string;
}

const EXTENDABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST = [
    "name",
    "description",
    "serviceTemplateIdentifiers",
    "ruleGroups",
    "rules",
    "ruleNotice",
    "isVisual",
    "visualType",
    "visualContentType",
    "isVisualDarkMode",
    "visualBlur",
    "visualHeroButtonText",
    "shouldForceToShowVisual",
] as Array<keyof IContentBlockerTemplate>;
Object.freeze(EXTENDABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST);

type ExtendableContentBlockerTemplateAttributes = Pick<
    IContentBlockerTemplate,
    (typeof EXTENDABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST)[number]
>;

enum EContentBlockerVisualType {
    Default = "default",
    Wrapped = "wrapped",
    Hero = "hero",
}

enum EContentBlockerVisualContentType {
    Map = "map",
    VideoPlayer = "video-player",
    AudioPlayer = "audio-player",
    FeedText = "feed-text",
    FeedVideo = "feed-video",
    Generic = "generic",
}

enum EContentBlockerTestStatus {
    Initial = "initial",
    Running = "running",
    Passed = "passed",
    Failed = "failed",
}

type ExtendedContentBlockerMergeStrategies = Partial<
    Record<keyof ExtendableContentBlockerTemplateAttributes, EExtendsMergeStrategy>
>;

type IContentBlockerTemplateClientResponse = Prettify<
    Partial<
        Remove<
            IContentBlockerTemplate,
            | "extendedMergeStrategies"
            | "logo"
            | "logoId"
            | "extends"
            | "extendsId"
            | "extendedTemplateId"
            | "next"
            | "nextId"
            | "pre"
            | "preId"
            | "release"
            | "translations"
            | "isDeleted"
            | "successorOfIdentifier"
        > & {
            language: string;
            logoUrl: string;
        }
    >
>;
type ContentBlockerColumn = keyof IContentBlockerTemplate;

/**
 * Represents the fields of a content blocker template.
 * Please also have a look at TemplateMetaDataField for base fields.
 */
enum ContentBlockerField {
    Description = "description",
    DescriptionTranslationFlags = "descriptionTranslationFlags",
    ExampleEmbedCodes = "exampleEmbedCodes",
    IsVisual = "isVisual",
    IsVisualDarkMode = "isVisualDarkMode",
    RuleGroups = "ruleGroups",
    RuleNotice = "ruleNotice",
    RuleNoticeTranslationFlags = "ruleNoticeTranslationFlags",
    Rules = "rules",
    ServiceTemplateIdentifiers = "serviceTemplateIdentifiers",
    ShouldForceToShowVisual = "shouldForceToShowVisual",
    TestPipelineId = "testPipelineId",
    TestStatus = "testStatus",
    VisualBlur = "visualBlur",
    VisualContentType = "visualContentType",
    VisualHeroButtonText = "visualHeroButtonText",
    VisualHeroButtonTextTranslationFlags = "visualHeroButtonTextTranslationFlags",
    VisualType = "visualType",
}

const EXPORT_REMOVABLE_CONTENT_BLOCKER: (ContentBlockerColumn | keyof ITranslationProperties)[] = [
    "id",
    "logo",
    "logoId",
    "release",
    "releaseId",
    "extends", // only extended identifier is needed
    "next",
    "nextId",
    "pre",
    "preId",
    "extendsId",
    "translationIds",
    "extendedTemplateId",
    "translationInfo",
    "translatableRequiredFields",
    "translatedRequiredFields",
    "translatableOptionalFields",
    "translatedOptionalFields",
    "translationFlaggedFields",
    "version",
];
Object.freeze(EXPORT_REMOVABLE_CONTENT_BLOCKER);

export {
    type ContentBlockerColumn,
    ContentBlockerField,
    EContentBlockerTestStatus,
    EContentBlockerVisualContentType,
    EContentBlockerVisualType,
    EXPORT_REMOVABLE_CONTENT_BLOCKER,
    EXTENDABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST,
    type ExtendableContentBlockerTemplateAttributes,
    type ExtendedContentBlockerMergeStrategies,
    type IContentBlockerRule,
    type IContentBlockerRuleGroup,
    type IContentBlockerRuleQueryArg,
    type IContentBlockerTemplate,
    type IContentBlockerTemplateClientResponse,
    type IContentBlockerTemplateLatest,
    type IContentBlockerTemplateTranslatable,
    type IContentBlockerTemplateTranslation,
    TRANSLATABLE_CONTENT_BLOCKER_TEMPLATE_ATTRIBUTES_LIST,
};
