import { action, computed, flow, observable, runInAction } from "mobx";

import type { WpRestEndpointWithMultilingualSection } from "@devowl-wp/multilingual";
import { AbstractCategory, ClientModel } from "@devowl-wp/utils";

import { CookieCollection } from "./cookieCollection.js";
import { request } from "../utils/request.js";

import type { CookieGroupCollection } from "./cookieGroupCollection.js";

type CancellablePromise<R> = ReturnType<ReturnType<typeof flow<R, any>>>;

@ClientModel.annotate({
    keyId: "id",
    namespace: "wp/v2",
    request,
    create: {
        path: "/rcb-cookie-group",
    },
    patch: {
        path: "/rcb-cookie-group/:id",
    },
    delete: {
        path: "/rcb-cookie-group/:id",
    },
})
class CookieGroupModel extends AbstractCategory<
    CookieGroupCollection,
    {
        order: number;
        isEssential: boolean;
        isDefault: boolean;
    },
    WpRestEndpointWithMultilingualSection
> {
    @observable
    public cookies: CookieCollection;

    @observable
    public fetchedAllCookies = false;

    @computed
    public get cookiesCount() {
        // TODO: this.data.count should return a count also of private cookies
        return this.fetchedAllCookies ? this.cookies.entries.size : this.data.count;
    }

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

        runInAction(() => {
            this.cookies = new CookieCollection(this);
        });
    }

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

    @action
    public setDescription(description: string) {
        this.data.description = description;
    }

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

    public fetchCookies: () => CancellablePromise<void> = flow(function* (this: CookieGroupModel) {
        yield this.cookies.get({
            request: {
                status: ["draft", "publish", "private"],
            },
            params: {
                per_page: 100, // Fetch all
                "rcb-cookie-group": this.key,
                context: "edit",
            },
        });
        this.fetchedAllCookies = true;
    });

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

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

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

export { CookieGroupModel };
