import React, { useEffect, useMemo, useRef, useState } from "react";
import { EllipsisVerticalIcon } from "@heroicons/react/20/solid";
import { toast } from "sonner";
import { LogType, Widget } from "@onvo-ai/js";
import {
  ArrowsRightLeftIcon,
  DocumentChartBarIcon,
  DocumentDuplicateIcon,
  FunnelIcon,
  PencilSquareIcon,
  PhotoIcon,
  TrashIcon,
} from "@heroicons/react/24/outline";

import ChartBase from "./ChartBase";
import { Card } from "../../tremor/Card";
import { Icon } from "../../tremor/Icon";
import { useDashboard } from "../../layouts/Dashboard/useDashboard";
import { useBackend } from "../../layouts/Wrapper";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuIconWrapper,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuSubMenu,
  DropdownMenuSubMenuContent,
  DropdownMenuSubMenuTrigger,
  DropdownMenuTrigger,
} from "../../tremor/DropdownMenu";
import { useTextWidgetModal } from "../TextWidgetModal";
import { useImageWidgetModal } from "../ImageWidgetModal";
import { useEditWidgetModal } from "../EditWidgetModal";
import { useTheme } from "../../layouts/Dashboard/useTheme";
import { ExclamationTriangleIcon } from "@heroicons/react/16/solid";
import { SortDirection } from "react-data-grid";
import { usePagination } from "./usePagination";
import { PaginationComponent } from "./PaginationComponent";
import { ChartPlaceholder } from "../ChartLoader";
import { useDrilldownModal } from "../DrilldownModal";

const DragHandle = () => {
  return (
    <div className="onvo-absolute -onvo-top-6 onvo-w-10 onvo-h-6 onvo-z-10 onvo-hidden group-hover/chartcard:onvo-flex onvo-transition-all onvo-left-[50%] -onvo-ml-5 onvo-justify-center onvo-items-center onvo-foreground-color onvo-border-solid onvo-border onvo-border-b-0 onvo-border-black/5 dark:onvo-border-white/10 onvo-rounded-t-md">
      <div className="onvo-chart-card-drag-handle  onvo-absolute onvo-grid-cols-4 onvo-py-1 onvo-cursor-move onvo-grid onvo-px-1 onvo-items-center onvo-justify-center onvo-h-6 onvo-w-10">
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
        <div className="onvo-h-[3px] onvo-w-[3px] onvo-ml-0.5 onvo-rounded-full onvo-bg-black/20 dark:onvo-bg-white/20"></div>
      </div></div>
  );
};

const ChartCard: React.FC<{
  widget: Widget;
  className?: string;
  hideOptions?: boolean;
  footer?: React.ReactNode;
}> = ({ widget, className, footer, hideOptions }) => {
  const { dashboard, refreshWidgets, tab, queue } = useDashboard();
  const { setOpen: setEditModalOpen } = useEditWidgetModal();
  const { setOpen: setTextModalOpen } = useTextWidgetModal();
  const { setOpen: setImageModalOpen } = useImageWidgetModal();
  const { setOpen: setDrilldownModalOpen } = useDrilldownModal();
  const { backend, adminMode, containerRef } = useBackend();
  const theme = useTheme();
  const cardRef = useRef(null);
  const [cache, setCache] = useState<any>(null);

  // Use pagination store
  const {
    pagination,
    setStats,
    stats,
    setPagination,
    resetPagination
  } = usePagination();



  const duplicate = async () => {
    let newObj: any = { ...widget };
    delete newObj.id;

    if (!backend) return;
    toast.promise(
      async () => {
        let wid = await backend.widgets.create(newObj);
        let data = await backend.widget(wid.id).updateCache();
        return wid;
      },
      {
        loading: "Duplicating widget...",
        success: (newWidget) => {
          refreshWidgets(backend);
          backend.logs.create({
            type: LogType.CreateWidget,
            dashboard: widget.dashboard,
            widget: newWidget.id,
          })

          return "Widget duplicated";
        },
        error: (error) => "Error duplicating widget: " + error.message,
      }
    );
  };

  const moveTab = async (newTab: number) => {
    let newObj: any = { ...widget, tab: newTab };

    if (!backend) return;
    toast.promise(
      () => {
        return backend.widgets.update(widget.id, newObj) as Promise<any>;
      },
      {
        loading: "Moving widget...",
        success: (newWidget) => {
          refreshWidgets(backend);

          return "Widget moved";
        },
        error: (error) => "Error moving widget: " + error.message,
      }
    );
  };

  const deleteWidget = async () => {
    if (!backend) return;
    toast.promise(
      () => {
        return backend.widgets.delete(widget.id);
      },
      {
        loading: "Deleting widget...",
        success: () => {
          backend.logs.create({
            type: LogType.DeleteWidget,
            dashboard: widget.dashboard
          });
          refreshWidgets(backend);
          return "Widget deleted";
        },
        error: (error) => "Error deleting widget: " + error.message,
      }
    );
  };

  const exportWidget = (format: "svg" | "png" | "csv" | "xlsx" | "jpeg") => {
    if (!backend) return;
    toast.promise(
      () => {
        return backend.widget(widget.id).export(format, theme, (event) => {
          console.log("EVENT: ", event);
        });
      },
      {
        loading: `Exporting widget as ${format}...`,
        success: async (output: any) => {
          try {
            // Get the file URL, replacing host.docker.internal with localhost if needed
            const fileUrl = output.url.replace("host.docker.internal", "localhost");

            // Create a link element
            const link = document.createElement('a');
            link.href = fileUrl;
            link.download = output.fileName || `export.${format}`; // Set the filename
            link.style.display = 'none';

            // Add to document, click and remove
            document.body.appendChild(link);
            link.click();

            // Clean up
            setTimeout(() => {
              document.body.removeChild(link);
            }, 100);
          } catch (error) {
            console.error('Download failed:', error);
            toast.error('Download failed. Please try again.');
          }

          return "Widget exported";
        },
        error: (error) => "Error exporting widget: " + error.message,
      }
    );
  };

  // Function to fetch paginated data from server
  const fetchPaginatedData = async (page: number, size: number, column?: string, direction?: SortDirection) => {
    if (!backend || !widget || !widget.code || widget.code.trim() === "") return;
    try {
      // Fetch paginated data from server
      const { data, pagination: paginationData } = await queue.add(() => backend.widget(widget.id).cache({
        page,
        pageSize: size,
        sortField: column,
        sortDirection: direction === "DESC" ? "desc" : "asc"
      }));

      setCache(data);
      // Update cache with paginated data
      if (paginationData) {
        // Update pagination metadata
        setStats({
          totalRows: paginationData.totalRows || 0,
          totalPages: paginationData.totalPages || 1
        });
      }
    } catch (error) {
      console.error("Error fetching paginated data:", error);
    }
  };

  // Handle sort change from pagination store
  const updatePagination = (newPagination: any) => {
    if (!newPagination) return;
    fetchPaginatedData(pagination.currentPage, pagination.pageSize, pagination.sortColumn || undefined, pagination.sortDirection || undefined);
    setPagination(newPagination);
  };

  useEffect(() => {
    if (!widget || !backend) return;

    // Function to fetch cache from server
    const fetchServerCache = async () => {
      if (!backend || !widget) return null;
      try {
        const { data: cacheData } = await queue.add(() => backend.widget(widget.id).cache());
        // Update component state
        setCache(cacheData);
      } catch (error) {
        console.error("Error fetching widget cache from server:", error);
      }
    };

    // Fetch data from server
    fetchServerCache();

    // Reset pagination when widget changes
    return () => {
      resetPagination();
    };
  }, [widget, backend]);


  const layout_editable =
    adminMode || dashboard?.settings?.can_edit_widget_layout;
  const widget_editable = adminMode || dashboard?.settings?.can_edit_widgets;
  const addable = adminMode || dashboard?.settings?.can_create_widgets;
  const deletable = adminMode || dashboard?.settings?.can_delete_widgets;

  const ImageDownloadEnabled = useMemo(() => {
    if (adminMode) return true;
    if (dashboard?.settings && dashboard.settings.disable_download_images)
      return false;
    return true;
  }, [dashboard, widget, adminMode]);

  const ReportDownloadEnabled = useMemo(() => {
    if (adminMode) return true;
    if (dashboard?.settings && dashboard.settings.disable_download_reports)
      return false;
    return true;
  }, [dashboard, widget, adminMode]);

  const error = useMemo(() => {
    if (widget && widget.error && widget_editable) {
      return (
        <div onClick={() =>
          setEditModalOpen(true, widget)} className="onvo-absolute onvo-right-4 onvo-bottom-4 onvo-rounded-full onvo-shadow-lg onvo-foreground-color onvo-z-10 onvo-border onvo-border-black/5 dark:onvo-border-white/10">
          <div className="onvo-flex onvo-cursor-pointer onvo-items-center onvo-justify-center onvo-size-10">
            <ExclamationTriangleIcon className="onvo-text-red-500 onvo-size-5" />
          </div>
        </div>)

    }
    return <></>;
  }, [widget]);

  const moveDropdown = useMemo(() => {

    const editable = adminMode || dashboard?.settings?.can_edit_tabs;
    if ((dashboard?.tabs || []).length <= 1) {
      return <></>;
    }
    if (!editable) return;
    return (<DropdownMenuSubMenu>
      <DropdownMenuSubMenuTrigger>
        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
          <ArrowsRightLeftIcon className="onvo-size-4" />
          <span>Move widget</span>
        </span>
      </DropdownMenuSubMenuTrigger>
      <DropdownMenuSubMenuContent className="!onvo-bg-transparent onvo-backdrop-blur-lg">
        <div className="onvo-w-full onvo-absolute onvo-top-0 onvo-left-0 onvo-right-0 onvo-bottom-0 onvo-foreground-color onvo-opacity-50 onvo-rounded-lg -onvo-z-10"></div>
        {dashboard?.tabs.map(a => (

          <DropdownMenuItem key={a.id} onClick={() => moveTab(a.id)}>
            <span className="onvo-flex onvo-items-center onvo-gap-x-2">
              <span>{a.label}</span>
            </span>
          </DropdownMenuItem>
        ))}

      </DropdownMenuSubMenuContent>
    </DropdownMenuSubMenu>)

  }, [tab, dashboard]);


  const border_radius = useMemo(() => {
    return dashboard?.settings?.widget_border_radius === undefined
      ? 16
      : dashboard?.settings?.widget_border_radius;
  }, [dashboard]);



  if (widget.type === "divider") {
    return (
      <div ref={cardRef}
        className={
          "onvo-group/chartcard onvo-relative onvo-h-full onvo-w-full onvo-py-0 !onvo-bg-transparent !onvo-border-0 !onvo-ring-0 !onvo-shadow-none onvo-px-0 " +
          (className || "")
        }
      >
        {layout_editable && !hideOptions && <DragHandle />}
        {deletable && !hideOptions && (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Icon
                className="!onvo-rounded-full onvo-z-20 group-hover/chartcard:onvo-opacity-100 onvo-transition-all onvo-opacity-0  onvo-cursor-pointer onvo-font-override onvo-absolute onvo-top-1 onvo-right-1"
                icon={EllipsisVerticalIcon}
                variant="shadow"
              />
            </DropdownMenuTrigger>
            <DropdownMenuContent container={containerRef?.current} className="!onvo-backdrop-blur-lg onvo-min-w-56 onvo-z-50">

              <div className="onvo-w-full onvo-absolute onvo-top-0 onvo-left-0 onvo-right-0 onvo-bottom-0 onvo-foreground-color onvo-opacity-50 onvo-rounded-lg -onvo-z-10"></div>
              {deletable && (
                <DropdownMenuGroup>
                  <DropdownMenuItem onClick={deleteWidget}>
                    <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                      <TrashIcon className="onvo-size-4 onvo-text-red-500" />
                      <span className="onvo-text-red-500">Delete widget</span>
                    </span>
                  </DropdownMenuItem>
                </DropdownMenuGroup>
              )}
            </DropdownMenuContent>
          </DropdownMenu>
        )}
        <ChartBase json={cache} title="" />
        {footer}
      </div>
    );
  }
  if (widget.type === "text") {
    let config = (widget.config as any);
    let sub = config?.options?.plugins?.subtitle.text || "";
    if (typeof sub !== "string") {
      sub = sub.join("<br />");
    }
    return (
      <div ref={cardRef}
        className={
          "onvo-group/chartcard onvo-relative onvo-h-full onvo-w-full onvo-py-0 !onvo-bg-transparent !onvo-border-0 !onvo-ring-0 !onvo-shadow-none onvo-px-0 " +
          (className || "")
        }
      >
        {layout_editable && !hideOptions && <DragHandle />}
        <div className="onvo-absolute onvo-top-1 onvo-right-1 onvo-flex onvo-flex-row onvo-gap-1">
          {widget.drilldown_widget && (
            <Icon
              onClick={(e) => {
                e.stopPropagation();
                e.preventDefault();
                if (widget.drilldown_widget) {
                  setDrilldownModalOpen(true, widget.drilldown_widget);
                }
              }}
              onMouseDown={(e) => {
                e.stopPropagation();
                e.preventDefault();
              }}
              onMouseUp={(e) => {
                e.stopPropagation();
                e.preventDefault();
              }}
              className="!onvo-rounded-full onvo-z-20 onvo-transition-all group-hover/chartcard:onvo-opacity-100 onvo-opacity-0 onvo-cursor-pointer !onvo-text-gray-500"
              icon={FunnelIcon}
              variant="shadow"
            />)}
          {(widget_editable || deletable) && !hideOptions && (
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Icon
                  className="!onvo-rounded-full onvo-z-20 group-hover/chartcard:onvo-opacity-100 onvo-transition-all onvo-opacity-0 onvo-cursor-pointer onvo-font-override"
                  icon={EllipsisVerticalIcon}
                  variant="shadow"
                />
              </DropdownMenuTrigger>
              <DropdownMenuContent side="bottom" container={containerRef?.current} className="onvo-backdrop-blur-lg onvo-min-w-56 onvo-z-50">
                <div className="onvo-w-full onvo-absolute onvo-top-0 onvo-left-0 onvo-right-0 onvo-bottom-0 onvo-foreground-color onvo-opacity-50 onvo-rounded-lg -onvo-z-10"></div>
                {widget_editable && (
                  <DropdownMenuGroup>
                    <DropdownMenuItem
                      onClick={() => {
                        setTimeout(() => {
                          setTextModalOpen(true, widget);
                        }, 30);
                      }}
                    >
                      <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                        <PencilSquareIcon className="onvo-size-4" />
                        <span>Edit widget</span>
                      </span>
                    </DropdownMenuItem>

                    {moveDropdown}
                  </DropdownMenuGroup>
                )}
                {(widget_editable) &&
                  ImageDownloadEnabled && <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />}
                {ImageDownloadEnabled && (
                  <>
                    <DropdownMenuLabel>Download images</DropdownMenuLabel>
                    <DropdownMenuGroup>
                      <DropdownMenuItem onClick={() => exportWidget("svg")}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <PhotoIcon className="onvo-size-4" />
                          <span>Download as SVG</span>
                        </span>
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={() => exportWidget("png")}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DropdownMenuIconWrapper>
                            <PhotoIcon className="onvo-size-4" />
                          </DropdownMenuIconWrapper>
                          <span>Download as PNG</span>
                        </span>
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={() => exportWidget("jpeg")}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DropdownMenuIconWrapper>
                            <PhotoIcon className="onvo-size-4" />
                          </DropdownMenuIconWrapper>
                          <span>Download as JPEG</span>
                        </span>
                      </DropdownMenuItem>
                    </DropdownMenuGroup>
                  </>
                )}

                {(widget_editable || ImageDownloadEnabled) && deletable && <DropdownMenuSeparator />}
                {deletable && (
                  <DropdownMenuGroup>
                    <DropdownMenuItem onClick={deleteWidget}>
                      <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                        <TrashIcon className="onvo-size-4 onvo-text-red-500" />
                        <span className="onvo-text-red-500">Delete widget</span>
                      </span>
                    </DropdownMenuItem>
                  </DropdownMenuGroup>
                )}
              </DropdownMenuContent>
            </DropdownMenu>
          )}
        </div>
        <ChartBase json={cache} title={widget.title} />
        {footer}
      </div>
    );
  }

  if (widget.type === "image") {
    return (
      <div ref={cardRef}
        className={
          `onvo-chart-card onvo-group/chartcard onvo-transition-all onvo-relative onvo-h-full onvo-w-full onvo-py-0 !onvo-bg-transparent !onvo-border-0 !onvo-ring-0 !onvo-shadow-none onvo-px-0 ` +
          (className || "")
        }
        style={{
          borderRadius: border_radius + "px"
        }}
      >
        {layout_editable && !hideOptions && <DragHandle />}

        <div className="onvo-absolute onvo-top-1 onvo-right-1 onvo-flex onvo-flex-row onvo-gap-1">
          {widget.drilldown_widget && (
            <Icon
              onClick={(e) => {
                e.stopPropagation();
                e.preventDefault();
                if (widget.drilldown_widget) {
                  setDrilldownModalOpen(true, widget.drilldown_widget);
                }
              }}
              onMouseDown={(e) => {
                e.stopPropagation();
                e.preventDefault();
              }}
              onMouseUp={(e) => {
                e.stopPropagation();
                e.preventDefault();
              }}
              className="!onvo-rounded-full onvo-z-20 onvo-transition-all group-hover/chartcard:onvo-opacity-100 onvo-opacity-0 onvo-cursor-pointer !onvo-text-gray-500"
              icon={FunnelIcon}
              variant="shadow"
            />)}
          {(widget_editable || deletable) && !hideOptions && (
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Icon
                  className="!onvo-rounded-full onvo-z-20 group-hover/chartcard:onvo-opacity-100 onvo-opacity-0 onvo-cursor-pointer onvo-font-override"
                  icon={EllipsisVerticalIcon}
                  variant="shadow"
                />
              </DropdownMenuTrigger>
              <DropdownMenuContent container={containerRef?.current} className="onvo-backdrop-blur-lg onvo-min-w-56 onvo-z-50">
                <div className="onvo-w-full onvo-absolute onvo-top-0 onvo-left-0 onvo-right-0 onvo-bottom-0 onvo-foreground-color onvo-opacity-50 onvo-rounded-lg -onvo-z-10"></div>
                {widget_editable && (
                  <DropdownMenuGroup>
                    <DropdownMenuItem
                      onClick={() => {
                        setTimeout(() => {
                          setImageModalOpen(true, widget);
                        }, 30);
                      }}
                    >
                      <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                        <PencilSquareIcon className="onvo-size-4" />
                        <span>Edit widget</span>
                      </span>
                    </DropdownMenuItem>

                    {moveDropdown}
                  </DropdownMenuGroup>
                )}
                {widget_editable && deletable && <DropdownMenuSeparator />}
                {deletable && (
                  <DropdownMenuGroup>
                    <DropdownMenuItem onClick={deleteWidget}>
                      <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                        <TrashIcon className="onvo-size-4 onvo-text-red-500" />
                        <span className="onvo-text-red-500">Delete widget</span>
                      </span>
                    </DropdownMenuItem>
                  </DropdownMenuGroup>
                )}
              </DropdownMenuContent>
            </DropdownMenu>
          )}
        </div>
        <ChartBase json={cache} title={""} />
        {footer}
      </div>
    );
  }


  const paginationEnabled = widget.engine === "manual-v1" && widget.type === "table";
  return (
    <Card
      ref={cardRef}
      key={widget.id}
      id={widget.settings?.css_id}
      className={
        "onvo-chart-card onvo-h-full onvo-group/chartcard onvo-foreground-color onvo-relative onvo-flex onvo-flex-col !onvo-p-0 " +
        (className || "") +
        " " +
        (widget.settings?.css_classnames ? widget.settings?.css_classnames : "")
      }
      style={{
        borderRadius: border_radius + "px"
      }}
      onMouseDown={(e) => {
        const startX = e.clientX;
        const startY = e.clientY;

        const handleMouseUp = (upEvent: any) => {
          if (!cardRef.current) return;
          // Remove the event listener
          // @ts-ignore
          cardRef.current.removeEventListener('mouseup', handleMouseUp);

          // Calculate distance between mousedown and mouseup
          const deltaX = Math.abs(upEvent.clientX - startX);
          const deltaY = Math.abs(upEvent.clientY - startY);
          const threshold = 5; // 5px threshold for considering it a click vs. drag

          // Only trigger if the mouse hasn't moved beyond the threshold
          if (deltaX <= threshold && deltaY <= threshold) {
            if (widget.settings?.link && widget.settings.link.trim() !== "") {
              console.log("CLICKED: ", upEvent, widget.settings?.link);
              window.open(widget.settings.link, "_blank");
            }
          }
        };

        // Add mouseup listener to document to catch mouseup events outside the element
        // @ts-ignore
        cardRef.current?.addEventListener('mouseup', handleMouseUp, { once: true });
      }}
    >
      {error}
      {layout_editable && !hideOptions && <DragHandle />}

      <div className="onvo-absolute onvo-top-1 onvo-right-1 onvo-flex onvo-flex-row onvo-gap-1">
        {widget.drilldown_widget && (
          <Icon
            onClick={(e) => {
              e.stopPropagation();
              e.preventDefault();
              if (widget.drilldown_widget) {
                setDrilldownModalOpen(true, widget.drilldown_widget);
              }
            }}
            onMouseDown={(e) => {
              e.stopPropagation();
              e.preventDefault();
            }}
            onMouseUp={(e) => {
              e.stopPropagation();
              e.preventDefault();
            }}
            className="!onvo-rounded-full onvo-z-20 onvo-transition-all group-hover/chartcard:onvo-opacity-100 onvo-opacity-0 onvo-cursor-pointer !onvo-text-gray-500"
            icon={FunnelIcon}
            variant="shadow"
          />)}

        {(addable ||
          deletable ||
          widget_editable ||
          ImageDownloadEnabled ||
          ReportDownloadEnabled) &&
          !hideOptions && (
            <DropdownMenu modal={false}>
              <DropdownMenuTrigger asChild>
                <Icon
                  onClick={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                  }}
                  onMouseDown={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                  }}
                  onMouseUp={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                  }}
                  className="!onvo-rounded-full onvo-z-20 onvo-transition-all group-hover/chartcard:onvo-opacity-100 onvo-opacity-0 onvo-cursor-pointer !onvo-text-gray-500"
                  icon={EllipsisVerticalIcon}
                  variant="shadow"
                />
              </DropdownMenuTrigger>
              <DropdownMenuContent container={containerRef?.current} className="onvo-min-w-56 onvo-backdrop-blur-lg onvo-border-black/10 dark:onvo-border-white/10 onvo-z-50">
                <div className="onvo-w-full onvo-absolute onvo-top-0 onvo-left-0 onvo-right-0 onvo-bottom-0 onvo-foreground-color onvo-opacity-50 onvo-rounded-lg -onvo-z-10"></div>
                {(addable || widget_editable) && (
                  <>
                    <DropdownMenuLabel>Edit widget</DropdownMenuLabel>
                    <DropdownMenuGroup>
                      {widget_editable && (
                        <>
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              e.preventDefault();
                              setEditModalOpen(true, widget);
                            }}
                          >
                            <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                              <PencilSquareIcon className="onvo-size-5" />
                              <span>Edit widget</span>
                            </span>
                          </DropdownMenuItem>
                          {moveDropdown}</>
                      )}
                      {addable && (
                        <DropdownMenuItem onClick={(e) => {
                          e.stopPropagation();
                          e.preventDefault();
                          duplicate();
                        }}>
                          <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                            <DropdownMenuIconWrapper>
                              <DocumentDuplicateIcon className="onvo-size-5" />
                            </DropdownMenuIconWrapper>
                            <span>Duplicate widget</span>
                          </span>
                        </DropdownMenuItem>
                      )}
                    </DropdownMenuGroup>
                  </>
                )}

                {(addable || widget_editable) && ReportDownloadEnabled && (
                  <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />
                )}
                {ReportDownloadEnabled && (
                  <>
                    <DropdownMenuLabel>Download reports</DropdownMenuLabel>
                    <DropdownMenuGroup>
                      <DropdownMenuItem onClick={(e) => {
                        e.stopPropagation();
                        e.preventDefault();
                        exportWidget("xlsx");
                      }}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DocumentChartBarIcon className="onvo-size-5" />
                          <span>Download as excel</span>
                        </span>
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={(e) => {
                        e.stopPropagation();
                        e.preventDefault();
                        exportWidget("csv");
                      }}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DropdownMenuIconWrapper>
                            <DocumentChartBarIcon className="onvo-size-5" />
                          </DropdownMenuIconWrapper>
                          <span>Download as CSV</span>
                        </span>
                      </DropdownMenuItem>
                    </DropdownMenuGroup>
                  </>
                )}
                {(addable || widget_editable || ReportDownloadEnabled) &&
                  ImageDownloadEnabled && <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />}
                {ImageDownloadEnabled && (
                  <>
                    <DropdownMenuLabel>Download images</DropdownMenuLabel>
                    <DropdownMenuGroup>
                      <DropdownMenuItem onClick={(e) => {
                        e.stopPropagation();
                        e.preventDefault();
                        exportWidget("svg");
                      }}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <PhotoIcon className="onvo-size-5" />
                          <span>Download as SVG</span>
                        </span>
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={(e) => {
                        e.stopPropagation();
                        e.preventDefault();
                        exportWidget("png");
                      }}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DropdownMenuIconWrapper>
                            <PhotoIcon className="onvo-size-5" />
                          </DropdownMenuIconWrapper>
                          <span>Download as PNG</span>
                        </span>
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={(e) => {
                        e.stopPropagation();
                        e.preventDefault();
                        exportWidget("jpeg");
                      }}>
                        <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                          <DropdownMenuIconWrapper>
                            <PhotoIcon className="onvo-size-5" />
                          </DropdownMenuIconWrapper>
                          <span>Download as JPEG</span>
                        </span>
                      </DropdownMenuItem>
                    </DropdownMenuGroup>
                  </>
                )}

                {(addable ||
                  widget_editable ||
                  ImageDownloadEnabled ||
                  ReportDownloadEnabled) &&
                  deletable && <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />}

                {deletable && (
                  <DropdownMenuGroup>
                    <DropdownMenuItem onClick={(e) => {
                      e.stopPropagation();
                      e.preventDefault();
                      deleteWidget();
                    }}>
                      <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                        <TrashIcon className="onvo-size-5 onvo-text-red-500" />
                        <span className="onvo-text-red-500">Delete widget</span>
                      </span>
                    </DropdownMenuItem>
                  </DropdownMenuGroup>
                )}
              </DropdownMenuContent>
            </DropdownMenu>
          )}
      </div>

      {(widget.code === "") && (
        <div className="onvo-p-4 onvo-w-full onvo-h-full">
          <ChartPlaceholder title="Generating chart..." showProgress type={widget.type} />
        </div>
      )}
      {(!cache && widget.code !== "") && (
        <div className="onvo-p-4 onvo-w-full onvo-h-full">
          <ChartPlaceholder type={widget.type} />
        </div>
      )}
      {(cache && widget.code !== "") && (
        <div className={"onvo-p-0 onvo-flex-grow onvo-w-full onvo-flex onvo-flex-col " + (footer ? "onvo-max-h-[calc(100%-48px)]" : paginationEnabled ? "onvo-max-h-[calc(100%-40px)]" : "onvo-max-h-full")}>
          <ChartBase
            json={cache}
            title={widget.title}
            pagination={pagination}
            stats={stats}
            setPagination={updatePagination}
            padding={(typeof dashboard?.settings?.widget_padding === "number") ? dashboard?.settings?.widget_padding : 20}
          />
        </div>)}
      {footer}

      {paginationEnabled && (
        <PaginationComponent
          pagination={pagination}
          stats={{ totalRows: stats?.totalRows || 0, totalPages: stats?.totalPages || 1 }}
          setPagination={updatePagination}
          padding={(typeof dashboard?.settings?.widget_padding === "number") ? dashboard?.settings?.widget_padding : 20}
        />)}
    </Card>
  );
};

export default ChartCard;
