import { computed, flow } from "mobx";

import { AbstractPostCollection, ClientCollection, RouteHttpVerb } from "@devowl-wp/utils";

import { CookieModel } from "./cookieModel.js";
import { request } from "../utils/request.js";
import { locationRestCookiesOrderPut } from "../wp-api/cookiesOrder.put.js";

import type { CookieGroupModel } from "./cookieGroupModel.js";
import type {
    ParamsRouteCookiesOrderPut,
    RequestRouteCookiesOrderPut,
    ResponseRouteCookiesOrderPut,
} from "../wp-api/cookiesOrder.put.js";

@ClientCollection.annotate({
    path: "/rcb-cookie",
    singlePath: "/rcb-cookie/:id",
    namespace: "wp/v2",
    methods: [RouteHttpVerb.GET],
    request,
})
class CookieCollection extends AbstractPostCollection<
    CookieModel,
    {
        "rcb-cookie-group"?: number | number[] | "";
        "rcb-cookie-group_exclude"?: number | number[];
    }
> {
    public readonly store: CookieGroupModel;

    @computed
    public get sortedCookies() {
        const result = Array.from(this.entries.values());
        result.sort((a, b) => {
            if (a.data.menu_order < b.data.menu_order) {
                return -1;
            } else if (a.data.menu_order > b.data.menu_order) {
                return 1;
            } else {
                // a.menu_order === b.menu_order
                if (a.key < b.key) {
                    return 1;
                } else if (a.key > b.key) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        return result;
    }

    public orderCookies: (ids: number[]) => Promise<void> = flow(function* (this: CookieCollection, ids) {
        this.busy = true;
        try {
            yield request<RequestRouteCookiesOrderPut, ParamsRouteCookiesOrderPut, ResponseRouteCookiesOrderPut>({
                location: locationRestCookiesOrderPut,
                request: {
                    ids,
                },
            });

            // Apply the order to existing cached models instead of fetching again
            let i = 0;
            for (const id of ids) {
                const cookie = this.entries.get(id);
                cookie.setOrder(i);
                i++;
            }
        } catch (e) {
            console.log(e);
            throw e;
        } finally {
            this.busy = false;
        }
    });

    public constructor(store: CookieGroupModel) {
        super();
        this.store = store;
    }

    public instance(response: CookieModel["data"]): CookieModel {
        return new CookieModel(this).fromResponse(response);
    }
}

export { CookieCollection };
