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

  unauthorized: boolean;
  loading: boolean;
  refreshing: boolean;
  progress: number;

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

  widgetsLoaded: boolean;
  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,
  progress: 0,
  setTab: (tab) => set({ tab }),
  queue: new RequestQueue(25),
  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) => {
      let initialTab = 0;
      if (dash.tabs && dash.tabs.length > 0) {
        initialTab = Math.min(...(dash.tabs.map(a => a.id))) || 0;
      }
      set({
        dashboard: dash,
        loading: false,
        tab: initialTab
      });

      if (
        !loading
      ) {
        set({ refreshing: true, progress: 0 });
        backend
          ?.dashboard(id)
          .updateCache(evt => {
            if (evt.progress) {
              set({ progress: evt.progress.completed / evt.progress.total });
            }
          })
          .then(async (data) => {
            let id = get().id;

            // @ts-ignore
            if (!data || !data.id) {
              set({
                loading: false,
                refreshing: false,
                dashboard: {
                  ...dash,
                  last_updated_at: new Date().toISOString(),
                },
              });
            }
            else if (id === data.id) {
              backend.widgets.list({ dashboard: id }).then((wid) => {
                set({ widgets: wid });
                toast.success("Dashboard successfully refreshed");
              });

              set({
                loading: false,
                refreshing: false,
                dashboard: {
                  ...dash,
                  last_updated_at: new Date().toISOString(),
                },
              });
            } else {
              set({
                loading: false,
                refreshing: false,
              });
            }
          }).catch(e => {
            toast.error(e.message, {
              duration: Infinity,
              closeButton: true
            });
          });
      }
    }).catch((e) => {
      if (e.message === "Your subscription is not active") {
        set({ unauthorized: true });
      }
    })
  },
  setDashboard: (dashboard) => set({ dashboard }),
  widgetsLoaded: false,
  setWidgets: (widgets) => set({ widgets, widgetsLoaded: true }),
  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, widgetsLoaded: true });
      });
    }
  }
}));
