import React, { memo, useEffect, useMemo, useState } from "react";

import { Card } from "../../tremor/Card";
import ChartCard from "../Chart/ChartCard";
import { Button } from "../../tremor/Button";
import { useDashboard } from "../../layouts/Dashboard/useDashboard";
import { useBackend } from "../../layouts/Wrapper";
import { toast } from "sonner";
import { Text, Title } from "../../tremor/Text";
import { Widget } from "@onvo-ai/js";
import { ArrowRightIcon, XMarkIcon } from "@heroicons/react/16/solid";
import { ChartLoader, ChartPlaceholder } from "../ChartLoader";
import { Badge } from "../../tremor/Badge";

const WidgetLibraryRaw: React.FC<{
  onExpanded: (val: boolean) => void;
}> = ({ onExpanded }) => {
  const { backend, adminMode } = useBackend();
  const { dashboard, widgets, refreshWidgets } = useDashboard();

  const [library, setLibrary] = useState<Widget[]>([]);
  const [expanded, setExpanded] = useState(false);
  const [loading, setLoading] = useState(true);

  const getLibrary = async () => {
    setLibrary([]);
    if (!dashboard) return;
    setLoading(true);
    let newSuggestions = await backend?.widgets.list({
      dashboard: dashboard.id,
      use_in_library: true,
    });
    if (newSuggestions && newSuggestions.length > 0) {
      setLibrary(newSuggestions);
    }
    setLoading(false);
  };

  useEffect(() => {
    if (dashboard && dashboard.id) {
      getLibrary();
    }
  }, [dashboard?.id]);

  const removeFromLibrary = async (id: string) => {
    toast.promise(
      async () => {
        return backend?.widgets.delete(id);
      },
      {
        loading: "Deleting widget...",
        success: () => {
          getLibrary();
          return "Widget deleted";
        },
        error: (error) => "Error deleting widget: " + error.message,
      }
    );
  };

  const addToDashboard = async (wid: Widget) => {
    let newObj = { ...wid, use_in_library: false };
    // @ts-ignore
    delete newObj.id;

    if (!backend) return;

    toast.promise(
      async () => {
        let cache = await backend.widget(wid.id).cache();
        let newWid = await backend.widgets.create(newObj, cache);
        return true;
      },
      {
        loading: "Adding widget to dashboard...",
        success: () => {
          refreshWidgets(backend);
          return "Widget added to dashboard";
        },
        error: (error) => "Error adding widget to dashboard: " + error.message,
      }
    );
  };

  const AddToDashboardEnabled = useMemo(() => {
    if (adminMode) return true;
    if (dashboard?.settings?.can_create_widgets) return true;
    return false;
  }, [dashboard, adminMode]);

  const filteredLibrary = useMemo(() => {
    if (expanded) return library;
    else return library.slice(0, 4);
  }, [expanded, library]);

  if (!loading && library.length === 0) {
    return <></>;
  }
  return (
    <div className="onvo-flex onvo-flex-col onvo-w-full">
      <div className="onvo-flex onvo-w-full onvo-pt-2 onvo-pb-2 onvo-flex-row onvo-items-center onvo-justify-between">
        <Title>Library</Title>
        {!loading && filteredLibrary.length > 0 && (
          <div className="onvo-flex onvo-flex-row onvo-items-center">
            {expanded ? (
              <Button
                variant="ghost"
                onClick={() => {
                  setExpanded(false);
                  onExpanded(false);
                }}
              >
                View less
                <XMarkIcon className="onvo-size-4 onvo-ml-1" />
              </Button>
            ) : (
              <Button
                variant="ghost"
                onClick={() => {
                  setExpanded(true);
                  onExpanded(true);
                }}
              >
                View more
                <ArrowRightIcon className="onvo-size-4 onvo-ml-1" />
              </Button>
            )}
          </div>
        )}
      </div>

      {loading && (
        <div className="onvo-question-modal-suggestions-list onvo-grid onvo-grid-cols-1 @xl/questionmodal:onvo-grid-cols-2 onvo-gap-2 onvo-w-full">
          {[1, 2, 3, 4].map((a) => (
            <ChartPlaceholder
              key={"library-loading-" + a}
              className="onvo-h-72"
            />
          ))}
        </div>
      )}

      {!loading && filteredLibrary.length > 0 && (
        <div className="onvo-question-modal-suggestions-list onvo-grid onvo-grid-cols-1 @xl/questionmodal:onvo-grid-cols-2 onvo-gap-2 onvo-w-full">
          {filteredLibrary.map((a) => (
            <div className="!onvo-h-96"
              key={a.id}>
              <ChartCard
                widget={a}
                hideOptions={true}
                className="onvo-z-10"
                footer={
                  <div className="onvo-chart-card-dropdown-wrapper onvo-flex-grow onvo-flex-shrink-0 onvo-py-2 onvo-px-2 onvo-z-20 onvo-border-solid onvo-border-t onvo-border-black/5 dark:onvo-border-white/10 onvo-rounded-b-2xl onvo-background-color onvo-flex onvo-w-full onvo-justify-between onvo-flex-row onvo-items-center">
                    <div className="onvo-flex onvo-gap-2 onvo-items-center">
                      {adminMode && (
                        <Button
                          variant="ghost"
                          onClick={() => removeFromLibrary(a.id)}
                        >
                          Remove from library
                        </Button>
                      )}
                    </div>
                    <div className="onvo-flex onvo-gap-2 onvo-items-center">
                      {AddToDashboardEnabled && (
                        <Button
                          variant="secondary" className="onvo-foreground-color onvo-border-black/10 dark:onvo-border-white/10"
                          onClick={() => addToDashboard(a)}
                        >
                          Add to dashboard
                        </Button>
                      )}
                    </div>
                  </div>
                }
              />
            </div>
          ))}
        </div>
      )}
      {!loading && filteredLibrary.length === 0 && (
        <Card>
          <Text>
            You have not added any widgets to the library yet. <br />
            You can add widgets to the library by asking a question and clicking
            on the <Badge>Add to Library</Badge> button
          </Text>
        </Card>
      )}
    </div>
  );
};

export const WidgetLibrary = memo(WidgetLibraryRaw);
