import { flow, observable } from "mobx";

import { SeoItem } from "./seoItem.js";
import { request } from "../utils/request.js";
import { locationRestSeoAttachmentOlderGet } from "../wp-api/seo-attachment-older.get.js";
import { locationRestSeoAttachmentThumbsGet } from "../wp-api/seo-attachment-thumbs.get.js";

import type { SeoStore } from "../store/seo.js";
import type { ClassProperties } from "../utils/types.js";
import type {
    ParamsRestSeoAttachmentOlderGet,
    RequestRestSeoAttachmentOlderGet,
    ResponseRestSeoAttachmentOlderGet,
} from "../wp-api/seo-attachment-older.get.js";
import type {
    ParamsRestSeoAttachmentThumbsGet,
    RequestRestSeoAttachmentThumbsGet,
    ResponseRestSeoAttachmentThumbsGet,
} from "../wp-api/seo-attachment-thumbs.get.js";

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

class SeoOriginalItem extends SeoItem {
    @observable
    public thumbnail = "";

    @observable
    public thumbs = 0;

    @observable
    public older = 0;

    @observable
    public fetchedThumbnails = false;

    @observable
    public fetchedOlder = false;

    @observable
    public thumbnails: SeoItem[] = [];

    @observable
    public olderEntries: SeoOriginalItem[] = [];

    @observable
    public busy = false;

    public constructor(seoOriginalItem: Partial<ClassProperties<SeoOriginalItem>>, seoStore: SeoStore) {
        super(seoOriginalItem, seoStore);
    }

    public fetchThumbnails: () => CancellablePromise<void> = flow(function* (this: SeoOriginalItem) {
        this.fetchedThumbnails = true;
        this.busy = true;
        this.thumbnails = [];

        const { items } = (yield request<
            RequestRestSeoAttachmentThumbsGet,
            ParamsRestSeoAttachmentThumbsGet,
            ResponseRestSeoAttachmentThumbsGet
        >({
            location: locationRestSeoAttachmentThumbsGet,
            params: {
                processId: this.processId,
            },
        })) as ResponseRestSeoAttachmentThumbsGet;

        this.thumbnails = items.map((i) => new SeoItem({ ...i, type: "thumbnail", original: this }, this.seoStore));
        this.busy = false;
    });

    public fetchOlder: () => CancellablePromise<void> = flow(function* (this: SeoOriginalItem) {
        this.fetchedThumbnails = true;
        this.busy = true;
        this.thumbnails = [];

        const { items } = (yield request<
            RequestRestSeoAttachmentOlderGet,
            ParamsRestSeoAttachmentOlderGet,
            ResponseRestSeoAttachmentOlderGet
        >({
            location: locationRestSeoAttachmentOlderGet,
            params: {
                id: this.attachment,
            },
        })) as ResponseRestSeoAttachmentOlderGet;

        this.olderEntries = items.map(
            (i) => new SeoOriginalItem({ ...i, type: "older", original: this }, this.seoStore),
        );
        this.busy = false;
    });
}

export { SeoOriginalItem };
