import { create } from "zustand";
import { Onvo, Dashboard, DataSource, Widget } from "@onvo-ai/js";
import { waitForJob } from "../../lib/waitForJob";
import { RequestQueue } from "./Queue";
interface DashboardState {
  id: string | undefined;
  setId: (id: string, backend: Onvo) => void;

  unauthorized: boolean;
  loading: boolean;
  refreshing: boolean;

  dashboard: Dashboard | undefined;
  setDashboard: (dashboard: Dashboard | undefined) => void;

  widgets: Widget[];
  setWidgets: (widgets: Widget[]) => void;
  refreshWidgets: (backend: Onvo, widgetId?: string) => Promise<void>;

  tab: number;
  setTab: (tab: number) => void;

  datasources: DataSource[];
  queue: RequestQueue;
}

export const useDashboard = create<DashboardState>((set, get) => ({
  id: undefined,
  loading: false,
  refreshing: false,
  dashboard: undefined,
  widgets: [],
  datasources: [],
  unauthorized: false,
  tab: 0,
  setTab: (tab) => set({ tab }),
  queue: new RequestQueue(5),
  setId: (id, backend) => {
    let loading = get().loading;
    set({ id, loading: true });

    backend.datasources.list({ dashboard: id }).then(ds => {
      set({ datasources: ds });
    });

    backend.dashboards.get(id).then((dash) => {
      set({
        dashboard: dash,
        loading: false,
      });
      const interval = dash.settings?.cache_refresh_interval || 5;
      const nextUpdate = new Date(dash.last_updated_at).getTime() + (interval * 60000);
      if (
        !loading &&
        nextUpdate < new Date().getTime()
      ) {
        set({ refreshing: true });
        backend
          ?.dashboard(id)
          .updateCache()
          .then(async (data) => {

            if (data._meta.total === 0) {
              set({
                loading: false,
                refreshing: false,
              });
              return;
            }

            try {
              await waitForJob(
                data._meta.url,
                "The dashboard is being automatically updated"
              );
            } catch (e) {
              console.error(e);
              set({ refreshing: false, loading: false });
            }

            let id = get().id;

            if (id === data.id) {
              backend.widgets.list({ dashboard: id }).then((wid) => {
                set({ widgets: wid });
              });

              set({
                loading: false,
                refreshing: false,
                dashboard: {
                  ...dash,
                  last_updated_at: new Date().toISOString(),
                },
              });
            } else {
              set({
                loading: false,
                refreshing: false,
              });
            }
          });
      }
    }).catch((e) => {
      if (e.message === "Your subscription is not active") {
        set({ unauthorized: true });
      }
    })
  },
  setDashboard: (dashboard) => set({ dashboard }),
  setWidgets: (widgets) => set({ widgets }),
  refreshWidgets: async (backend, widgetId?: string) => {
    let id = get().id;

    if (!id) return;
    if (widgetId) {
      let widgets = get().widgets;
      backend.widgets.get(widgetId).then((wid) => {
        set({
          widgets: widgets.map((w) => {
            if (w.id === wid.id) {
              return wid;
            }
            return w;
          })
        });
      });
    } else {
      backend.widgets.list({ dashboard: id }).then((wid) => {
        set({ widgets: wid });
      });
    }
  }
}));
