import { action, computed, reaction, runInAction } from "mobx";

import type { EServiceTemplateGoogleConsentModeTypes } from "@devowl-wp/api-real-cookie-banner";
import type { WpRestEndpointWithMultilingualSection } from "@devowl-wp/multilingual";
import type { VisualService, VisualServiceTechnicalDefinition } from "@devowl-wp/react-cookie-banner";
import type { PostStatus } from "@devowl-wp/utils";
import { AbstractPost, ClientModel } from "@devowl-wp/utils";

import { RootStore } from "../store/stores.js";
import { request } from "../utils/request.js";

import type { CookieCollection } from "./cookieCollection.js";
import type { ServiceTemplate } from "./serviceTemplate.js";
import type { CookieStore } from "../store/cookie.js";
import type { CookieMeta } from "../types/cookie.js";

@ClientModel.annotate({
    keyId: "id",
    namespace: "wp/v2",
    request,
    create: {
        path: "/rcb-cookie",
    },
    patch: {
        path: "/rcb-cookie/:id",
    },
    delete: {
        path: "/rcb-cookie/:id",
    },
})
class CookieModel extends AbstractPost<
    CookieCollection,
    CookieMeta,
    {
        "rcb-cookie-group": number[];
        usedTemplate: false | ServiceTemplate["use"];
    } & WpRestEndpointWithMultilingualSection
> {
    @computed
    public get templateModel() {
        return RootStore.get.cookieStore.templatesServices.get(this.data.meta?.presetId);
    }

    @computed
    public get rootStore() {
        return this.collection.store.collection.store.rootStore;
    }

    @computed
    public get technicalDefinitions(): VisualServiceTechnicalDefinition[] {
        return JSON.parse(this.data.meta.technicalDefinitions || "[]");
    }

    @computed
    public get googleConsentModeConsentTypes(): EServiceTemplateGoogleConsentModeTypes[] {
        return JSON.parse(this.data.meta.googleConsentModeConsentTypes || "[]");
    }

    @computed
    public get dataProcessingInCountries(): VisualService["dataProcessingInCountries"] {
        return JSON.parse(this.data.meta.dataProcessingInCountries || "[]");
    }

    @computed
    public get dataProcessingInCountriesSpecialTreatments(): VisualService["dataProcessingInCountriesSpecialTreatments"] {
        return JSON.parse(this.data.meta.dataProcessingInCountriesSpecialTreatments || "[]");
    }

    @computed
    public get isUpdateAvailable() {
        for (const { post_id } of this.rootStore.optionStore.templateNeedsUpdate) {
            if (post_id === this.data.id) {
                return true;
            }
        }
        return false;
    }

    @computed
    public get codeDynamics(): Record<string, string> {
        return JSON.parse(this.data.meta.codeDynamics || "{}");
    }

    public readonly store: CookieStore;

    public constructor(collection: CookieModel["collection"], data: Partial<CookieModel["data"]> = {}) {
        super(collection, data);

        reaction(
            () => this.data?.usedTemplate,
            (template) =>
                runInAction(() => {
                    if (template) {
                        RootStore.get.cookieStore.addServiceTemplates([template]);
                    }
                }),
            { fireImmediately: true },
        );
    }

    @action
    public afterPatch() {
        // Remove this cookie from all other groups
        const groups = this.collection.store.collection;
        const [thisGroup] = this.data["rcb-cookie-group"];
        groups.entries.forEach((group) => {
            if (thisGroup !== group.key) {
                group.cookies.entries.delete(this.key);
            } else {
                group.cookies.entries.set(this.key, this);
            }
        });

        this.rootStore.optionStore.fetchCurrentRevision();
        this.rootStore.cookieStore.unassignedCookies.delete(this.key);
    }

    @action
    public setOrder(order: number) {
        this.data.menu_order = order;
    }

    @action
    public setName(name: string) {
        this.data.title.raw = name;
    }

    @action
    public setStatus(status: PostStatus) {
        this.data.status = status;
    }

    @action
    public setPurpose(purpose: string) {
        this.data.content.raw = purpose;
    }

    @action
    public setGroup(group: number) {
        this.data["rcb-cookie-group"] = [group];
    }

    @action
    public setMeta(meta: CookieModel["data"]["meta"]) {
        this.data.meta = meta;
    }

    public transformDataForPersist(): any {
        const data = super.transformDataForPersist();
        return {
            ...data,
            "rcb-cookie-group": [this.collection.store.key],
        };
    }

    public transformDataForPatch(): any {
        const data = super.transformDataForPatch();
        return {
            title: data.title,
            content: data.content,
            status: data.status,
            meta: data.meta,
            menu_order: data.menu_order,
            "rcb-cookie-group": this.data["rcb-cookie-group"],
            // Force to rewrite slug
            slug: data.title,
        };
    }

    public afterDelete() {
        this.collection.store.cookies.store.collection.store.rootStore.optionStore.fetchCurrentRevision();
    }

    public afterPersist() {
        const { optionStore, checklistStore } = this.collection.store.cookies.store.collection.store.rootStore;
        optionStore.fetchCurrentRevision();
        checklistStore.probablyFetchByChangedItem("add-cookie");
    }
}

export { CookieModel };
