import { Badge } from "../../tremor/Badge";
import { Label, Metric } from "../../tremor/Text";
import { Button } from "../../tremor/Button";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useDashboard } from "../../layouts/Dashboard/useDashboard";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import {
  AdjustmentsHorizontalIcon,
  ArrowDownTrayIcon,
  ArrowPathIcon,
  ChevronDownIcon,
  ClockIcon,
  DocumentChartBarIcon,
  FunnelIcon,
  PhotoIcon,
  PresentationChartBarIcon,
} from "@heroicons/react/24/outline";
import { toast } from "sonner";
import { useBackend } from "../../layouts/Wrapper";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuIconWrapper,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "../../tremor/DropdownMenu";
import { useTheme } from "../../layouts/Dashboard/useTheme";
import { AutomationsModal } from "../AutomationsModal";
import { Popover, PopoverContent, PopoverTrigger } from "../../tremor/Popover";
import { FilterBar } from "../FilterBar";
import { useAutomationsModal } from "../AutomationsModal/useAutomationsModal";
import { Tooltip } from "../../tremor/Tooltip";
import { List, Trigger } from "@radix-ui/react-tabs";

dayjs.extend(relativeTime);

function formatList(items: string[]) {
  if (items.length === 0) return <></>;
  if (items.length === 1) return <Badge variant="neutral" className="!onvo-py-0 onvo-mb-1">{items[0]}</Badge>;
  if (items.length === 2) return <><Badge variant="neutral" className="!onvo-py-0 onvo-mb-1">{items[0]}</Badge> and <Badge variant="neutral" className="!onvo-py-0 onvo-mb-1">{items[1]}</Badge></>;

  return <>{items.slice(0, -1).map(a => <Badge variant="neutral" className="!onvo-py-0 onvo-mb-1 onvo-mr-1">{a}</Badge>)}and <Badge variant="neutral" className="!onvo-py-0 onvo-mb-1">{items[items.length - 1]}</Badge></>;
}

export const LastUpdatedBadge: React.FC<{}> = ({ }) => {
  const { dashboard, refreshing } = useDashboard();
  const [key, setKey] = useState(dashboard?.last_updated_at || new Date().toISOString());

  useEffect(() => {
    let interval = setInterval(() => {
      setKey(new Date().toISOString());
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  }, []);

  if (refreshing) {
    return (
      <Badge key="refreshing-badge" className="onvo-last-updated-badge onvo-justify-center onvo-items-center">
        <ArrowPathIcon className="onvo-size-3 onvo-animate-spin onvo-w-full" />
        Auto refreshing...
      </Badge>
    );
  }
  return (
    <Tooltip side="bottom" align="end" content={"The dashboard was last updated " + dayjs(key).fromNow()}>
      <Badge key={key} className="onvo-last-updated-badge onvo-justify-center onvo-items-center onvo-w-full">
        <ArrowPathIcon className="onvo-size-3" />
        {dayjs(key).fromNow()}
      </Badge>
    </Tooltip>
  );
};

export const DashboardHeader: React.FC<{
  children?: React.ReactNode;
  className?: string;
  variant?: "default" | "pdf" | "pptx"
}> = ({ children, className, variant }) => {
  const { setOpen } = useAutomationsModal();
  const { dashboard, tab, setTab } = useDashboard();
  const theme = useTheme();
  const { backend, adminMode, containerRef } = useBackend();

  const exportDashboard = useCallback(
    (format: "csv" | "xlsx" | "pdf" | "png" | "jpeg" | "pptx") => {
      if (!backend || !dashboard) {
        return;
      }
      toast.promise(
        async () => {
          const blob = await backend.dashboard(dashboard.id).export(format, theme, tab);
          return window.URL.createObjectURL(blob);
        },
        {
          loading: `Exporting dashboard as ${format}...`,
          success: (url: string) => {
            let a = document.createElement("a");
            if (format === "csv") {
              a.download = dashboard.title + ".zip";
            } else {
              a.download = dashboard.title + "." + format;
            }
            a.href = url;
            document.body.appendChild(a);
            a.click();
            a.remove();
            return "Dashboard exported successfully";
          },
          error: (e: any) => {
            return "Failed to export dashboard: " + e.message;
          },
        }
      );
    },
    [dashboard, backend, tab]
  );

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


  const DocumentDownloadEnabled = useMemo(() => {
    if (dashboard?.settings && dashboard.settings.disable_download_documents)
      return false;
    return true;
  }, [dashboard]);

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

  const filtered = useMemo(() => {
    let filters = dashboard?.filters || [];
    if (filters.length === 0) return [];
    let results = [] as string[];
    for (let filter of filters) {
      if (filter.type === "text" && filter.options.length !== filter.values.length) {
        results.push(filter.label);
      }
      if (filter.type === "number" && (filter.options[0] !== filter.values[0] || filter.options[1] !== filter.values[1])) {
        results.push(filter.label);
      }
      if (filter.type === "date" && (filter.options[0] !== filter.values[0] || filter.options[1] !== filter.values[1])) {
        results.push(filter.label);
      }
    }

    return results;

  }, [dashboard])

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

  const DownloadDropdown = (<DropdownMenu modal={false}>
    <DropdownMenuTrigger asChild>
      <Button className="onvo-foreground-color onvo-border-black/10 dark:onvo-border-white/10" variant="secondary" disabled={!dashboard}>
        <ArrowDownTrayIcon className="onvo-size-4" />
      </Button>
    </DropdownMenuTrigger>
    <DropdownMenuContent side="bottom" align="end" container={containerRef?.current} className="onvo-min-w-56 onvo-foreground-color onvo-border-black/10 dark:onvo-border-white/10">
      {ReportDownloadEnabled && (
        <>
          <DropdownMenuLabel>Report formats</DropdownMenuLabel>
          <DropdownMenuGroup>
            <DropdownMenuItem onClick={() => exportDashboard("xlsx")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <DocumentChartBarIcon className="onvo-size-4" />
                <span>Excel</span>
              </span>
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => exportDashboard("csv")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <DropdownMenuIconWrapper>
                  <DocumentChartBarIcon className="onvo-size-4" />
                </DropdownMenuIconWrapper>
                <span>CSV</span>
              </span>
            </DropdownMenuItem>
          </DropdownMenuGroup>
        </>
      )}

      {DocumentDownloadEnabled && ReportDownloadEnabled && (
        <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />
      )}
      {DocumentDownloadEnabled && (
        <>
          <DropdownMenuLabel>Document formats</DropdownMenuLabel>
          <DropdownMenuGroup>
            <DropdownMenuItem onClick={() => exportDashboard("pdf")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <DocumentChartBarIcon className="onvo-size-4" />
                <span>PDF</span>
              </span>
            </DropdownMenuItem>

            <DropdownMenuItem onClick={() => exportDashboard("pptx")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <PresentationChartBarIcon className="onvo-size-4" />
                <span>Powerpoint</span>
              </span>
            </DropdownMenuItem>
          </DropdownMenuGroup>
        </>
      )}
      {ImageDownloadEnabled && (DocumentDownloadEnabled || ReportDownloadEnabled) && (
        <DropdownMenuSeparator className="onvo-border-black/10 dark:onvo-border-white/10" />
      )}
      {ImageDownloadEnabled && (
        <>
          <DropdownMenuLabel>Image formats</DropdownMenuLabel>
          <DropdownMenuGroup>
            <DropdownMenuItem onClick={() => exportDashboard("png")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <DropdownMenuIconWrapper>
                  <PhotoIcon className="onvo-size-4" />
                </DropdownMenuIconWrapper>
                <span>PNG</span>
              </span>
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => exportDashboard("jpeg")}>
              <span className="onvo-flex onvo-items-center onvo-gap-x-2">
                <DropdownMenuIconWrapper>
                  <PhotoIcon className="onvo-size-4" />
                </DropdownMenuIconWrapper>
                <span>JPEG</span>
              </span>
            </DropdownMenuItem>
          </DropdownMenuGroup>
        </>
      )}
    </DropdownMenuContent>
  </DropdownMenu>);

  if (variant === "pdf" || variant === "pptx") {
    return (
      <section
        className={`onvo-@container/onvo-dashboard-header onvo-leading-tight onvo-bg-slate-900 onvo-dashboard-header onvo-sticky onvo-z-50 onvo-top-0 ${className ? className : ""}`}
      >
        <div className="onvo-flex onvo-py-2 onvo-px-5 onvo-flex-row onvo-justify-between onvo-items-center">
          {(dashboard?.tabs || []).filter(a => !a.hidden).length > 1 ? (
            <div className="onvo-flex onvo-flex-row onvo-gap-2">
              {(dashboard?.tabs || []).filter(a => !a.hidden).map(a => (
                <Button key={a.id + ""} variant={a.id === tab ? "light" : "secondary"} onClick={() => {
                  setTab(a.id);
                }}>{a.label}</Button>))}
            </div>) : <div></div>}
          {(ImageDownloadEnabled || ReportDownloadEnabled || DocumentDownloadEnabled) &&
            DownloadDropdown
          }
        </div>
      </section>)
  }

  return (
    <section
      className={`onvo-@container/onvo-dashboard-header onvo-leading-tight onvo-background-color onvo-dashboard-header onvo-sticky onvo-z-50 onvo-top-0 ${className ? className : ""}`}

    >
      <AutomationsModal />
      <main className="onvo-mx-auto onvo-px-5 onvo-pt-4 onvo-pb-2 onvo-z-10 onvo-relative onvo-flex onvo-flex-col onvo-items-start onvo-justify-between onvo-gap-4 @lg/onvo-dashboard-header:onvo-flex-row @lg/onvo-dashboard-header:onvo-items-center">

        <div className="onvo-flex-grow onvo-flex onvo-flex-row onvo-gap-4">
          {dashboard && dashboard.thumbnail && dashboard.thumbnail.trim() !== "" && (
            <div className="onvo-relative onvo-h-12 onvo-w-12 onvo-flex-shrink-0 onvo-rounded-md onvo-border onvo-border-slate-200 onvo-bg-slate-50 dark:onvo-border-slate-700 dark:onvo-bg-slate-900">
              <img
                className={
                  "onvo-rounded-md onvo-onvo-size-12 onvo-bg-slate-50 onvo-object-contain dark:onvo-bg-slate-900"
                }
                src={dashboard.thumbnail}
                alt={dashboard.title} />
            </div>)}
          <div className="onvo-flex-grow">
            {dashboard ? (
              <>
                <Metric className="onvo-dashboard-header-title !onvo-font-semibold dark:onvo-text-white onvo-text-black onvo-font-override onvo-text-xl">
                  {dashboard?.title || ""}
                </Metric>
                <Label className="onvo-dashboard-header-description !onvo-font-normal onvo-font-override">
                  {dashboard?.description || ""}
                </Label>
              </>
            ) : (
              <div className="onvo-w-3/5 onvo-animate-pulse">
                <div className="onvo-mb-2 onvo-h-6 onvo-w-4/5 onvo-rounded-md onvo-bg-gray-100 dark:onvo-bg-gray-700" />
                <div className="onvo-h-4 onvo-w-2/5 onvo-rounded-md onvo-bg-gray-100 dark:onvo-bg-gray-700" />
              </div>
            )}</div>
        </div>
        <div className="onvo-gap-2 onvo-flex onvo-flex-col">

          <div className="onvo-flex onvo-flex-row onvo-gap-2 onvo-justify-end">
            {dashboard?.settings?.filters && dashboard.filters.length > 0 && (
              <Popover>
                <PopoverTrigger asChild>

                  <Button className="onvo-relative onvo-foreground-color onvo-border-black/10 dark:onvo-border-white/10" variant="secondary"
                  >
                    <FunnelIcon className="onvo-size-4" />
                    {filtered?.length > 0 && (
                      <>
                        <div className="onvo-size-2"></div>

                        <Tooltip side="bottom" sideOffset={20} content={<p className="onvo-text-xs">The dashboard is currently filtered by {formatList(filtered)}</p>}>
                          <div className="onvo-absolute -onvo-top-2 -onvo-right-2 onvo-rounded-full onvo-bg-red-500 onvo-text-white onvo-text-xs onvo-text-center onvo-font-bold onvo-size-5 onvo-flex onvo-items-center onvo-justify-center">
                            {filtered?.length}
                          </div>
                        </Tooltip>
                      </>
                    )}
                  </Button>
                </PopoverTrigger>
                <PopoverContent side="bottom" align="end" onInteractOutside={e => e.preventDefault()} container={containerRef?.current} className="!onvo-p-0 onvo-z-50 onvo-w-[320px]">
                  <FilterBar />
                </PopoverContent>
              </Popover>)}
            {(dashboard?.settings?.can_schedule_reports) && (
              <Tooltip content="Schedule reports" side="bottom" align="end">
                <Button className="onvo-foreground-color onvo-border-black/10 dark:onvo-border-white/10" variant="secondary"
                  onClick={() => {
                    setOpen(true);
                  }}
                >
                  <ClockIcon className="onvo-size-4" />

                </Button></Tooltip>)}
            {(ImageDownloadEnabled || ReportDownloadEnabled || DocumentDownloadEnabled) &&
              DownloadDropdown
            }
            {children}
          </div>
          <LastUpdatedBadge />
        </div>
      </main>
      {(dashboard?.tabs || []).filter(a => !a.hidden).length > 1 && (
        <List className="onvo-px-5 onvo-pb-2 onvo-flex onvo-flex-row onvo-gap-2">
          {(dashboard?.tabs || []).filter(a => !a.hidden).map(a => (
            <Trigger key={a.id + ""} value={a.id + ""}>
              <Button className="!onvo-rounded-full" variant={a.id === tab ? "light" : "secondary"} onClick={() => {
                setTab(a.id);
              }}>
                {a.label}
              </Button>
            </Trigger>))}
        </List>
      )}
    </section>
  );
};
