import React, { useEffect, useState } from "react";
import { Icon } from "../../tremor/Icon";
import { Input } from "../../tremor/Input";
import { Button } from "../../tremor/Button";
import { Widget, WidgetSettings } from "@onvo-ai/js";
import { create } from "zustand";
import { useDashboard } from "../../layouts/Dashboard/useDashboard";
import { useBackend } from "../../layouts/Wrapper";
import { Text, Label, Title } from "../../tremor/Text";
import {
  Editor,
  EditorProvider,
  BtnBold,
  BtnBulletList,
  BtnClearFormatting,
  BtnItalic,
  BtnLink,
  BtnNumberedList,
  BtnRedo,
  BtnStrikeThrough,
  BtnUnderline,
  BtnUndo,
  HtmlButton,
  Separator,
  Toolbar,
} from "react-simple-wysiwyg";
import { twMerge } from "tailwind-merge";
import {
  ChevronLeftIcon,
  ChevronRightIcon,
  TrashIcon,
} from "@heroicons/react/20/solid";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../../tremor/Select";
import { Divider } from "../../tremor/Divider";
import ChartBase from "../Chart/ChartBase";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../tremor/Tabs";
import { Card } from "../../tremor/Card";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "../../tremor/Accordion";
import { Textarea } from "../../tremor/Textarea";
import { SparklesIcon } from "@heroicons/react/24/solid";
import { toast } from "sonner";
import { useMaxHeight } from "../../lib/useMaxHeight";
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";


export const useTextWidgetModal = create<{
  open: boolean;
  widget?: Widget;
  setOpen: (open: boolean, widget?: Widget) => void;
}>((set) => ({
  open: false,
  setOpen: (op: boolean, wid?: Widget) => set({ open: op, widget: wid }),
}));

export const TextWidgetModal: React.FC<{}> = ({ }) => {
  const { dashboard, refreshWidgets, tab, widgets } = useDashboard();
  const { backend, adminMode } = useBackend();
  const { open, setOpen, widget } = useTextWidgetModal();
  const { lg, sm } = useMaxHeight();

  const [title, setTitle] = useState("");
  const [subtitle, setSubtitle] = useState("");
  const [prompt, setPrompt] = useState("");
  const [summaryLoading, setSummaryLoading] = useState(false);
  const [loading, setLoading] = useState(false);
  const [titleAlignment, setTitleAlignment] = useState<
    "start" | "center" | "end"
  >("start");
  const [descriptionAlignment, setDescriptionAlignment] = useState<
    "start" | "center" | "end"
  >("start");
  const [settings, setSettings] = useState<WidgetSettings>({});
  const [activeTab, setActiveTab] = useState("configure");
  const [drilldownWidget, setDrilldownWidget] = useState<string | null>(null);

  const deleteWidget = async () => {
    if (!widget || !backend) return;
    toast.promise(
      async () => {
        await backend.widgets.delete(widget.id);
        refreshWidgets(backend);
        setOpen(false);
      },
      {
        loading: "Deleting widget...",
        success: "Widget deleted",
        error: (err) => `Failed to delete widget: ${err.message}`,
      }
    );
  };

  useEffect(() => {
    if (widget) {
      const config = widget.config as any;
      setTitle(widget.title || "");
      setSubtitle(config?.options?.plugins?.subtitle?.text || "");
      setSettings(widget.settings || {});
      setTitleAlignment(
        config?.options?.plugins?.title?.align || "start"
      );
      setDescriptionAlignment(
        config?.options?.plugins?.subtitle?.align || "start"
      );
      setPrompt(config?.options?.plugins?.text?.prompt || "");
      setDrilldownWidget(widget.drilldown_widget);
    } else {
      setTitle("");
      setSubtitle("");
      setPrompt("");
      setTitleAlignment("start");
      setDescriptionAlignment("start");
      setSettings({});
      setDrilldownWidget(null);
    }
  }, [widget]);

  const createWidget = async () => {
    if (!dashboard || !backend) return;
    setLoading(true);
    let cache = {
      type: "text",
      data: { datasets: [{ data: [], label: "" }] },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          title: { display: true, text: title, align: titleAlignment },
          text: {
            prompt: prompt,
          },
          subtitle: {
            display: false,
            text: subtitle,
            align: descriptionAlignment,
          },
        },
      },
    };

    if (widget) {
      await backend.widgets.update(widget.id, {
        title: title,
        code: "",
        config: cache,
        settings: settings,
        drilldown_widget: drilldownWidget,
      });
    } else {
      await backend.widgets.create({
        dashboard: dashboard.id,
        layouts: {
          lg: {
            x: 0,
            y: lg,
            w: 12,
            h: 10,
          },
          sm: {
            x: 0,
            y: sm,
            w: 3,
            h: 10,
          },
        },
        use_in_library: false,
        use_in_chat: false,
        title: title,
        team: dashboard.team,
        code: "",
        messages: [],
        settings: settings,
        error: null,
        tab: tab || 0,
        config: cache,
        engine: "manual-v1",
        type: "text",
        drilldown_widget: drilldownWidget,
      });
    }
    setOpen(false);
    setLoading(false);
    setTitle("");
    setSubtitle("");
    refreshWidgets(backend);
  };

  const summarize = async () => {
    if (!backend || !dashboard) return;
    setSummaryLoading(true);
    try {
      let data = await backend.dashboard(dashboard.id).summarize(prompt);
      setTitle(data.title);
      setSubtitle(data.description);
      setSummaryLoading(false);
    } catch (e: any) {
      toast.error("Failed to summarize: " + e.message);
      setSummaryLoading(false);
    }
  };

  if (!dashboard?.settings?.can_create_widgets && !adminMode) return <></>;

  return (
    <>
      <dialog open={open}>
        <div
          className={twMerge(
            "onvo-@container/widgetmodal onvo-h-full onvo-animate-dialogOpen onvo-w-full onvo-z-50 onvo-fixed onvo-top-0 onvo-left-0 onvo-foreground-color"
          )}
        >
          <div className="onvo-relative onvo-flex onvo-flex-grow onvo-h-full onvo-w-full">
            <PanelGroup autoSaveId="edit-widget" direction="horizontal">
              <Panel minSize={25}>

                <div
                  className={
                    "onvo-foreground-color onvo-w-full onvo-left-0 onvo-top-0 onvo-z-10 onvo-flex onvo-flex-row onvo-justify-start onvo-items-center onvo-gap-4 onvo-border-solid onvo-border-b onvo-border-black/10 onvo-p-2 dark:onvo-border-white/10"
                  }
                >
                  <Icon
                    icon={ChevronLeftIcon}
                    variant="shadow"
                    className="onvo-ml-2 onvo-background-color onvo-border-solid onvo-border onvo-border-black/10 dark:onvo-border-white/10"
                    onClick={() => setOpen(false)}
                  />

                  <div className="onvo-flex onvo-flex-row onvo-w-full onvo-gap-1 onvo-flex-grow onvo-justify-start onvo-items-center">
                    <Text className="onvo-hidden @xl/widgetmodal:onvo-block">
                      {dashboard?.title}
                    </Text>
                    <ChevronRightIcon className="onvo-hidden @xl/widgetmodal:onvo-block onvo-h-4 onvo-w-4 dark:onvo-fill-slate-500" />
                    <Label>{widget ? `Edit ${title}` : "Create text widget"}</Label>
                  </div>
                </div>
                <div className="onvo-h-full onvo-background-color onvo-flex onvo-flex-shrink-0 @xl/widgetmodal:onvo-flex-shrink onvo-flex-col onvo-justify-center onvo-w-full onvo-flex-grow onvo-relative onvo-p-4 onvo-overflow-y-auto onvo-bg-[radial-gradient(#e2e8f0_1px,transparent_1px)] dark:onvo-bg-[radial-gradient(#0f172a_1px,transparent_1px)] [background-size:16px_16px]">
                  <div
                    className={"onvo-relative onvo-flex onvo-w-full onvo-flex-col"}
                  >
                    <ChartBase
                      json={{
                        type: "text",
                        data: { datasets: [{ data: [], label: "" }] },
                        options: {
                          responsive: true,
                          maintainAspectRatio: false,
                          plugins: {
                            title: {
                              display: true,
                              text: title,
                              align: titleAlignment,
                            },
                            subtitle: {
                              display: false,
                              text: subtitle,
                              align: descriptionAlignment,
                            },
                          },
                        },
                      }}
                      title={title}
                    />
                  </div>
                </div>
              </Panel>

              <PanelResizeHandle className="onvo-w-3 onvo-border-0 onvo-transition-all onvo-bg-black/10 dark:onvo-bg-white/10 hover:onvo-bg-black/20 dark:hover:onvo-bg-white/20 active:onvo-bg-black/40 dark:active:onvo-bg-white/40 onvo-flex onvo-justify-center onvo-items-center">
                <div className="onvo-w-1 onvo-h-12 onvo-rounded-full onvo-bg-black/30 dark:onvo-bg-white/30"></div>
              </PanelResizeHandle>

              <Panel defaultSize={50} minSize={25}>
                <Tabs
                  defaultValue="configure"
                  onValueChange={(value) => setActiveTab(value)}
                  className="onvo-flex onvo-flex-col onvo-h-full"
                >
                  <TabsList>
                    <div className="onvo-flex onvo-flex-row onvo-pt-5">
                      <TabsTrigger value="configure">Configure</TabsTrigger>
                      <TabsTrigger value="settings">Settings</TabsTrigger>
                    </div>

                    <div className="onvo-flex-grow onvo-w-full onvo-h-2" />
                    <Button
                      onClick={createWidget}
                      className="onvo-flex-shrink-0 onvo-mr-2"
                      isLoading={loading}
                    >
                      {widget ? "Save" : "Create"}
                    </Button>
                  </TabsList>
                  <TabsContent
                    value="configure"
                    className="onvo-h-full onvo-overflow-y-auto onvo-scrollbar-thin"
                  >
                    <div className="onvo-p-4 onvo-flex onvo-flex-col onvo-justify-start">
                      <Text>Title</Text>
                      <Input
                        placeholder="Type in a title"
                        value={title}
                        inputClassName="onvo-background-color onvo-border-black/10 dark:onvo-border-white/10"
                        onChange={(e) => setTitle(e.target.value)}
                      />
                      <div className="onvo-mt-2 onvo-flex onvo-items-center onvo-justify-between">
                        <Text>Title alignment</Text>
                        <Tabs
                          value={titleAlignment}
                          onValueChange={(val) => {
                            setTitleAlignment(val as "start" | "center" | "end");
                          }}
                        >
                          <TabsList variant="solid">
                            <TabsTrigger value="start">Left</TabsTrigger>
                            <TabsTrigger value="center">Center</TabsTrigger>
                            <TabsTrigger value="end">End</TabsTrigger>
                          </TabsList>
                        </Tabs>
                      </div>
                      <Text className="onvo-mt-2">Description</Text>
                      <div className="onvo-min-h-48 onvo-max-w-full onvo-prose onvo-prose-slate onvo-prose-sm dark:onvo-prose-invert">
                        <EditorProvider>
                          <Editor
                            containerProps={{ style: { minHeight: 192 } }}
                            value={subtitle}
                            onChange={(e) => setSubtitle(e.target.value)}
                          >
                            <Toolbar>
                              <BtnUndo />
                              <BtnRedo />
                              <Separator />
                              <BtnBold />
                              <BtnItalic />
                              <BtnUnderline />
                              <BtnStrikeThrough />
                              <Separator />
                              <BtnNumberedList />
                              <BtnBulletList />
                              <Separator />
                              <BtnLink />
                              <BtnClearFormatting />
                              <HtmlButton />
                            </Toolbar>
                          </Editor>
                        </EditorProvider>
                      </div>
                      <div className="onvo-mt-2 onvo-flex onvo-items-center onvo-justify-between">
                        <Text>Description alignment</Text>
                        <Tabs
                          value={descriptionAlignment}
                          onValueChange={(val) => {
                            setDescriptionAlignment(
                              val as "start" | "center" | "end"
                            );
                          }}
                        >
                          <TabsList variant="solid">
                            <TabsTrigger value="start">Left</TabsTrigger>
                            <TabsTrigger value="center">Center</TabsTrigger>
                            <TabsTrigger value="end">End</TabsTrigger>
                          </TabsList>
                        </Tabs>
                      </div>

                      <div className="onvo-mt-2 onvo-flex onvo-items-center onvo-justify-between">
                        <Card className="!onvo-p-0 onvo-background-color">
                          <Accordion type="single" collapsible>
                            <AccordionItem
                              value="item-1"
                              className="onvo-border-b-0"
                            >
                              <AccordionTrigger className="onvo-background-color onvo-px-3 onvo-rounded-2xl">
                                <div className="onvo-flex onvo-gap-2 onvo-items-center onvo-justify-start">
                                  <SparklesIcon className="onvo-h-4 onvo-w-4" />
                                  Generate text with AI
                                </div>
                              </AccordionTrigger>
                              <AccordionContent className="onvo-px-3 onvo-relative">
                                <Textarea
                                  placeholder="Enter prompt for AI"
                                  className="onvo-mt-2 onvo-foreground-color"
                                  value={prompt}
                                  onChange={(e) => setPrompt(e.target.value)}
                                />
                                <div className="onvo-w-full onvo-flex onvo-justify-end onvo-mt-2">
                                  <Button
                                    isLoading={summaryLoading}
                                    onClick={summarize}
                                  >
                                    Generate
                                  </Button>
                                </div>
                              </AccordionContent>
                            </AccordionItem>
                          </Accordion>
                        </Card>
                      </div>
                    </div>
                  </TabsContent>
                  <TabsContent value="settings" className="onvo-px-4 onvo-py-2">
                    <div className="onvo-flex onvo-flex-row onvo-items-center onvo-justify-between onvo-gap-2">
                      <Text className="onvo-text-sm onvo-w-32 onvo-shrink-0">
                        Widget ID
                      </Text>
                      <Input
                        placeholder="ID"
                        className="onvo-text-xs"
                        value={widget?.id}
                        disabled
                        inputClassName="onvo-background-color onvo-border-black/10 dark:onvo-border-white/10"
                      />
                    </div>

                    <Divider />
                    <div className="onvo-flex onvo-flex-row onvo-items-center onvo-justify-between onvo-gap-2 onvo-mt-2">
                      <Text className="onvo-text-sm onvo-w-32 onvo-shrink-0">
                        CSS ID
                      </Text>
                      <Input
                        placeholder="id"
                        className="onvo-text-xs"
                        value={settings?.css_id}
                        onChange={(e) =>
                          setSettings({ ...settings, css_id: e.target.value })
                        }
                        inputClassName="onvo-background-color onvo-border-black/10 dark:onvo-border-white/10"
                      />
                    </div>
                    <div className="onvo-flex onvo-flex-row onvo-items-center onvo-justify-between onvo-gap-2 onvo-mt-2">
                      <Text className="onvo-text-sm onvo-w-32 onvo-shrink-0">
                        CSS classes
                      </Text>
                      <Input
                        placeholder="class-name"
                        className="onvo-text-xs"
                        value={settings?.css_classnames}
                        onChange={(e) =>
                          setSettings({
                            ...settings,
                            css_classnames: e.target.value,
                          })
                        }
                        inputClassName="onvo-background-color onvo-border-black/10 dark:onvo-border-white/10"
                      />
                    </div>
                    <div className="onvo-flex onvo-flex-row onvo-items-center onvo-justify-between onvo-gap-2 onvo-mt-2">
                      <Text className="onvo-text-sm onvo-w-32 onvo-shrink-0">Link</Text>
                      <Input
                        placeholder="https://..."
                        className="onvo-text-xs"
                        value={settings?.link}
                        onChange={(e) =>
                          setSettings({ ...settings, link: e.target.value })
                        }
                        inputClassName="onvo-background-color onvo-border-black/10 dark:onvo-border-white/10"
                      />
                    </div>

                    <Divider />
                    <div className="onvo-flex onvo-flex-row onvo-items-center onvo-justify-between onvo-gap-2">
                      <Text className="onvo-text-sm onvo-w-32 onvo-shrink-0">
                        Drilldown widget
                      </Text>
                      <Select
                        value={drilldownWidget || undefined}
                        onValueChange={(val) => {
                          setDrilldownWidget(val);
                        }}
                      >
                        <SelectTrigger>
                          <SelectValue placeholder="None" />
                        </SelectTrigger>
                        <SelectContent>
                          {widgets
                            .filter(
                              (item) =>
                                item.id !== widget?.id &&
                                [
                                  "divider"
                                ].indexOf(widget?.type || "") === -1 &&
                                item.title.trim() !== ""
                            )
                            .map((item) => (
                              <SelectItem key={item.id} value={item.id}>
                                {item.title}
                              </SelectItem>
                            ))}
                        </SelectContent>
                      </Select>
                    </div>
                    <Divider />
                    <Button
                      variant="destructive"
                      onClick={deleteWidget}
                      className="onvo-w-full onvo-mt-2"
                    >
                      <TrashIcon className="onvo-h-4 onvo-w-4 onvo-mr-2" />
                      Delete widget
                    </Button>
                  </TabsContent>
                </Tabs>
              </Panel>
            </PanelGroup>

          </div>
        </div>
      </dialog>
    </>
  );
};
