import { action, flow, observable, runInAction } from "mobx";
import moment from "moment";

import { BaseOptions } from "@devowl-wp/utils";

import { request } from "../utils/request.js";
import { locationRestStatsButtonsClickedGet } from "../wp-api/statsButtonsClicked.js";
import { locationRestStatsCustomBypassGet } from "../wp-api/statsCustomBypass.get.js";
import { locationRestStatsMainGet } from "../wp-api/statsMain.get.js";

import type { RootStore } from "./stores.js";
import type {
    ParamsRouteStatsButtonsClickedGet,
    RequestRouteStatsButtonsClickedGet,
    ResponseRouteStatsButtonsClickedGet,
} from "../wp-api/statsButtonsClicked.js";
import type {
    ParamsRouteStatsCustomBypassGet,
    RequestRouteStatsCustomBypassGet,
    ResponseRouteStatsCustomBypassGet,
} from "../wp-api/statsCustomBypass.get.js";
import type {
    ParamsRouteStatsMainGet,
    RequestRouteStatsMainGet,
    ResponseRouteStatsMainGet,
    ResponseRouteStatsMainGetEntry,
} from "../wp-api/statsMain.get.js";

const DATE_FORMAT = "YYYY-MM-DD";

class StatsStore extends BaseOptions {
    @observable
    public busyStats = {
        main: false,
        buttonClicked: false,
        customBypass: false,
    };

    public readonly rootStore: RootStore;

    public stats: {
        main: ResponseRouteStatsMainGetEntry[];
        buttonsClicked: ResponseRouteStatsButtonsClickedGet;
        customBypass: ResponseRouteStatsCustomBypassGet;
    } = observable.object(
        {
            main: undefined,
            buttonsClicked: undefined,
            customBypass: undefined,
        },
        {},
        { deep: false },
    );

    public filters: {
        dates: [moment.Moment, moment.Moment];
        context: string;
    } = observable.object(
        {
            dates: undefined,
            context: undefined,
        },
        {},
        { deep: false },
    );

    public constructor(rootStore: RootStore) {
        super();
        this.rootStore = rootStore;
        runInAction(() => {
            this.filters.dates = [moment().subtract(30, "days"), moment()];
            this.filters.context = this.rootStore.optionStore.others.context;
        });
    }

    /**
     * This action does not actually refetch the stats, you need to act on your components!
     *
     * @param dates
     */
    @action
    public applyDates(dates: StatsStore["filters"]["dates"]) {
        this.filters.dates = dates;
    }

    /**
     * This action does not actually refetch the stats, you need to act on your components!
     *
     * @param context
     */
    @action
    public applyContext(context: StatsStore["filters"]["context"]) {
        this.filters.context = context;
    }

    public fetchMain: () => Promise<void> = flow(function* (this: StatsStore) {
        if (process.env.PLUGIN_CTX === "pro") {
            /* onlypro:start */
            this.busyStats.main = true;
            try {
                const dates = this.filters.dates.map((m) => m.format(DATE_FORMAT)) as [string, string];
                const result: ResponseRouteStatsMainGet = yield request<
                    RequestRouteStatsMainGet,
                    ParamsRouteStatsMainGet,
                    ResponseRouteStatsMainGet
                >({
                    location: locationRestStatsMainGet,
                    params: {
                        from: dates[0],
                        to: dates[1],
                        context: this.filters.context,
                    },
                });

                this.stats.main = result;

                if (result.length > 0) {
                    this.rootStore.checklistStore.probablyFetchByChangedItem("view-stats");
                }
            } catch (e) {
                console.log(e);
                throw e;
            } finally {
                this.busyStats.main = false;
            }
            /* onlypro:end */
        } else {
            throw new Error("This feature is not available in the free version.");
        }
    });

    public fetchButtonsClicked: () => Promise<void> = flow(function* (this: StatsStore) {
        if (process.env.PLUGIN_CTX === "pro") {
            /* onlypro:start */
            this.busyStats.buttonClicked = true;
            try {
                const dates = this.filters.dates.map((m) => m.format(DATE_FORMAT)) as [string, string];
                const result: ResponseRouteStatsButtonsClickedGet = yield request<
                    RequestRouteStatsButtonsClickedGet,
                    ParamsRouteStatsButtonsClickedGet,
                    ResponseRouteStatsButtonsClickedGet
                >({
                    location: locationRestStatsButtonsClickedGet,
                    params: {
                        from: dates[0],
                        to: dates[1],
                        context: this.filters.context,
                    },
                });

                this.stats.buttonsClicked = result;
            } catch (e) {
                console.log(e);
                throw e;
            } finally {
                this.busyStats.buttonClicked = false;
            }
            /* onlypro:end */
        } else {
            throw new Error("This feature is not available in the free version.");
        }
    });

    public fetchCustomBypass: () => Promise<void> = flow(function* (this: StatsStore) {
        if (process.env.PLUGIN_CTX === "pro") {
            /* onlypro:start */
            this.busyStats.customBypass = true;
            try {
                const dates = this.filters.dates.map((m) => m.format(DATE_FORMAT)) as [string, string];
                const result: ResponseRouteStatsCustomBypassGet = yield request<
                    RequestRouteStatsCustomBypassGet,
                    ParamsRouteStatsCustomBypassGet,
                    ResponseRouteStatsCustomBypassGet
                >({
                    location: locationRestStatsCustomBypassGet,
                    params: {
                        from: dates[0],
                        to: dates[1],
                        context: this.filters.context,
                    },
                });

                this.stats.customBypass = result;
            } catch (e) {
                console.log(e);
                throw e;
            } finally {
                this.busyStats.customBypass = false;
            }
            /* onlypro:end */
        } else {
            throw new Error("This feature is not available in the free version.");
        }
    });
}

export { StatsStore };
