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

import { request } from "../utils/request.js";
import { locationRestAttachmentDelete } from "../wp-api/attachment.delete.js";
import { locationRestAttachmentPost } from "../wp-api/attachment.post.js";

import type {
    ParamsRestAttachmentDelete,
    RequestRestAttachmentDelete,
    ResponseRestAttachmentDelete,
} from "../wp-api/attachment.delete.js";
import type { ParamsRestAttachmentGet, ResponseRestAttachmentGet } from "../wp-api/attachment.get.js";
import type {
    ParamsRestAttachmentPost,
    RequestRestAttachmentPost,
    ResponseRestAttachmentPost,
} from "../wp-api/attachment.post.js";

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

class SingleFile {
    @observable
    public id: number;

    @observable
    public filename: string;

    @observable
    public error: string;

    @observable
    public schema: string;

    @observable
    public schemaf: string;

    @observable
    public cntGenerated: number;

    @observable
    public cntRegistered: number;

    @observable
    public filesizeSum: number;

    @observable
    public filesize: number;

    @observable
    public deletableSpace: number;

    @observable
    public deletableSpaceFormat: string;

    @observable
    public filesizeSumFormat: string;

    @observable
    public usedSchema: string;

    @observable
    public newSchema: string;

    @observable
    public newThumbnailsCount: number;

    @observable
    public rows: ResponseRestAttachmentGet["rows"];

    @observable
    public busy = false;

    @computed public get thumbnail() {
        const { thumbnail } = this.rows;
        return thumbnail && thumbnail.filesFound && thumbnail.href;
    }

    @computed public get medium() {
        const { medium } = this.rows;
        return medium && medium.filesFound && medium.href;
    }

    public constructor(singleFile: Partial<ResponseRestAttachmentGet>) {
        runInAction(() => set(this, singleFile));
    }

    public regenerate: (forceNewSchema: boolean, overwrite: boolean) => CancellablePromise<ResponseRestAttachmentGet> =
        flow(function* (this: SingleFile, forceNewSchema, overwrite) {
            this.busy = true;
            try {
                const result: ResponseRestAttachmentPost = yield request<
                    RequestRestAttachmentPost,
                    ParamsRestAttachmentPost,
                    ResponseRestAttachmentPost
                >({
                    location: locationRestAttachmentPost,
                    params: {
                        id: this.id,
                    },
                    request: {
                        forceNewSchema,
                    },
                });
                if (overwrite) {
                    set(this, result);
                }
                return result;
            } catch (e) {
                console.log(e);
                throw e;
            } finally {
                this.busy = false;
            }
        });

    public clear: (overwrite: boolean) => CancellablePromise<ParamsRestAttachmentGet> = flow(function* (
        this: SingleFile,
        overwrite,
    ) {
        if (process.env.PLUGIN_CTX === "pro") {
            /* onlypro:start */
            this.busy = true;
            try {
                const result: ResponseRestAttachmentDelete = yield request<
                    RequestRestAttachmentDelete,
                    ParamsRestAttachmentDelete,
                    ResponseRestAttachmentDelete
                >({
                    location: locationRestAttachmentDelete,
                    params: {
                        id: this.id,
                    },
                });
                if (overwrite) {
                    set(this, result);
                }
                return result;
            } catch (e) {
                console.log(e);
                throw e;
            } finally {
                this.busy = false;
            }
            /* onlypro:end */
        } else {
            throw new Error("This feature is not available in the free version.");
        }
    });
}

export { SingleFile };
