import { useMemo } from "react";
import React from "react";
import { Responsive, WidthProvider } from "react-grid-layout";

import { Widget } from "@onvo-ai/js";
import ChartCard from "../Chart/ChartCard";
import { useDashboard } from "../../layouts/Dashboard/useDashboard";
import { useBackend } from "../../layouts/Wrapper";
import { TextWidgetModal } from "../TextWidgetModal";
import { ImageWidgetModal } from "../ImageWidgetModal";
import { EditWidgetModal } from "../EditWidgetModal";
import { Content } from "@radix-ui/react-tabs";

export const DashboardGrid: React.FC<{ className?: string }> = ({ className }) => {
  const { dashboard, widgets: allWidgets, setWidgets } = useDashboard();
  const { backend, adminMode } = useBackend();

  const ResponsiveGridLayout = useMemo(
    () => WidthProvider(Responsive) as any,
    []
  );

  const editable = useMemo(() => {
    return adminMode || dashboard?.settings?.can_edit_widget_layout;
  }, [adminMode, dashboard]);

  const grid_spacing = useMemo(() => {
    return dashboard?.settings?.grid_spacing === undefined
      ? 10
      : dashboard?.settings?.grid_spacing;
  }, [dashboard]);


  const grid_height = useMemo(() => {
    return dashboard?.settings?.grid_height === undefined
      ? 10
      : dashboard?.settings?.grid_height;
  }, [dashboard]);

  if (!dashboard)
    return (
      <div
        className={
          "onvo-dashboard-grid-wrapper onvo-overflow-y-auto onvo-flex-grow onvo-pt-2 onvo-font-override onvo-background-color onvo-relative onvo-w-full " + (className || "")
        }
      ></div>
    );

  if (
    allWidgets.length === 0 &&
    (dashboard?.settings?.can_create_widgets || adminMode)
  ) {
    return (
      <div
        className={
          "onvo-dashboard-grid-wrapper onvo-overflow-y-auto onvo-flex-grow onvo-pt-2 onvo-font-override onvo-background-color onvo-relative onvo-w-full " + (className || "")
        }
      >
        <TextWidgetModal />
        <ImageWidgetModal />
        <EditWidgetModal />
      </div>
    );
  }
  return (
    <>
      <TextWidgetModal />
      <ImageWidgetModal />
      <EditWidgetModal />

      <div
        className={
          "onvo-dashboard-grid-wrapper onvo-overflow-y-auto onvo-pt-6 onvo-scrollbar-thin onvo-flex-grow onvo-font-override onvo-background-color onvo-w-full " + (className || "")
        }
      >
        {(dashboard?.tabs || []).filter(a => !a.hidden).map((currentTab) => {
          const filteredWidgets = allWidgets.filter((i: Widget) => {
            return i.tab === currentTab.id;
          });

          const layouts =
            filteredWidgets.length === 0
              ? { lg: [], sm: [] }
              : {
                lg: filteredWidgets.map((i: Widget) => {
                  let layouts = i.layouts;
                  return {
                    i: i.id,
                    x: layouts.lg.x,
                    y: layouts.lg.y,
                    w: layouts.lg.w,
                    h: layouts.lg.h,
                    minH: 4,
                  };
                }),
                sm: filteredWidgets.map((i: Widget) => {
                  let layouts = i.layouts;
                  return {
                    i: i.id,
                    x: layouts.sm?.x || layouts.lg.x,
                    y: layouts.sm?.y || layouts.lg.y,
                    w: layouts.sm?.w || layouts.lg.w,
                    h: layouts.sm?.h || layouts.lg.h,
                    minH: 4,
                  };
                }),
              };

          const widgets = (filteredWidgets || []).map((i: Widget) => (
            <div key={i.id}>
              <ChartCard widget={i} />
            </div>
          ));

          return (
            <Content key={currentTab.id} value={currentTab.id.toString()}>
              <ResponsiveGridLayout
                resizeHandles={["se", "sw"]}
                draggableHandle=".onvo-chart-card-drag-handle"
                className="onvo-dashboard-grid-layout onvo-layout"
                rowHeight={grid_height}
                compactType="vertical"
                margin={[grid_spacing, grid_spacing]}
                breakpoints={{ lg: 720, sm: 480 }}
                cols={{ lg: 12, sm: 4 }}
                isDraggable={editable}
                isResizable={editable}
                layouts={layouts}
                containerPadding={[grid_spacing * 2, grid_spacing]}
                onLayoutChange={(layout: any, allLayouts: any) => {
                  if (!dashboard || !editable) return;

                  let newWidgets = allWidgets.filter(b => b.tab === currentTab.id).map((i: any) => {
                    let lgLayout = {
                      ...allLayouts.lg.find((j: any) => j.i === i.id),
                    };
                    let smLayout = {
                      ...allLayouts.sm.find((j: any) => j.i === i.id),
                    };

                    return {
                      ...i,
                      layouts: {
                        lg: {
                          ...i.layouts.lg,
                          h: lgLayout.h,
                          w: lgLayout.w,
                          x: lgLayout.x,
                          y: lgLayout.y,

                        },
                        sm: {
                          ...i.layouts.sm,
                          h: smLayout.h,
                          w: smLayout.w,
                          x: smLayout.x,
                          y: smLayout.y,
                        },
                      },
                    };
                  });

                  // UPDATE ONLY THE WIDGETS THAT CHANGED
                  let updatedWidgets = newWidgets.filter((widget) => {
                    let oldWidget = allWidgets.find((i: any) => i.id === widget.id);
                    if (!oldWidget) return true;
                    return (
                      JSON.stringify(oldWidget.layouts) !==
                      JSON.stringify(widget.layouts)
                    );
                  });

                  if (dashboard && editable && updatedWidgets.length > 0) {
                    setWidgets([
                      ...allWidgets.filter((i) => i.tab !== currentTab.id),
                      ...newWidgets
                    ]);

                    updatedWidgets.forEach((i) => {
                      backend?.widgets.update(i.id, {
                        layouts: i.layouts,
                      });
                    });
                  }
                }}
              >
                {widgets}
              </ResponsiveGridLayout>
            </Content>
          );
        })}
      </div>
    </>
  );
};
