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

import type { ClientBlockerTemplate, ClientServiceTemplate } from "@devowl-wp/service-cloud-consumer";

import { ServiceTemplate } from "./serviceTemplate.js";
import { request } from "../utils/request.js";
import { locationRestScannerResultIgnorePost } from "../wp-api/scannerResultIgnore.post.js";

import type { BlockerTemplate } from "./blockerTemplate.js";
import type { ScannerStore } from "../store/scanner.js";
import type {
    ParamsRouteScannerResultIgnorePost,
    RequestRouteScannerResultIgnorePost,
    ResponseRouteScannerResultIgnorePost,
} from "../wp-api/scannerResultIgnore.post.js";
import type { ResponseRouteScannerResultTemplatesGet } from "../wp-api/scannerResultsTemplate.get.js";

class ScannerResultTemplate {
    @observable
    public busy = false;

    @observable
    public data: ResponseRouteScannerResultTemplatesGet["items"][0];

    @observable
    public templateModel: ServiceTemplate | BlockerTemplate;

    public readonly store: ScannerStore;

    @computed
    public get identifier() {
        return this.data.identifier;
    }

    @computed
    public get type() {
        return this.templateModel instanceof ServiceTemplate ? "service" : "blocker";
    }

    /**
     * Determines if this template needs further attention. It is inactive when it e.g. already exists.
     */
    @computed
    public get inactive() {
        return this.data.consumerData["isCreated"] || this.data.consumerData["isIgnored"];
    }

    public constructor(template: ScannerResultTemplate["data"], store: ScannerStore) {
        runInAction(() => {
            this.data = template;
        });
        this.store = store;

        const { cookieStore } = store.rootStore;
        if (Object.hasOwn(template, "rules")) {
            cookieStore.addBlockerTemplates([template as ClientBlockerTemplate["afterPersist"]]);
            this.templateModel = cookieStore.templatesBlocker.get(template.identifier);
        } else {
            cookieStore.addServiceTemplates([template as ClientServiceTemplate["afterPersist"]]);
            this.templateModel = cookieStore.templatesServices.get(template.identifier);
        }
    }

    public ignore: (state: boolean) => Promise<void> = flow(function* (this: ScannerResultTemplate, state) {
        this.busy = true;
        try {
            yield request<
                RequestRouteScannerResultIgnorePost,
                ParamsRouteScannerResultIgnorePost,
                ResponseRouteScannerResultIgnorePost
            >({
                location: locationRestScannerResultIgnorePost,
                request: {
                    type: "template",
                    value: this.identifier,
                    ignored: state,
                },
            });

            this.data.consumerData.isIgnored = state;
        } catch (e) {
            console.log(e);
            throw e;
        } finally {
            this.busy = false;
        }
    });
}

export { ScannerResultTemplate };
