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

import { request } from "../utils/request.js";
import { locationRestLicenseDelete } from "../wp-api/license.delete.js";
import { locationRestLicenseRetry } from "../wp-api/licenseRetry.post.js";
import { locationRestLicenseTelemetryGet } from "../wp-api/licenseTelemetry.get.js";

import type { PluginUpdate } from "./pluginUpdate.js";
import type {
    ParamsRouteLicenseDelete,
    RequestRouteLicenseDelete,
    ResponseRouteLicenseDelete,
} from "../wp-api/license.delete.js";
import type {
    ParamsRouteLicenseRetry,
    RequestRouteLicenseRetry,
    ResponseRouteLicenseRetry,
} from "../wp-api/licenseRetry.post.js";
import type {
    ParamsRouteLicenseTelemetryGet,
    RequestRouteLicenseTelemetryGet,
    ResponseRouteLicenseTelemetryGet,
} from "../wp-api/licenseTelemetry.get.js";
import type { ResponseRoutePluginUpdateGetLicenseEntity } from "../wp-api/pluginUpdate.get.js";

class License {
    @observable
    public busy = false;

    @observable
    public uuid: ResponseRoutePluginUpdateGetLicenseEntity["uuid"];

    @observable
    public blog: ResponseRoutePluginUpdateGetLicenseEntity["blog"];

    @observable
    public host: ResponseRoutePluginUpdateGetLicenseEntity["host"];

    @observable
    public programmatically: ResponseRoutePluginUpdateGetLicenseEntity["programmatically"];

    @observable
    public blogName: ResponseRoutePluginUpdateGetLicenseEntity["blogName"];

    @observable
    public installationType: ResponseRoutePluginUpdateGetLicenseEntity["installationType"];

    @observable
    public telemetryDataSharingOptIn: ResponseRoutePluginUpdateGetLicenseEntity["telemetryDataSharingOptIn"];

    @observable
    public code: ResponseRoutePluginUpdateGetLicenseEntity["code"];

    @observable
    public hint?: ResponseRoutePluginUpdateGetLicenseEntity["hint"];

    @observable
    public remote?: ResponseRoutePluginUpdateGetLicenseEntity["remote"];

    @observable
    public noUsage: ResponseRoutePluginUpdateGetLicenseEntity["noUsage"];

    @observable
    public telemetryData: ResponseRouteLicenseTelemetryGet;

    public readonly store: PluginUpdate;

    public constructor(license: Partial<ResponseRoutePluginUpdateGetLicenseEntity>, store: PluginUpdate) {
        runInAction(() => set(this, license));
        this.store = store;
    }

    public retry: () => Promise<void> = flow(function* (this: License) {
        this.busy = true;
        try {
            const result: ResponseRouteLicenseDelete = yield request<
                RequestRouteLicenseRetry,
                ParamsRouteLicenseRetry,
                ResponseRouteLicenseRetry
            >({
                location: locationRestLicenseRetry,
                params: {
                    slug: this.store.slug,
                    blogId: this.blog,
                },
            });

            set(this, result);
        } catch (e) {
            console.log(e);
            throw e;
        } finally {
            this.busy = false;
        }
    });

    public deactivate: () => Promise<void> = flow(function* (this: License) {
        this.busy = true;
        try {
            const result: ResponseRouteLicenseDelete = yield request<
                RequestRouteLicenseDelete,
                ParamsRouteLicenseDelete,
                ResponseRouteLicenseDelete
            >({
                location: locationRestLicenseDelete,
                params: {
                    slug: this.store.slug,
                    blogId: this.blog,
                },
            });

            set(this, result);
        } catch (e) {
            console.log(e);
            throw e;
        } finally {
            this.busy = false;
        }
    });

    public fetchTelemetryData: () => Promise<void> = flow(function* (this: License) {
        this.busy = true;
        try {
            const result: ResponseRouteLicenseDelete = yield request<
                RequestRouteLicenseTelemetryGet,
                ParamsRouteLicenseTelemetryGet,
                ResponseRouteLicenseTelemetryGet
            >({
                location: locationRestLicenseTelemetryGet,
                params: {
                    slug: this.store.slug,
                    blogId: this.blog,
                },
            });

            this.telemetryData = result;
        } catch (e) {
            console.log(e);
            throw e;
        } finally {
            this.busy = false;
        }
    });
}

export { License };
